mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
Builder style implementation for trace_call (#5074)
This commit is contained in:
@ -1,9 +1,8 @@
|
|||||||
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
|
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
|
||||||
use reth_primitives::{BlockId, Bytes, B256};
|
use reth_primitives::{BlockId, Bytes, B256};
|
||||||
use reth_rpc_types::{
|
use reth_rpc_types::{
|
||||||
state::StateOverride,
|
trace::{filter::TraceFilter, parity::*, tracerequest::TraceRequest},
|
||||||
trace::{filter::TraceFilter, parity::*},
|
CallRequest, Index,
|
||||||
BlockOverrides, CallRequest, Index,
|
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
@ -13,14 +12,7 @@ use std::collections::HashSet;
|
|||||||
pub trait TraceApi {
|
pub trait TraceApi {
|
||||||
/// Executes the given call and returns a number of possible traces for it.
|
/// Executes the given call and returns a number of possible traces for it.
|
||||||
#[method(name = "call")]
|
#[method(name = "call")]
|
||||||
async fn trace_call(
|
async fn trace_call(&self, trace_request: TraceRequest) -> RpcResult<TraceResults>;
|
||||||
&self,
|
|
||||||
call: CallRequest,
|
|
||||||
trace_types: HashSet<TraceType>,
|
|
||||||
block_id: Option<BlockId>,
|
|
||||||
state_overrides: Option<StateOverride>,
|
|
||||||
block_overrides: Option<Box<BlockOverrides>>,
|
|
||||||
) -> RpcResult<TraceResults>;
|
|
||||||
|
|
||||||
/// Performs multiple call traces on top of the same block. i.e. transaction n will be executed
|
/// 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
|
/// on top of a pending block with all n-1 transactions applied (traced) first. Allows to trace
|
||||||
|
|||||||
@ -4,3 +4,4 @@ pub mod common;
|
|||||||
pub mod filter;
|
pub mod filter;
|
||||||
pub mod geth;
|
pub mod geth;
|
||||||
pub mod parity;
|
pub mod parity;
|
||||||
|
pub mod tracerequest;
|
||||||
|
|||||||
82
crates/rpc/rpc-types/src/eth/trace/tracerequest.rs
Normal file
82
crates/rpc/rpc-types/src/eth/trace/tracerequest.rs
Normal file
@ -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<TraceType>,
|
||||||
|
/// Optional: blockId
|
||||||
|
pub block_id: Option<BlockId>,
|
||||||
|
/// Optional: StateOverride
|
||||||
|
pub state_overrides: Option<StateOverride>,
|
||||||
|
/// Optional: BlockOverrides
|
||||||
|
pub block_overrides: Option<Box<BlockOverrides>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TraceRequest {
|
||||||
|
/// Returns a new [`TraceRequest`] given a [`CallRequest`] and [`HashSet<TraceType>`]
|
||||||
|
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<BlockOverrides>) -> 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<I: IntoIterator<Item = TraceType>>(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)
|
||||||
|
}
|
||||||
|
}
|
||||||
37
crates/rpc/rpc-types/src/eth/tracerequest.rs
Normal file
37
crates/rpc/rpc-types/src/eth/tracerequest.rs
Normal file
@ -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<TraceType>,
|
||||||
|
block_id: Option<BlockId>,
|
||||||
|
state_overrides: Option<StateOverride>,
|
||||||
|
block_overrides: Option<Box<BlockOverrides>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TraceRequest{
|
||||||
|
|
||||||
|
pub fn new(call:CallRequest,trace_types:HashSet<TraceType>) -> 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<BlockOverrides>) -> Self{
|
||||||
|
self.block_overrides = Some(block_overrides);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -19,9 +19,8 @@ use reth_revm::{
|
|||||||
};
|
};
|
||||||
use reth_rpc_api::TraceApiServer;
|
use reth_rpc_api::TraceApiServer;
|
||||||
use reth_rpc_types::{
|
use reth_rpc_types::{
|
||||||
state::StateOverride,
|
trace::{filter::TraceFilter, parity::*, tracerequest::TraceRequest},
|
||||||
trace::{filter::TraceFilter, parity::*},
|
BlockError, CallRequest, Index,
|
||||||
BlockError, BlockOverrides, CallRequest, Index,
|
|
||||||
};
|
};
|
||||||
use revm::{db::CacheDB, primitives::Env};
|
use revm::{db::CacheDB, primitives::Env};
|
||||||
use revm_primitives::db::DatabaseCommit;
|
use revm_primitives::db::DatabaseCommit;
|
||||||
@ -65,25 +64,19 @@ where
|
|||||||
Eth: EthTransactions + 'static,
|
Eth: EthTransactions + 'static,
|
||||||
{
|
{
|
||||||
/// Executes the given call and returns a number of possible traces for it.
|
/// Executes the given call and returns a number of possible traces for it.
|
||||||
pub async fn trace_call(
|
pub async fn trace_call(&self, trace_request: TraceRequest) -> EthResult<TraceResults> {
|
||||||
&self,
|
let at = trace_request.block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest));
|
||||||
call: CallRequest,
|
let config = tracing_config(&trace_request.trace_types);
|
||||||
trace_types: HashSet<TraceType>,
|
let overrides =
|
||||||
block_id: Option<BlockId>,
|
EvmOverrides::new(trace_request.state_overrides, trace_request.block_overrides);
|
||||||
state_overrides: Option<StateOverride>,
|
|
||||||
block_overrides: Option<Box<BlockOverrides>>,
|
|
||||||
) -> EthResult<TraceResults> {
|
|
||||||
let at = block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest));
|
|
||||||
let config = tracing_config(&trace_types);
|
|
||||||
let overrides = EvmOverrides::new(state_overrides, block_overrides);
|
|
||||||
let mut inspector = TracingInspector::new(config);
|
let mut inspector = TracingInspector::new(config);
|
||||||
self.inner
|
self.inner
|
||||||
.eth_api
|
.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 (res, _, db) = inspect_and_return_db(db, env, &mut inspector)?;
|
||||||
let trace_res = inspector.into_parity_builder().into_trace_results_with_state(
|
let trace_res = inspector.into_parity_builder().into_trace_results_with_state(
|
||||||
&res,
|
&res,
|
||||||
&trace_types,
|
&trace_request.trace_types,
|
||||||
&db,
|
&db,
|
||||||
)?;
|
)?;
|
||||||
Ok(trace_res)
|
Ok(trace_res)
|
||||||
@ -439,24 +432,9 @@ where
|
|||||||
/// Executes the given call and returns a number of possible traces for it.
|
/// Executes the given call and returns a number of possible traces for it.
|
||||||
///
|
///
|
||||||
/// Handler for `trace_call`
|
/// Handler for `trace_call`
|
||||||
async fn trace_call(
|
async fn trace_call(&self, trace_request: TraceRequest) -> Result<TraceResults> {
|
||||||
&self,
|
|
||||||
call: CallRequest,
|
|
||||||
trace_types: HashSet<TraceType>,
|
|
||||||
block_id: Option<BlockId>,
|
|
||||||
state_overrides: Option<StateOverride>,
|
|
||||||
block_overrides: Option<Box<BlockOverrides>>,
|
|
||||||
) -> Result<TraceResults> {
|
|
||||||
let _permit = self.acquire_trace_permit().await;
|
let _permit = self.acquire_trace_permit().await;
|
||||||
Ok(TraceApi::trace_call(
|
Ok(TraceApi::trace_call(self, trace_request).await?)
|
||||||
self,
|
|
||||||
call,
|
|
||||||
trace_types,
|
|
||||||
block_id,
|
|
||||||
state_overrides,
|
|
||||||
block_overrides,
|
|
||||||
)
|
|
||||||
.await?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handler for `trace_callMany`
|
/// Handler for `trace_callMany`
|
||||||
|
|||||||
@ -17,7 +17,10 @@ use reth::{
|
|||||||
Cli,
|
Cli,
|
||||||
},
|
},
|
||||||
primitives::{Address, IntoRecoveredTransaction},
|
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,
|
tasks::TaskSpawner,
|
||||||
transaction_pool::TransactionPool,
|
transaction_pool::TransactionPool,
|
||||||
};
|
};
|
||||||
@ -76,16 +79,9 @@ impl RethNodeCommandConfig for RethCliTxpoolExt {
|
|||||||
// trace the transaction with `trace_call`
|
// trace the transaction with `trace_call`
|
||||||
let callrequest =
|
let callrequest =
|
||||||
transaction_to_call_request(tx.to_recovered_transaction());
|
transaction_to_call_request(tx.to_recovered_transaction());
|
||||||
if let Ok(trace_result) = traceapi
|
let tracerequest =
|
||||||
.trace_call(
|
TraceRequest::new(callrequest).with_trace_type(TraceType::Trace);
|
||||||
callrequest,
|
if let Ok(trace_result) = traceapi.trace_call(tracerequest).await {
|
||||||
HashSet::from([TraceType::Trace]),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
println!(
|
println!(
|
||||||
"trace result for transaction : {:?} is {:?}",
|
"trace result for transaction : {:?} is {:?}",
|
||||||
tx.hash(),
|
tx.hash(),
|
||||||
|
|||||||
Reference in New Issue
Block a user