diff --git a/bus-mapping/src/rpc.rs b/bus-mapping/src/rpc.rs index 1013c0e5281..0c331c2c728 100644 --- a/bus-mapping/src/rpc.rs +++ b/bus-mapping/src/rpc.rs @@ -1,6 +1,8 @@ //! Module which contains all the RPC calls that are needed at any point to query a Geth node in order to get a Block, Tx or Trace info. -use crate::eth_types::{Block, Hash, Transaction, U64}; +use crate::eth_types::{ + Block, GethExecTrace, Hash, ResultGethExecTrace, Transaction, U64, +}; use crate::Error; use ethers_providers::JsonRpcClient; @@ -78,6 +80,34 @@ impl GethClient

{ .await .map_err(|e| Error::JSONRpcError(e.into())) } + + /// Calls `debug_traceBlockByHash` via JSON-RPC returning a [`Vec`] with each GethTrace corresponding to 1 transaction of the block. + pub async fn trace_block_by_hash( + &self, + hash: Hash, + ) -> Result, Error> { + let hash = serialize(&hash); + let resp: ResultGethExecTrace = self + .0 + .request("debug_traceBlockByHash", [hash]) + .await + .map_err(|e| Error::JSONRpcError(e.into()))?; + Ok(resp.0.into_iter().map(|step| step.result).collect()) + } + + /// Calls `debug_traceBlockByNumber` via JSON-RPC returning a [`Vec`] with each GethTrace corresponding to 1 transaction of the block. + pub async fn trace_block_by_number( + &self, + block_num: BlockNumber, + ) -> Result, Error> { + let num = block_num.serialize(); + let resp: ResultGethExecTrace = self + .0 + .request("debug_traceBlockByNumber", [num]) + .await + .map_err(|e| Error::JSONRpcError(e.into()))?; + Ok(resp.0.into_iter().map(|step| step.result).collect()) + } } #[cfg(test)] @@ -89,12 +119,12 @@ mod rpc_tests { // The test is ignored as the values used depend on the Geth instance used each time you run the tests. // And we can't assume that everyone will have a Geth client synced with mainnet to have unified "test-vectors". - //#[ignore] + #[ignore] #[tokio::test] async fn test_get_block_by_hash() { let transport = Http::new(Url::parse("http://localhost:8545").unwrap()); - let hash = Hash::from_str("0x0492a44be5a74a6724bd666d308498c7a830a498f2c574768cbb25d09b4ec948").unwrap(); + let hash = Hash::from_str("0xe4f7aa19a76fcf31a6adff3b400300849e39dd84076765fb3af09d05ee9d787a").unwrap(); let prov = GethClient::new(transport); let block_by_hash = prov.get_block_by_hash(hash).await.unwrap(); assert!(hash == block_by_hash.hash.unwrap()); @@ -102,12 +132,12 @@ mod rpc_tests { // The test is ignored as the values used depend on the Geth instance used each time you run the tests. // And we can't assume that everyone will have a Geth client synced with mainnet to have unified "test-vectors". - //#[ignore] + #[ignore] #[tokio::test] async fn test_get_block_by_number() { let transport = Http::new(Url::parse("http://localhost:8545").unwrap()); - let hash = Hash::from_str("0x0492a44be5a74a6724bd666d308498c7a830a498f2c574768cbb25d09b4ec948").unwrap(); + let hash = Hash::from_str("0xe4f7aa19a76fcf31a6adff3b400300849e39dd84076765fb3af09d05ee9d787a").unwrap(); let prov = GethClient::new(transport); let block_by_num_latest = prov.get_block_by_number(BlockNumber::Latest).await.unwrap(); @@ -118,4 +148,38 @@ mod rpc_tests { == block_by_num_latest.transactions[0].hash ); } + + // The test is ignored as the values used depend on the Geth instance used each time you run the tests. + // And we can't assume that everyone will have a Geth client synced with mainnet to have unified "test-vectors". + #[ignore] + #[tokio::test] + async fn test_trace_block_by_hash() { + let transport = Http::new(Url::parse("http://localhost:8545").unwrap()); + + let hash = Hash::from_str("0xe2d191e9f663a3a950519eadeadbd614965b694a65a318a0b8f053f2d14261ff").unwrap(); + let prov = GethClient::new(transport); + let trace_by_hash = prov.trace_block_by_hash(hash).await.unwrap(); + // Since we called in the test block the same transaction twice the len should be the same and != 0. + assert!( + trace_by_hash[0].struct_logs.len() + == trace_by_hash[1].struct_logs.len() + ); + assert!(trace_by_hash[0].struct_logs.len() != 0); + } + + // The test is ignored as the values used depend on the Geth instance used each time you run the tests. + // And we can't assume that everyone will have a Geth client synced with mainnet to have unified "test-vectors". + //#[ignore] + #[tokio::test] + async fn test_trace_block_by_number() { + let transport = Http::new(Url::parse("http://localhost:8545").unwrap()); + let prov = GethClient::new(transport); + let trace_by_hash = prov.trace_block_by_number(5.into()).await.unwrap(); + // Since we called in the test block the same transaction twice the len should be the same and != 0. + assert!( + trace_by_hash[0].struct_logs.len() + == trace_by_hash[1].struct_logs.len() + ); + assert!(trace_by_hash[0].struct_logs.len() != 0); + } }