Skip to content

Commit

Permalink
Merge pull request #103 from mempool/junderw/json-rpc-2
Browse files Browse the repository at this point in the history
Fix JSON-RPC v2 errors
  • Loading branch information
wiz authored Nov 14, 2024
2 parents e5c1587 + 66c76bc commit c6a7fbd
Showing 1 changed file with 49 additions and 18 deletions.
67 changes: 49 additions & 18 deletions src/electrum/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ fn get_status_hash(txs: Vec<(Txid, Option<BlockId>)>, query: &Query) -> Option<F
}
}

#[repr(i16)]
#[derive(Clone, Copy, PartialEq, Eq)]
enum JsonRpcV2Error {
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InternalError = -32603,
}
impl JsonRpcV2Error {
#[inline]
fn into_i16(self) -> i16 {
self as i16
}
}

struct Connection {
query: Arc<Query>,
last_header_entry: Option<HeaderEntry>,
Expand Down Expand Up @@ -447,7 +462,14 @@ impl Connection {
#[cfg(feature = "electrum-discovery")]
"server.add_peer" => self.server_add_peer(params),

&_ => bail!("unknown method {} {:?}", method, params),
&_ => {
warn!("rpc unknown method #{} {} {:?}", id, method, params);
return Ok(json_rpc_error(
format!("Method {method} not found"),
Some(id),
JsonRpcV2Error::MethodNotFound,
));
}
};
timer.observe_duration();
// TODO: return application errors should be sent to the client
Expand All @@ -461,7 +483,7 @@ impl Connection {
params,
e.display_chain()
);
json!({"jsonrpc": "2.0", "id": id, "error": format!("{}", e)})
json_rpc_error(e, Some(id), JsonRpcV2Error::InternalError)
}
})
}
Expand Down Expand Up @@ -558,7 +580,11 @@ impl Connection {
}
} else {
// serde_json was unable to parse
invalid_json_rpc(line)
json_rpc_error(
format!("Invalid JSON: {line}"),
None,
JsonRpcV2Error::ParseError,
)
}
}

Expand All @@ -572,16 +598,14 @@ impl Connection {
(Some(Value::String(method)), Value::Array(params), Some(id)) => self
.handle_command(method, params, id)
.unwrap_or_else(|err| {
json!({
"error": {
"code": 1,
"message": format!("{method} RPC error: {err}")
},
"id": id,
"jsonrpc": "2.0"
})
json_rpc_error(
format!("{method} RPC error: {err}"),
Some(id),
JsonRpcV2Error::InternalError,
)
}),
_ => invalid_json_rpc(value),
(_, _, Some(id)) => json_rpc_error(value, Some(id), JsonRpcV2Error::InvalidRequest),
_ => json_rpc_error(value, None, JsonRpcV2Error::InvalidRequest),
}
}

Expand Down Expand Up @@ -661,15 +685,22 @@ impl Connection {
}

#[inline]
fn invalid_json_rpc(input: impl core::fmt::Display) -> Value {
json!({
fn json_rpc_error(
input: impl core::fmt::Display,
id: Option<&Value>,
code: JsonRpcV2Error,
) -> Value {
let mut ret = json!({
"error": {
"code": -32600,
"message": format!("invalid request: {input}")
"code": code.into_i16(),
"message": format!("{input}")
},
"id": null,
"jsonrpc": "2.0"
})
});
if let (Some(id), Some(obj)) = (id, ret.as_object_mut()) {
obj.insert(String::from("id"), id.clone());
}
ret
}

fn get_history(
Expand Down

0 comments on commit c6a7fbd

Please sign in to comment.