Bläddra i källkod

rpc: Allow params as JSON object

parazyd 2 år sedan
förälder
incheckning
235626b31d

+ 1 - 1
bin/darkfi-mmproxy/src/monero.rs

@@ -29,7 +29,7 @@ impl MiningProxy {
     pub async fn monero_get_block_count(&self, id: u16, params: JsonValue) -> JsonResult {
         debug!(target: "rpc::monero", "get_block_count()");
 
-        let req_body = JsonRequest::new("get_block_count", vec![]).stringify().unwrap();
+        let req_body = JsonRequest::new("get_block_count", vec![].into()).stringify().unwrap();
 
         let client = surf::Client::new();
         let mut response = client

+ 1 - 1
bin/darkfid2/src/proto/protocol_block.rs

@@ -128,7 +128,7 @@ impl ProtocolBlock {
                 Ok(()) => {
                     self.p2p.broadcast_with_exclude(&block_copy, &exclude_list).await;
                     let encoded_block = JsonValue::String(base64::encode(&serialize(&block_copy)));
-                    self.subscriber.notify(vec![encoded_block]).await;
+                    self.subscriber.notify(vec![encoded_block].into()).await;
                 }
                 Err(e) => {
                     debug!(

+ 1 - 1
bin/darkfid2/src/proto/protocol_proposal.rs

@@ -118,7 +118,7 @@ impl ProtocolProposal {
                 Ok(()) => {
                     self.p2p.broadcast_with_exclude(&proposal_copy, &exclude_list).await;
                     let enc_prop = JsonValue::String(base64::encode(&serialize(&proposal_copy)));
-                    self.subscriber.notify(vec![enc_prop]).await;
+                    self.subscriber.notify(vec![enc_prop].into()).await;
                 }
                 Err(e) => {
                     debug!(

+ 1 - 1
bin/darkfid2/src/proto/protocol_tx.rs

@@ -114,7 +114,7 @@ impl ProtocolTx {
                 Ok(()) => {
                     self.p2p.broadcast_with_exclude(&tx_copy, &exclude_list).await;
                     let encoded_tx = JsonValue::String(base64::encode(&serialize(&tx_copy)));
-                    self.subscriber.notify(vec![encoded_tx]).await;
+                    self.subscriber.notify(vec![encoded_tx].into()).await;
                 }
                 Err(e) => {
                     debug!(

+ 1 - 1
bin/darkfid2/src/task/sync.rs

@@ -73,7 +73,7 @@ pub async fn sync_task(node: &Darkfid) -> Result<()> {
         // Notify subscriber
         for block in &response.blocks {
             let encoded_block = JsonValue::String(base64::encode(&serialize(block)));
-            notif_sub.notify(vec![encoded_block]).await;
+            notif_sub.notify(vec![encoded_block].into()).await;
         }
 
         let last_received = node.validator.read().await.blockchain.last()?;

+ 1 - 1
bin/darkirc/src/main.rs

@@ -204,7 +204,7 @@ async fn realmain(args: Args, ex: Arc<Executor<'static>>) -> Result<()> {
             loop {
                 let event = dnet_sub.receive().await;
                 debug!("Got dnet event: {:?}", event);
-                dnet_sub_.notify(vec![event.into()]).await;
+                dnet_sub_.notify(vec![event.into()].into()).await;
             }
         },
         |res| async {

+ 1 - 1
bin/tau/taud/src/main.rs

@@ -468,7 +468,7 @@ async fn realmain(settings: Args, executor: Arc<smol::Executor<'static>>) -> Res
             loop {
                 let event = dnet_sub.receive().await;
                 debug!("Got dnet event: {:?}", event);
-                json_sub_.notify(vec![event.into()]).await;
+                json_sub_.notify(vec![event.into()].into()).await;
             }
         },
         |res| async {

+ 17 - 21
src/rpc/jsonrpc.rs

@@ -155,13 +155,9 @@ pub struct JsonRequest {
 impl JsonRequest {
     /// Create a new [`JsonRequest`] object with the given method and parameters.
     /// The request ID is chosen randomly.
-    pub fn new(method: &str, params: Vec<JsonValue>) -> Self {
-        Self {
-            jsonrpc: "2.0",
-            id: OsRng::gen(&mut OsRng),
-            method: method.to_string(),
-            params: JsonValue::Array(params),
-        }
+    pub fn new(method: &str, params: JsonValue) -> Self {
+        assert!(params.is_object() || params.is_array());
+        Self { jsonrpc: "2.0", id: OsRng::gen(&mut OsRng), method: method.to_string(), params }
     }
 
     /// Convert the object into a JSON string
@@ -213,29 +209,23 @@ impl TryFrom<&JsonValue> for JsonRequest {
             ))
         }
 
-        if !map.contains_key("params")
-        /* || !map["params"].is_array() */
-        {
+        if !map.contains_key("params") {
             return Err(RpcError::InvalidJson(
                 "Request does not contain valid \"params\" field".to_string(),
             ))
         }
 
-        let params = if map["params"].is_object() {
-            JsonValue::Array(vec![map["params"].clone()])
-        } else if map["params"].is_array() {
-            map["params"].clone()
-        } else {
+        if !map["params"].is_object() && !map["params"].is_array() {
             return Err(RpcError::InvalidJson(
                 "Request does not contain valid \"params\" field".to_string(),
             ))
-        };
+        }
 
         Ok(Self {
             jsonrpc: "2.0",
             id: *map["id"].get::<f64>().unwrap() as u16,
             method: map["method"].get::<String>().unwrap().clone(),
-            params,
+            params: map["params"].clone(),
         })
     }
 }
@@ -254,7 +244,7 @@ pub struct JsonNotification {
 impl JsonNotification {
     /// Create a new [`JsonNotification`] object with the given method and parameters.
     pub fn new(method: &str, params: JsonValue) -> Self {
-        assert!(params.is_array());
+        assert!(params.is_object() || params.is_array());
         Self { jsonrpc: "2.0", method: method.to_string(), params }
     }
 
@@ -300,12 +290,18 @@ impl TryFrom<&JsonValue> for JsonNotification {
             ))
         }
 
-        if !map.contains_key("params") || !map["params"].is_array() {
+        if !map.contains_key("params") {
             return Err(RpcError::InvalidJson(
                 "Notification does not contain valid \"params\" field".to_string(),
             ))
         }
 
+        if !map["params"].is_object() && !map["params"].is_array() {
+            return Err(RpcError::InvalidJson(
+                "Request does not contain valid \"params\" field".to_string(),
+            ))
+        }
+
         Ok(Self {
             jsonrpc: "2.0",
             method: map["method"].get::<String>().unwrap().clone(),
@@ -503,8 +499,8 @@ impl JsonSubscriber {
     }
 
     /// Send a notification to the subscriber with the given JSON object
-    pub async fn notify(&self, params: Vec<JsonValue>) {
-        let notification = JsonNotification::new(self.method, JsonValue::Array(params));
+    pub async fn notify(&self, params: JsonValue) {
+        let notification = JsonNotification::new(self.method, params);
         self.sub.notify(notification).await;
     }
 }

+ 2 - 2
tests/jsonrpc.rs

@@ -104,13 +104,13 @@ fn jsonrpc_reqrep() -> Result<()> {
         msleep(500).await;
 
         let client = RpcClient::new(endpoint, executor.clone()).await?;
-        let req = JsonRequest::new("ping", vec![]);
+        let req = JsonRequest::new("ping", vec![].into());
         let rep = client.request(req).await?;
 
         let rep = String::try_from(rep).unwrap();
         assert_eq!(&rep, "pong");
 
-        let req = JsonRequest::new("kill", vec![]);
+        let req = JsonRequest::new("kill", vec![].into());
         let rep = client.request(req).await?;
 
         let rep = String::try_from(rep).unwrap();