From b9e361cbeab40423d2651a9394f3e6f691509f5e Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:08:31 -0500 Subject: [PATCH] feat(rpc): implement debug_executionWitnessByHash (#14022) Co-authored-by: Roman Krasiuk --- crates/rpc/rpc-api/src/debug.rs | 14 +++++++++++- crates/rpc/rpc/src/debug.rs | 40 ++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/crates/rpc/rpc-api/src/debug.rs b/crates/rpc/rpc-api/src/debug.rs index c2d1c605f..281e0798f 100644 --- a/crates/rpc/rpc-api/src/debug.rs +++ b/crates/rpc/rpc-api/src/debug.rs @@ -136,11 +136,23 @@ pub trait DebugApi { /// to their preimages that were required during the execution of the block, including during /// state root recomputation. /// - /// The first argument is the block number or block hash. + /// The first argument is the block number or tag. #[method(name = "executionWitness")] async fn debug_execution_witness(&self, block: BlockNumberOrTag) -> RpcResult; + /// The `debug_executionWitnessByBlockHash` method allows for re-execution of a block with the + /// purpose of generating an execution witness. The witness comprises of a map of all hashed + /// trie nodes to their preimages that were required during the execution of the block, + /// including during state root recomputation. + /// + /// The first argument is the block hash. + #[method(name = "executionWitnessByBlockHash")] + async fn debug_execution_witness_by_block_hash( + &self, + hash: B256, + ) -> RpcResult; + /// Sets the logging backtrace location. When a backtrace location is set and a log message is /// emitted at that location, the stack of the goroutine executing the log statement will /// be printed to stderr. diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index fa0da3dec..fc6f27f60 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -596,10 +596,26 @@ where .await } + /// Generates an execution witness for the given block hash. see + /// [`Self::debug_execution_witness`] for more info. + pub async fn debug_execution_witness_by_block_hash( + &self, + hash: B256, + ) -> Result { + let this = self.clone(); + let block = this + .eth_api() + .block_with_senders(hash.into()) + .await? + .ok_or(EthApiError::HeaderNotFound(hash.into()))?; + + self.debug_execution_witness_for_block(block).await + } + /// The `debug_executionWitness` method allows for re-execution of a block with the purpose of - /// generating an execution witness. The witness comprises of a map of all hashed trie nodes - /// to their preimages that were required during the execution of the block, including during - /// state root recomputation. + /// generating an execution witness. The witness comprises of a map of all hashed trie nodes to + /// their preimages that were required during the execution of the block, including during state + /// root recomputation. pub async fn debug_execution_witness( &self, block_id: BlockNumberOrTag, @@ -611,6 +627,15 @@ where .await? .ok_or(EthApiError::HeaderNotFound(block_id.into()))?; + self.debug_execution_witness_for_block(block).await + } + + /// Generates an execution witness, using the given recovered block. + pub async fn debug_execution_witness_for_block( + &self, + block: Arc>>, + ) -> Result { + let this = self.clone(); self.eth_api() .spawn_with_state_at_block(block.parent_hash().into(), move |state_provider| { let db = StateProviderDatabase::new(&state_provider); @@ -976,6 +1001,15 @@ where Self::debug_execution_witness(self, block).await.map_err(Into::into) } + /// Handler for `debug_executionWitnessByBlockHash` + async fn debug_execution_witness_by_block_hash( + &self, + hash: B256, + ) -> RpcResult { + let _permit = self.acquire_trace_permit().await; + Self::debug_execution_witness_by_block_hash(self, hash).await.map_err(Into::into) + } + async fn debug_backtrace_at(&self, _location: &str) -> RpcResult<()> { Ok(()) }