Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
Add support for debug_traceBlockByHash/Number
Browse files Browse the repository at this point in the history
Following @ed255 suggestions the following extra JSON-RPC methods have
been provided support:
- debug_traceBlockByHash
- debug_traceBlockByNumber

Resolves: #23
  • Loading branch information
CPerezz committed Nov 16, 2021
1 parent 7198f57 commit 5fdaf3f
Showing 1 changed file with 69 additions and 5 deletions.
74 changes: 69 additions & 5 deletions bus-mapping/src/rpc.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -78,6 +80,34 @@ impl<P: JsonRpcClient> GethClient<P> {
.await
.map_err(|e| Error::JSONRpcError(e.into()))
}

/// Calls `debug_traceBlockByHash` via JSON-RPC returning a [`Vec<GethExecTrace>`] with each GethTrace corresponding to 1 transaction of the block.
pub async fn trace_block_by_hash(
&self,
hash: Hash,
) -> Result<Vec<GethExecTrace>, 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<GethExecTrace>`] with each GethTrace corresponding to 1 transaction of the block.
pub async fn trace_block_by_number(
&self,
block_num: BlockNumber,
) -> Result<Vec<GethExecTrace>, 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)]
Expand All @@ -89,25 +119,25 @@ 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());
}

// 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();
Expand All @@ -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);
}
}

0 comments on commit 5fdaf3f

Please sign in to comment.