Explorar el Código

explorerd/service/blocks: handle duplicate PoW coin errors after reorgs

This update introduces code to ensure blocks with PoW rewards containing coins already applied to the contract state prior to a reorg are synced. Additionally, it brings awareness to the need for rolling back the contract state to a specific height during reorgs.
kalm hace 1 año
padre
commit
15fb9fd8ea
Se han modificado 1 ficheros con 16 adiciones y 1 borrados
  1. 16 1
      bin/explorer/explorerd/src/service/blocks.rs

+ 16 - 1
bin/explorer/explorerd/src/service/blocks.rs

@@ -32,6 +32,7 @@ use darkfi::{
 use darkfi_sdk::{
     crypto::{schnorr::Signature, MerkleTree},
     tx::TransactionHash,
+    ContractError,
 };
 use darkfi_serial::AsyncEncodable;
 
@@ -154,7 +155,21 @@ impl ExplorerService {
 
                 // Execute and apply state changes
                 let mut state_update = vec![call.data.data[0]];
-                state_update.append(&mut runtime.exec(&payload)?);
+                let exec_result = runtime.exec(&payload);
+
+                // Handle duplicate coin error (thrown as Custom(7)) after a reorg.
+                // Ensures blocks with PoW reward coin already applied to contract state syncs.
+                if let Err(Error::ContractError(ContractError::Custom(7))) = exec_result {
+                    warn!(target: "explorerd::blocks::put_block",
+                        "PoW reward coin already applied to the contract state for contract ID {} at height {} for tx: {}. Skipping re-application.",
+                        call.data.contract_id,
+                        block.header.height,
+                        tx.hash()
+                    );
+                    continue;
+                }
+
+                state_update.append(&mut exec_result?);
                 runtime.apply(&state_update)?;
 
                 // Append transaction hash to the Merkle tree