Explorar o código

darkfid/rpc: new get_blocks fn added

x hai 1 día
pai
achega
9153fd8854
Modificáronse 2 ficheiros con 51 adicións e 1 borrados
  1. 50 1
      bin/darkfid/src/rpc/blockchain.rs
  2. 1 0
      bin/darkfid/src/rpc/mod.rs

+ 50 - 1
bin/darkfid/src/rpc/blockchain.rs

@@ -34,7 +34,7 @@ use darkfi::{
     util::encoding::base64,
 };
 
-use crate::{server_error, DarkfiNode, RpcError};
+use crate::{proto::BATCH, server_error, DarkfiNode, RpcError};
 
 impl DarkfiNode {
     // RPCAPI:
@@ -85,6 +85,55 @@ impl DarkfiNode {
         JsonResponse::new(JsonValue::String(block), id).into()
     }
 
+    // RPCAPI:
+    // Queries the blockchain database for up to `BATCH` blocks after
+    // the given height.
+    //
+    // **Params:**
+    // * `array[0]`: `u32` block height
+    //
+    // **Returns:**
+    // * `array[n]`: base64-encoded blocks.
+    //
+    // --> {"jsonrpc": "2.0", "method": "blockchain.get_blocks", "params": [0], "id": 1}
+    // <-- {"jsonrpc": "2.0", "result": ["base64encodedblock", "base64encodedblock"], "id": 1}
+    pub async fn blockchain_get_blocks(&self, id: i64, params: JsonValue) -> JsonResult {
+        let Some(params) = params.get::<Vec<JsonValue>>() else {
+            return JsonError::new(InvalidParams, None, id).into()
+        };
+        if params.len() != 1 || !params[0].is_number() {
+            return JsonError::new(InvalidParams, None, id).into()
+        }
+
+        let block_height = *params[0].get::<f64>().unwrap() as u32;
+        let block_heights: Vec<u32> = (block_height..block_height + BATCH as u32).collect();
+
+        let blocks = match self
+            .validator
+            .read()
+            .await
+            .blockchain
+            .get_blocks_by_heights(&block_heights)
+        {
+            Ok(v) => v,
+            Err(e) => {
+                error!(target: "darkfid::rpc::blockchain_get_blocks", "Failed fetching blocks by heights: {e}");
+                return JsonError::new(InternalError, None, id).into()
+            }
+        };
+
+        if blocks.is_empty() {
+            return server_error(RpcError::UnknownBlockHeight, id, None)
+        }
+
+        let mut ret = vec![];
+        for block in blocks {
+            ret.push(JsonValue::String(base64::encode(&serialize_async(&block).await)));
+        }
+
+        JsonResponse::new(JsonValue::Array(ret), id).into()
+    }
+
     // RPCAPI:
     // Queries the blockchain database for a given transaction.
     // Returns a base64 encoded `Transaction` object.

+ 1 - 0
bin/darkfid/src/rpc/mod.rs

@@ -70,6 +70,7 @@ impl RequestHandler<DefaultRpcHandler> for DarkfiNode {
             // Blockchain methods
             // ==================
             "blockchain.get_block" => self.blockchain_get_block(req.id, req.params).await,
+            "blockchain.get_blocks" => self.blockchain_get_blocks(req.id, req.params).await,
             "blockchain.get_tx" => self.blockchain_get_tx(req.id, req.params).await,
             "blockchain.get_difficulty" => self.blockchain_get_difficulty(req.id, req.params).await,
             "blockchain.last_confirmed_block" => self.blockchain_last_confirmed_block(req.id, req.params).await,