Skip to content

Commit

Permalink
Refactor the JSON-RPC service code (smol-dot#793)
Browse files Browse the repository at this point in the history
* Refactor the JSON-RPC service code

* Remove unused stub

* Fix overflow when limits are very high

* Fix doclinks

* Docfix

* Remove obsolete files

* Fix missing subscriptions

* Fix doclinks
  • Loading branch information
tomaka authored Jun 22, 2023
1 parent ead9ea4 commit 8e5de78
Show file tree
Hide file tree
Showing 18 changed files with 3,142 additions and 5,107 deletions.
10 changes: 6 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ wasmtime = [
# theoretically be `no_std`-compatible (i.e. doesn't need the help of the operating system) but is
# not, or if things are sketchy, please leave a comment next to it.
arrayvec = { version = "0.7.3", default-features = false }
async-channel = { version = "1.8.0", default-features = false } # TODO: no-std-ize; this is has been done and is just waiting for a release: https://github.com/smol-rs/event-listener/pull/34
async-lock = { version = "2.7.0", default-features = false } # TODO: no-std-ize; this is has been done and is just waiting for a release: https://github.com/smol-rs/event-listener/pull/34
atomic = { version = "0.5.3", default-features = false }
atomic-take = { version = "1.1.0" }
base64 = { version = "0.21.2", default-features = false, features = ["alloc"] }
bip39 = { version = "2.0.0", default-features = false }
blake2-rfc = { version = "0.2.18", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion lib/src/json_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,5 @@
pub mod methods;
pub mod parse;
pub mod payment_info;
pub mod requests_subscriptions;
pub mod service;
pub mod websocket_server;
53 changes: 36 additions & 17 deletions lib/src/json_rpc/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,37 +35,27 @@ use hashbrown::HashMap;
///
/// On success, returns a JSON-encoded identifier for that request that must be passed back when
/// emitting the response.
pub fn parse_json_call(message: &str) -> Result<(&str, MethodCall), ParseError> {
let call_def = parse::parse_call(message).map_err(ParseError::JsonRpcParse)?;
pub fn parse_json_call(message: &str) -> Result<(&str, MethodCall), ParseCallError> {
let call_def = parse::parse_call(message).map_err(ParseCallError::JsonRpcParse)?;

// No notification is supported by this server. If the `id` field is missing in the request,
// assuming that this is a notification and return an appropriate error.
let request_id = match call_def.id_json {
Some(id) => id,
None => return Err(ParseError::UnknownNotification(call_def.method)),
None => return Err(ParseCallError::UnknownNotification(call_def.method)),
};

let call = match MethodCall::from_defs(call_def.method, call_def.params_json) {
Ok(c) => c,
Err(error) => return Err(ParseError::Method { request_id, error }),
Err(error) => return Err(ParseCallError::Method { request_id, error }),
};

Ok((request_id, call))
}

/// Builds a JSON call, to send it to a JSON-RPC server.
///
/// # Panic
///
/// Panics if the `id_json` isn't valid JSON.
///
pub fn build_json_call_object_parameters(id_json: Option<&str>, method: MethodCall) -> String {
method.to_json_call_object_parameters(id_json)
}

/// Error produced by [`parse_json_call`].
#[derive(Debug, derive_more::Display)]
pub enum ParseError<'a> {
pub enum ParseCallError<'a> {
/// Could not parse the body of the message as a valid JSON-RPC message.
JsonRpcParse(parse::ParseError),
/// Call concerns a notification that isn't recognized.
Expand All @@ -80,7 +70,36 @@ pub enum ParseError<'a> {
},
}

/// See [`ParseError::Method`].
/// Parses a JSON notification.
pub fn parse_notification(message: &str) -> Result<ServerToClient, ParseNotificationError> {
let call_def = parse::parse_call(message).map_err(ParseNotificationError::JsonRpcParse)?;
let call = ServerToClient::from_defs(call_def.method, call_def.params_json)
.map_err(ParseNotificationError::Method)?;
Ok(call)
}

/// Error produced by [`parse_notification`].
#[derive(Debug, derive_more::Display)]
pub enum ParseNotificationError<'a> {
/// Could not parse the body of the message as a valid JSON-RPC message.
#[display(fmt = "{_0}")]
JsonRpcParse(parse::ParseError),
/// JSON-RPC request is valid, but there is a problem related to the method being called.
#[display(fmt = "{_0}")]
Method(MethodError<'a>),
}

/// Builds a JSON call, to send it to a JSON-RPC server.
///
/// # Panic
///
/// Panics if the `id_json` isn't valid JSON.
///
pub fn build_json_call_object_parameters(id_json: Option<&str>, method: MethodCall) -> String {
method.to_json_call_object_parameters(id_json)
}

/// See [`ParseCallError::Method`] or [`ParseNotificationError::Method`].
#[derive(Debug, derive_more::Display)]
pub enum MethodError<'a> {
/// Call concerns a method that isn't recognized.
Expand Down Expand Up @@ -1258,7 +1277,7 @@ mod tests {

assert!(matches!(
err,
Err(super::ParseError::Method {
Err(super::ParseCallError::Method {
request_id: "2",
error: super::MethodError::MissingParameters {
rpc_method: "chainHead_unstable_follow"
Expand Down
Loading

0 comments on commit 8e5de78

Please sign in to comment.