From ae3914eb6642b5abaf8ce0495bbe37f09b76c1f4 Mon Sep 17 00:00:00 2001 From: "Supernovahs.eth" <91280922+supernovahs@users.noreply.github.com> Date: Thu, 19 Oct 2023 01:38:56 +0530 Subject: [PATCH] Builder style implementation for trace_call (#5074) --- crates/rpc/rpc-api/src/trace.rs | 14 +--- crates/rpc/rpc-types/src/eth/trace/mod.rs | 1 + .../rpc-types/src/eth/trace/tracerequest.rs | 82 +++++++++++++++++++ crates/rpc/rpc-types/src/eth/tracerequest.rs | 37 +++++++++ crates/rpc/rpc/src/trace.rs | 44 +++------- examples/trace-transaction-cli/src/main.rs | 18 ++-- 6 files changed, 141 insertions(+), 55 deletions(-) create mode 100644 crates/rpc/rpc-types/src/eth/trace/tracerequest.rs create mode 100644 crates/rpc/rpc-types/src/eth/tracerequest.rs diff --git a/crates/rpc/rpc-api/src/trace.rs b/crates/rpc/rpc-api/src/trace.rs index 557016a9a..a05a7bd9a 100644 --- a/crates/rpc/rpc-api/src/trace.rs +++ b/crates/rpc/rpc-api/src/trace.rs @@ -1,9 +1,8 @@ use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_primitives::{BlockId, Bytes, B256}; use reth_rpc_types::{ - state::StateOverride, - trace::{filter::TraceFilter, parity::*}, - BlockOverrides, CallRequest, Index, + trace::{filter::TraceFilter, parity::*, tracerequest::TraceRequest}, + CallRequest, Index, }; use std::collections::HashSet; @@ -13,14 +12,7 @@ use std::collections::HashSet; pub trait TraceApi { /// Executes the given call and returns a number of possible traces for it. #[method(name = "call")] - async fn trace_call( - &self, - call: CallRequest, - trace_types: HashSet, - block_id: Option, - state_overrides: Option, - block_overrides: Option>, - ) -> RpcResult; + async fn trace_call(&self, trace_request: TraceRequest) -> RpcResult; /// Performs multiple call traces on top of the same block. i.e. transaction n will be executed /// on top of a pending block with all n-1 transactions applied (traced) first. Allows to trace diff --git a/crates/rpc/rpc-types/src/eth/trace/mod.rs b/crates/rpc/rpc-types/src/eth/trace/mod.rs index d4ec6960f..8cd79eb2c 100644 --- a/crates/rpc/rpc-types/src/eth/trace/mod.rs +++ b/crates/rpc/rpc-types/src/eth/trace/mod.rs @@ -4,3 +4,4 @@ pub mod common; pub mod filter; pub mod geth; pub mod parity; +pub mod tracerequest; diff --git a/crates/rpc/rpc-types/src/eth/trace/tracerequest.rs b/crates/rpc/rpc-types/src/eth/trace/tracerequest.rs new file mode 100644 index 000000000..7b6b509eb --- /dev/null +++ b/crates/rpc/rpc-types/src/eth/trace/tracerequest.rs @@ -0,0 +1,82 @@ +//! Builder style functions for `trace_call` + +use crate::{state::StateOverride, trace::parity::TraceType, BlockOverrides, CallRequest}; +use reth_primitives::BlockId; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; + +/// Trace Request builder style function implementation +#[derive(Debug, Serialize, Deserialize)] +pub struct TraceRequest { + /// call request object + pub call: CallRequest, + /// trace types + pub trace_types: HashSet, + /// Optional: blockId + pub block_id: Option, + /// Optional: StateOverride + pub state_overrides: Option, + /// Optional: BlockOverrides + pub block_overrides: Option>, +} + +impl TraceRequest { + /// Returns a new [`TraceRequest`] given a [`CallRequest`] and [`HashSet`] + pub fn new(call: CallRequest) -> Self { + Self { + call, + trace_types: HashSet::new(), + block_id: None, + state_overrides: None, + block_overrides: None, + } + } + + /// Sets the [`BlockId`] + /// Note: this is optional + pub fn with_block_id(mut self, block_id: BlockId) -> Self { + self.block_id = Some(block_id); + self + } + + /// Sets the [`StateOverride`] + /// Note: this is optional + pub fn with_state_override(mut self, state_overrides: StateOverride) -> Self { + self.state_overrides = Some(state_overrides); + self + } + + /// Sets the [`BlockOverrides`] + /// Note: this is optional + pub fn with_block_overrides(mut self, block_overrides: Box) -> Self { + self.block_overrides = Some(block_overrides); + self + } + + /// Inserts a single trace type. + pub fn with_trace_type(mut self, trace_type: TraceType) -> Self { + self.trace_types.insert(trace_type); + self + } + + /// Inserts multiple trace types from an iterator. + pub fn with_trace_types>(mut self, trace_types: I) -> Self { + self.trace_types.extend(trace_types); + self + } + + /// Inserts [`TraceType::Trace`] + pub fn with_trace(self) -> Self { + self.with_trace_type(TraceType::Trace) + } + + /// Inserts [`TraceType::VmTrace`] + pub fn with_vm_trace(self) -> Self { + self.with_trace_type(TraceType::VmTrace) + } + + /// Inserts [`TraceType::StateDiff`] + pub fn with_statediff(self) -> Self { + self.with_trace_type(TraceType::StateDiff) + } +} diff --git a/crates/rpc/rpc-types/src/eth/tracerequest.rs b/crates/rpc/rpc-types/src/eth/tracerequest.rs new file mode 100644 index 000000000..d895c2367 --- /dev/null +++ b/crates/rpc/rpc-types/src/eth/tracerequest.rs @@ -0,0 +1,37 @@ +use crate::{CallRequest,state::StateOverride,BlockOverrides}; +use std::{collections::HashSet}; +use reth_primitives::{BlockId}; +use reth_rpc::{types::tracerequest::parity::TraceType}; + +pub struct TraceRequest{ + call: CallRequest, + trace_types: HashSet, + block_id: Option, + state_overrides: Option, + block_overrides: Option> +} + +impl TraceRequest{ + + pub fn new(call:CallRequest,trace_types:HashSet) -> Self{ + + Self { call,trace_types,block_id:None, state_overrides: None, block_overrides:None } + + } + + pub fn with_block_id(mut self, block_id: BlockId) -> Self{ + self.block_id = Some(block_id); + self + } + + pub fn with_state_override(mut self, state_overrides:StateOverride) -> Self{ + self.state_overrides = Some(state_overrides); + self + } + + pub fn with_block_overrides(mut self, block_overrides:Box) -> Self{ + self.block_overrides = Some(block_overrides); + self + } + +} \ No newline at end of file diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 121625dc8..54cca2012 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -19,9 +19,8 @@ use reth_revm::{ }; use reth_rpc_api::TraceApiServer; use reth_rpc_types::{ - state::StateOverride, - trace::{filter::TraceFilter, parity::*}, - BlockError, BlockOverrides, CallRequest, Index, + trace::{filter::TraceFilter, parity::*, tracerequest::TraceRequest}, + BlockError, CallRequest, Index, }; use revm::{db::CacheDB, primitives::Env}; use revm_primitives::db::DatabaseCommit; @@ -65,25 +64,19 @@ where Eth: EthTransactions + 'static, { /// Executes the given call and returns a number of possible traces for it. - pub async fn trace_call( - &self, - call: CallRequest, - trace_types: HashSet, - block_id: Option, - state_overrides: Option, - block_overrides: Option>, - ) -> EthResult { - let at = block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)); - let config = tracing_config(&trace_types); - let overrides = EvmOverrides::new(state_overrides, block_overrides); + pub async fn trace_call(&self, trace_request: TraceRequest) -> EthResult { + let at = trace_request.block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)); + let config = tracing_config(&trace_request.trace_types); + let overrides = + EvmOverrides::new(trace_request.state_overrides, trace_request.block_overrides); let mut inspector = TracingInspector::new(config); self.inner .eth_api - .spawn_with_call_at(call, at, overrides, move |db, env| { + .spawn_with_call_at(trace_request.call, at, overrides, move |db, env| { let (res, _, db) = inspect_and_return_db(db, env, &mut inspector)?; let trace_res = inspector.into_parity_builder().into_trace_results_with_state( &res, - &trace_types, + &trace_request.trace_types, &db, )?; Ok(trace_res) @@ -439,24 +432,9 @@ where /// Executes the given call and returns a number of possible traces for it. /// /// Handler for `trace_call` - async fn trace_call( - &self, - call: CallRequest, - trace_types: HashSet, - block_id: Option, - state_overrides: Option, - block_overrides: Option>, - ) -> Result { + async fn trace_call(&self, trace_request: TraceRequest) -> Result { let _permit = self.acquire_trace_permit().await; - Ok(TraceApi::trace_call( - self, - call, - trace_types, - block_id, - state_overrides, - block_overrides, - ) - .await?) + Ok(TraceApi::trace_call(self, trace_request).await?) } /// Handler for `trace_callMany` diff --git a/examples/trace-transaction-cli/src/main.rs b/examples/trace-transaction-cli/src/main.rs index b79ec009c..6c77d779c 100644 --- a/examples/trace-transaction-cli/src/main.rs +++ b/examples/trace-transaction-cli/src/main.rs @@ -17,7 +17,10 @@ use reth::{ Cli, }, primitives::{Address, IntoRecoveredTransaction}, - rpc::{compat::transaction::transaction_to_call_request, types::trace::parity::TraceType}, + rpc::{ + compat::transaction::transaction_to_call_request, + types::trace::{parity::TraceType, tracerequest::TraceRequest}, + }, tasks::TaskSpawner, transaction_pool::TransactionPool, }; @@ -76,16 +79,9 @@ impl RethNodeCommandConfig for RethCliTxpoolExt { // trace the transaction with `trace_call` let callrequest = transaction_to_call_request(tx.to_recovered_transaction()); - if let Ok(trace_result) = traceapi - .trace_call( - callrequest, - HashSet::from([TraceType::Trace]), - None, - None, - None, - ) - .await - { + let tracerequest = + TraceRequest::new(callrequest).with_trace_type(TraceType::Trace); + if let Ok(trace_result) = traceapi.trace_call(tracerequest).await { println!( "trace result for transaction : {:?} is {:?}", tx.hash(),