diff --git a/bin/wasm-node/CHANGELOG.md b/bin/wasm-node/CHANGELOG.md index 2c6ae370e8..272cfe2d86 100644 --- a/bin/wasm-node/CHANGELOG.md +++ b/bin/wasm-node/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixed +- JSON-RPC requests without a `params` field are no longer invalid. ([#3090](https://github.com/paritytech/smoldot/pull/3090)) - Fix Merkle proofs whose trie root node has a size inferior to 32 bytes being considered as invalid. ([#3046](https://github.com/paritytech/smoldot/pull/3046)) ## 0.7.9 - 2022-11-28 diff --git a/src/json_rpc/methods.rs b/src/json_rpc/methods.rs index 63be322252..75c6d5fe3a 100644 --- a/src/json_rpc/methods.rs +++ b/src/json_rpc/methods.rs @@ -219,11 +219,13 @@ macro_rules! define_methods { parse::build_call(parse::Call { id_json, method: self.name(), - params_json: &self.params_to_json_object(), + // Note that we never skip the `params` field, even if empty. This is an + // arbitrary choice. + params_json: Some(&self.params_to_json_object()), }) } - fn from_defs(name: &'a str, params: &'a str) -> Result> { + fn from_defs(name: &'a str, params: Option<&'a str>) -> Result> { #![allow(unused, unused_mut)] $( @@ -243,7 +245,7 @@ macro_rules! define_methods { #[serde(borrow, skip)] _dummy: core::marker::PhantomData<&'a ()>, } - if let Ok(params) = serde_json::from_str(params) { + if let Some(Ok(params)) = params.as_ref().map(|p| serde_json::from_str(p)) { let Params { _dummy: _, $($p_name),* } = params; return Ok($rq_name::$name { $($p_name,)* @@ -257,7 +259,7 @@ macro_rules! define_methods { // // The code below allocates a `Vec`, but at the time of writing there is // no way to ask `serde_json` to parse an array without doing so. - if let Ok(params) = serde_json::from_str::>(params) { + if let Some(Ok(params)) = params.as_ref().map(|p| serde_json::from_str::>(p)) { let mut n = 0; $( // Missing parameters are implicitly equal to null. diff --git a/src/json_rpc/parse.rs b/src/json_rpc/parse.rs index cf63c01299..9c9ea5d28b 100644 --- a/src/json_rpc/parse.rs +++ b/src/json_rpc/parse.rs @@ -41,7 +41,7 @@ pub fn parse_call(call_json: &str) -> Result { Ok(Call { id_json: serde_call.id.map(|v| v.get()), method: serde_call.method, - params_json: serde_call.params.get(), + params_json: serde_call.params.map(|p| p.get()), }) } @@ -59,7 +59,7 @@ pub fn build_call(call: Call) -> String { jsonrpc: SerdeVersion::V2, id: call.id_json.map(|id| serde_json::from_str(id).unwrap()), method: call.method, - params: serde_json::from_str(call.params_json).unwrap(), + params: call.params_json.map(|p| serde_json::from_str(p).unwrap()), }) .unwrap() } @@ -71,8 +71,8 @@ pub struct Call<'a> { pub id_json: Option<&'a str>, /// Name of the method that is being called. pub method: &'a str, - /// JSON-formatted list of parameters. - pub params_json: &'a str, + /// JSON-formatted list of parameters. `None` iff the `params` field is missing. + pub params_json: Option<&'a str>, } /// Error while parsing a call. @@ -206,7 +206,7 @@ struct SerdeCall<'a> { #[serde(borrow)] method: &'a str, #[serde(borrow)] - params: &'a serde_json::value::RawValue, + params: Option<&'a serde_json::value::RawValue>, } #[derive(Debug, PartialEq, Clone, Copy, Hash, Eq)] @@ -335,7 +335,7 @@ mod tests { .unwrap(); assert_eq!(call.id_json.unwrap(), "5"); assert_eq!(call.method, "foo"); - assert_eq!(call.params_json, "[5,true, \"hello\"]"); + assert_eq!(call.params_json, Some("[5,true, \"hello\"]")); } #[test] @@ -343,7 +343,7 @@ mod tests { let call = super::parse_call(r#"{"jsonrpc":"2.0","method":"foo","params":[]}"#).unwrap(); assert!(call.id_json.is_none()); assert_eq!(call.method, "foo"); - assert_eq!(call.params_json, "[]"); + assert_eq!(call.params_json, Some("[]")); } #[test] @@ -353,7 +353,7 @@ mod tests { .unwrap(); assert_eq!(call.id_json.unwrap(), "\"hello\""); assert_eq!(call.method, "foo"); - assert_eq!(call.params_json, "[]"); + assert_eq!(call.params_json, Some("[]")); } #[test] @@ -363,7 +363,15 @@ mod tests { .unwrap(); assert_eq!(call.id_json.unwrap(), r#""extern:\"health-checker:0\"""#); assert_eq!(call.method, "system_health"); - assert_eq!(call.params_json, "[]"); + assert_eq!(call.params_json, Some("[]")); + } + + #[test] + fn missing_params() { + let call = super::parse_call(r#"{"jsonrpc":"2.0","id":2,"method":"foo"}"#).unwrap(); + assert_eq!(call.id_json.unwrap(), r#"2"#); + assert_eq!(call.method, "foo"); + assert_eq!(call.params_json, None); } #[test]