Parcourir la source

bin/darkfid/rpc: also return the hash of the last known(finalized) block

skoupidi il y a 1 an
Parent
commit
3153069aad

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

@@ -64,7 +64,7 @@ impl RequestHandler for DarkfiNode {
             // ==================
             "blockchain.get_block" => self.blockchain_get_block(req.id, req.params).await,
             "blockchain.get_tx" => self.blockchain_get_tx(req.id, req.params).await,
-            "blockchain.last_known_block" => self.blockchain_last_known_block(req.id, req.params).await,
+            "blockchain.last_finalized_block" => self.blockchain_last_finalized_block(req.id, req.params).await,
             "blockchain.best_fork_next_block_height" => self.blockchain_best_fork_next_block_height(req.id, req.params).await,
             "blockchain.block_target" => self.blockchain_block_target(req.id, req.params).await,
             "blockchain.lookup_zkas" => self.blockchain_lookup_zkas(req.id, req.params).await,

+ 19 - 14
bin/darkfid/src/rpc_blockchain.rs

@@ -117,28 +117,35 @@ impl DarkfiNode {
     }
 
     // RPCAPI:
-    // Queries the blockchain database to find the last known block.
+    // Queries the blockchain database to find the last finalized block.
     //
     // **Params:**
     // * `None`
     //
     // **Returns:**
-    // * `f64` Height of the last known block
+    // * `f64`   : Height of the last finalized block
+    // * `String`: Header hash of the last finalized block
     //
-    // --> {"jsonrpc": "2.0", "method": "blockchain.last_known_block", "params": [], "id": 1}
-    // <-- {"jsonrpc": "2.0", "result": 1234, "id": 1}
-    pub async fn blockchain_last_known_block(&self, id: u16, params: JsonValue) -> JsonResult {
+    // --> {"jsonrpc": "2.0", "method": "blockchain.last_finalized_block", "params": [], "id": 1}
+    // <-- {"jsonrpc": "2.0", "result": [1234, "HeaderHash"], "id": 1}
+    pub async fn blockchain_last_finalized_block(&self, id: u16, params: JsonValue) -> JsonResult {
         let params = params.get::<Vec<JsonValue>>().unwrap();
         if !params.is_empty() {
             return JsonError::new(InvalidParams, None, id).into()
         }
 
-        let blockchain = self.validator.blockchain.clone();
-        let Ok(last_block_height) = blockchain.last() else {
+        let Ok((height, hash)) = self.validator.blockchain.last() else {
             return JsonError::new(InternalError, None, id).into()
         };
 
-        JsonResponse::new(JsonValue::Number(last_block_height.0 as f64), id).into()
+        JsonResponse::new(
+            JsonValue::Array(vec![
+                JsonValue::Number(height as f64),
+                JsonValue::String(hash.to_string()),
+            ]),
+            id,
+        )
+        .into()
     }
 
     // RPCAPI:
@@ -148,7 +155,7 @@ impl DarkfiNode {
     // * `None`
     //
     // **Returns:**
-    // * `f64` Height of the last known block
+    // * `f64`: Current best fork next block height
     //
     // --> {"jsonrpc": "2.0", "method": "blockchain.best_fork_next_block_height", "params": [], "id": 1}
     // <-- {"jsonrpc": "2.0", "result": 1234, "id": 1}
@@ -176,7 +183,7 @@ impl DarkfiNode {
     // * `None`
     //
     // **Returns:**
-    // * `f64` Height of the last known block
+    // * `f64`: Current block target time
     //
     // --> {"jsonrpc": "2.0", "method": "blockchain.block_target", "params": [], "id": 1}
     // <-- {"jsonrpc": "2.0", "result": 1234, "id": 1}
@@ -267,10 +274,8 @@ impl DarkfiNode {
             }
         };
 
-        let blockchain = self.validator.blockchain.clone();
-
-        let Ok(zkas_db) = blockchain.contracts.lookup(
-            &blockchain.sled_db,
+        let Ok(zkas_db) = self.validator.blockchain.contracts.lookup(
+            &self.validator.blockchain.sled_db,
             &contract_id,
             SMART_CONTRACT_ZKAS_DB_NAME,
         ) else {

+ 29 - 24
bin/drk/src/rpc.rs

@@ -54,14 +54,11 @@ impl Drk {
         endpoint: Url,
         ex: Arc<smol::Executor<'static>>,
     ) -> Result<()> {
-        // Grab last known block
-        let rep = self
-            .darkfid_daemon_request("blockchain.last_known_block", &JsonValue::Array(vec![]))
-            .await?;
-        let mut last_known = *rep.get::<f64>().unwrap() as u32;
+        // Grab last finalized block
+        let (last_finalized, _) = self.get_last_finalized_block().await?;
 
         // Handle genesis(0) block
-        if last_known == 0 {
+        if last_finalized == 0 {
             if let Err(e) = self.scan_blocks().await {
                 return Err(Error::DatabaseError(format!(
                     "[subscribe_blocks] Scanning from genesis block failed: {e:?}"
@@ -69,11 +66,10 @@ impl Drk {
             }
         }
 
-        // Grab last known block again
-        let rep = self
-            .darkfid_daemon_request("blockchain.last_known_block", &JsonValue::Array(vec![]))
-            .await?;
-        last_known = *rep.get::<f64>().unwrap() as u32;
+        // Grab last finalized block again
+        let (last_finalized, _) = self.get_last_finalized_block().await?;
+
+        // Grab last scanned block
         let last_scanned = match self.get_last_scanned_block() {
             Ok((l, _)) => l,
             Err(e) => {
@@ -83,9 +79,9 @@ impl Drk {
             }
         };
 
-        // When no other block has been created
-        if last_known != last_scanned {
-            eprintln!("Warning: Last scanned block is not the last known block.");
+        // Check if other blocks have been created
+        if last_finalized != last_scanned {
+            eprintln!("Warning: Last scanned block is not the last finalized block.");
             eprintln!("You should first fully scan the blockchain, and then subscribe");
             return Err(Error::DatabaseError(
                 "[subscribe_blocks] Blockchain not fully scanned".to_string(),
@@ -266,27 +262,24 @@ impl Drk {
         }
 
         loop {
-            let rep = match self
-                .darkfid_daemon_request("blockchain.last_known_block", &JsonValue::Array(vec![]))
-                .await
-            {
-                Ok(r) => r,
+            // Grab last finalized block
+            let (last_height, last_hash) = match self.get_last_finalized_block().await {
+                Ok(last) => last,
                 Err(e) => {
                     eprintln!("[scan_blocks] RPC client request failed: {e:?}");
                     return Err(WalletDbError::GenericError)
                 }
             };
-            let last = *rep.get::<f64>().unwrap() as u32;
 
             println!("Requested to scan from block number: {height}");
-            println!("Last known block number reported by darkfid: {last}");
+            println!("Last finalized block reported by darkfid: {last_height} - {last_hash}");
 
-            // Already scanned last known block
-            if height > last {
+            // Already scanned last finalized block
+            if height > last_height {
                 return Ok(())
             }
 
-            while height <= last {
+            while height <= last_height {
                 println!("Requesting block {height}...");
                 let block = match self.get_block_by_height(height).await {
                     Ok(r) => r,
@@ -305,6 +298,18 @@ impl Drk {
         }
     }
 
+    // Queries darkfid for last finalized block.
+    async fn get_last_finalized_block(&self) -> Result<(u32, String)> {
+        let rep = self
+            .darkfid_daemon_request("blockchain.last_finalized_block", &JsonValue::Array(vec![]))
+            .await?;
+        let params = rep.get::<Vec<JsonValue>>().unwrap();
+        let height = *params[0].get::<f64>().unwrap() as u32;
+        let hash = params[1].get::<String>().unwrap().clone();
+
+        Ok((height, hash))
+    }
+
     // Queries darkfid for a block with given height.
     async fn get_block_by_height(&self, height: u32) -> Result<BlockInfo> {
         let params = self

+ 24 - 22
script/research/blockchain-explorer/src/rpc_blocks.rs

@@ -79,28 +79,18 @@ impl Explorerd {
         };
 
         loop {
-            let rep = match self
-                .darkfid_daemon_request("blockchain.last_known_block", &JsonValue::Array(vec![]))
-                .await
-            {
-                Ok(r) => r,
-                Err(e) => {
-                    let error_message = format!("[sync_blocks] RPC client request failed: {:?}", e);
-                    error!(target: "blockchain-explorer::rpc_blocks::sync_blocks", "{}", error_message);
-                    return Err(Error::DatabaseError(error_message));
-                }
-            };
-            let last = *rep.get::<f64>().unwrap() as u32;
+            // Grab last finalized block
+            let (last_height, last_hash) = self.get_last_finalized_block().await?;
 
             info!(target: "blockchain-explorer::rpc_blocks::sync_blocks", "Requested to sync from block number: {height}");
-            info!(target: "blockchain-explorer::rpc_blocks::sync_blocks", "Last known block number reported by darkfid: {last}");
+            info!(target: "blockchain-explorer::rpc_blocks::sync_blocks", "Last finalized block number reported by darkfid: {last_height} - {last_hash}");
 
-            // Already synced last known block
-            if height > last {
+            // Already synced last finalized block
+            if height > last_height {
                 return Ok(())
             }
 
-            while height <= last {
+            while height <= last_height {
                 let block = match self.get_block_by_height(height).await {
                     Ok(r) => r,
                     Err(e) => {
@@ -257,6 +247,18 @@ impl Explorerd {
             }
         }
     }
+
+    // Queries darkfid for last finalized block.
+    async fn get_last_finalized_block(&self) -> Result<(u32, String)> {
+        let rep = self
+            .darkfid_daemon_request("blockchain.last_finalized_block", &JsonValue::Array(vec![]))
+            .await?;
+        let params = rep.get::<Vec<JsonValue>>().unwrap();
+        let height = *params[0].get::<f64>().unwrap() as u32;
+        let hash = params[1].get::<String>().unwrap().clone();
+
+        Ok((height, hash))
+    }
 }
 
 /// Subscribes to darkfid's JSON-RPC notification endpoint that serves
@@ -266,10 +268,10 @@ pub async fn subscribe_blocks(
     endpoint: Url,
     ex: Arc<smol::Executor<'static>>,
 ) -> Result<(StoppableTaskPtr, StoppableTaskPtr)> {
-    let rep = explorer
-        .darkfid_daemon_request("blockchain.last_known_block", &JsonValue::Array(vec![]))
-        .await?;
-    let last_known = *rep.get::<f64>().unwrap() as u32;
+    // Grab last finalized block
+    let (last_finalized, _) = explorer.get_last_finalized_block().await?;
+
+    // Grab last synced block
     let last_synced = match explorer.db.last_block() {
         Ok(Some((height, _))) => height,
         Ok(None) => 0,
@@ -280,8 +282,8 @@ pub async fn subscribe_blocks(
         }
     };
 
-    if last_known != last_synced {
-        warn!(target: "blockchain-explorer::rpc_blocks::subscribe_blocks", "Warning: Last synced block is not the last known block.");
+    if last_finalized != last_synced {
+        warn!(target: "blockchain-explorer::rpc_blocks::subscribe_blocks", "Warning: Last synced block is not the last finalized block.");
         warn!(target: "blockchain-explorer::rpc_blocks::subscribe_blocks", "You should first fully sync the blockchain, and then subscribe");
         return Err(Error::DatabaseError(
             "[subscribe_blocks] Blockchain not fully synced".to_string(),