mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-30 09:38:24 -05:00
feat: support any Inspector for block + tx tracing (#6978)
Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
This commit is contained in:
@@ -287,6 +287,32 @@ pub trait EthTransactions: Send + Sync {
|
||||
F: FnOnce(TransactionInfo, TracingInspector, ResultAndState, StateCacheDB) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
self.spawn_trace_transaction_in_block_with_inspector(hash, TracingInspector::new(config), f)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Retrieves the transaction if it exists and returns its trace.
|
||||
///
|
||||
/// Before the transaction is traced, all previous transaction in the block are applied to the
|
||||
/// state by executing them first.
|
||||
/// The callback `f` is invoked with the [ResultAndState] after the transaction was executed and
|
||||
/// the database that points to the beginning of the transaction.
|
||||
///
|
||||
/// Note: Implementers should use a threadpool where blocking is allowed, such as
|
||||
/// [BlockingTaskPool](reth_tasks::pool::BlockingTaskPool).
|
||||
async fn spawn_trace_transaction_in_block_with_inspector<Insp, F, R>(
|
||||
&self,
|
||||
hash: B256,
|
||||
inspector: Insp,
|
||||
f: F,
|
||||
) -> EthResult<Option<R>>
|
||||
where
|
||||
F: FnOnce(TransactionInfo, Insp, ResultAndState, StateCacheDB) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
Insp: for<'a> Inspector<&'a mut StateCacheDB> + Send + 'static,
|
||||
R: Send + 'static;
|
||||
|
||||
/// Executes all transactions of a block and returns a list of callback results invoked for each
|
||||
@@ -306,17 +332,60 @@ pub trait EthTransactions: Send + Sync {
|
||||
f: F,
|
||||
) -> EthResult<Option<Vec<R>>>
|
||||
where
|
||||
// This is the callback that's invoked for each transaction with
|
||||
// This is the callback that's invoked for each transaction with the inspector, the result,
|
||||
// state and db
|
||||
F: for<'a> Fn(
|
||||
TransactionInfo,
|
||||
TracingInspector,
|
||||
ExecutionResult,
|
||||
&'a State,
|
||||
&'a CacheDB<StateProviderDatabase<StateProviderBox>>,
|
||||
&'a StateCacheDB,
|
||||
) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
R: Send + 'static;
|
||||
R: Send + 'static,
|
||||
{
|
||||
self.trace_block_until(block_id, None, config, f).await
|
||||
}
|
||||
|
||||
/// Executes all transactions of a block and returns a list of callback results invoked for each
|
||||
/// transaction in the block.
|
||||
///
|
||||
/// This
|
||||
/// 1. fetches all transactions of the block
|
||||
/// 2. configures the EVM evn
|
||||
/// 3. loops over all transactions and executes them
|
||||
/// 4. calls the callback with the transaction info, the execution result, the changed state
|
||||
/// _after_ the transaction [State] and the database that points to the state
|
||||
/// right _before_ the transaction, in other words the state the transaction was
|
||||
/// executed on: `changed_state = tx(cached_state)`
|
||||
///
|
||||
/// This accepts a `inspector_setup` closure that returns the inspector to be used for tracing
|
||||
/// a transaction. This is invoked for each transaction.
|
||||
async fn trace_block_with_inspector<Setup, Insp, F, R>(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
insp_setup: Setup,
|
||||
f: F,
|
||||
) -> EthResult<Option<Vec<R>>>
|
||||
where
|
||||
// This is the callback that's invoked for each transaction with the inspector, the result,
|
||||
// state and db
|
||||
F: for<'a> Fn(
|
||||
TransactionInfo,
|
||||
Insp,
|
||||
ExecutionResult,
|
||||
&'a State,
|
||||
&'a StateCacheDB,
|
||||
) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
Setup: FnMut() -> Insp + Send + 'static,
|
||||
Insp: for<'a> Inspector<&'a mut StateCacheDB> + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
self.trace_block_until_with_inspector(block_id, None, insp_setup, f).await
|
||||
}
|
||||
|
||||
/// Executes all transactions of a block.
|
||||
///
|
||||
@@ -336,10 +405,48 @@ pub trait EthTransactions: Send + Sync {
|
||||
TracingInspector,
|
||||
ExecutionResult,
|
||||
&'a State,
|
||||
&'a CacheDB<StateProviderDatabase<StateProviderBox>>,
|
||||
&'a StateCacheDB,
|
||||
) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
self.trace_block_until_with_inspector(
|
||||
block_id,
|
||||
highest_index,
|
||||
move || TracingInspector::new(config),
|
||||
f,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Executes all transactions of a block.
|
||||
///
|
||||
/// If a `highest_index` is given, this will only execute the first `highest_index`
|
||||
/// transactions, in other words, it will stop executing transactions after the
|
||||
/// `highest_index`th transaction.
|
||||
///
|
||||
/// This accepts a `inspector_setup` closure that returns the inspector to be used for tracing
|
||||
/// the transactions.
|
||||
async fn trace_block_until_with_inspector<Setup, Insp, F, R>(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
highest_index: Option<u64>,
|
||||
inspector_setup: Setup,
|
||||
f: F,
|
||||
) -> EthResult<Option<Vec<R>>>
|
||||
where
|
||||
F: for<'a> Fn(
|
||||
TransactionInfo,
|
||||
Insp,
|
||||
ExecutionResult,
|
||||
&'a State,
|
||||
&'a StateCacheDB,
|
||||
) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
Setup: FnMut() -> Insp + Send + 'static,
|
||||
Insp: for<'a> Inspector<&'a mut StateCacheDB> + Send + 'static,
|
||||
R: Send + 'static;
|
||||
}
|
||||
|
||||
@@ -883,16 +990,17 @@ where
|
||||
Ok(block.map(|block| (transaction, block.seal(block_hash))))
|
||||
}
|
||||
|
||||
async fn spawn_trace_transaction_in_block<F, R>(
|
||||
async fn spawn_trace_transaction_in_block_with_inspector<Insp, F, R>(
|
||||
&self,
|
||||
hash: B256,
|
||||
config: TracingInspectorConfig,
|
||||
mut inspector: Insp,
|
||||
f: F,
|
||||
) -> EthResult<Option<R>>
|
||||
where
|
||||
F: FnOnce(TransactionInfo, TracingInspector, ResultAndState, StateCacheDB) -> EthResult<R>
|
||||
F: FnOnce(TransactionInfo, Insp, ResultAndState, StateCacheDB) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
Insp: for<'a> Inspector<&'a mut StateCacheDB> + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
let (transaction, block) = match self.transaction_and_block(hash).await? {
|
||||
@@ -917,53 +1025,32 @@ where
|
||||
let env =
|
||||
EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, tx_env_with_recovered(&tx));
|
||||
|
||||
let mut inspector = TracingInspector::new(config);
|
||||
let (res, _, db) = inspect_and_return_db(db, env, &mut inspector)?;
|
||||
let (res, _) = inspect(&mut db, env, &mut inspector)?;
|
||||
f(tx_info, inspector, res, db)
|
||||
})
|
||||
.await
|
||||
.map(Some)
|
||||
}
|
||||
|
||||
async fn trace_block_with<F, R>(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
config: TracingInspectorConfig,
|
||||
f: F,
|
||||
) -> EthResult<Option<Vec<R>>>
|
||||
where
|
||||
// This is the callback that's invoked for each transaction with
|
||||
F: for<'a> Fn(
|
||||
TransactionInfo,
|
||||
TracingInspector,
|
||||
ExecutionResult,
|
||||
&'a State,
|
||||
&'a CacheDB<StateProviderDatabase<StateProviderBox>>,
|
||||
) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
self.trace_block_until(block_id, None, config, f).await
|
||||
}
|
||||
|
||||
async fn trace_block_until<F, R>(
|
||||
async fn trace_block_until_with_inspector<Setup, Insp, F, R>(
|
||||
&self,
|
||||
block_id: BlockId,
|
||||
highest_index: Option<u64>,
|
||||
config: TracingInspectorConfig,
|
||||
mut inspector_setup: Setup,
|
||||
f: F,
|
||||
) -> EthResult<Option<Vec<R>>>
|
||||
where
|
||||
F: for<'a> Fn(
|
||||
TransactionInfo,
|
||||
TracingInspector,
|
||||
Insp,
|
||||
ExecutionResult,
|
||||
&'a State,
|
||||
&'a CacheDB<StateProviderDatabase<StateProviderBox>>,
|
||||
&'a StateCacheDB,
|
||||
) -> EthResult<R>
|
||||
+ Send
|
||||
+ 'static,
|
||||
Setup: FnMut() -> Insp + Send + 'static,
|
||||
Insp: for<'a> Inspector<&'a mut StateCacheDB> + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
let ((cfg, block_env, _), block) =
|
||||
@@ -1010,7 +1097,7 @@ where
|
||||
while let Some((tx_info, tx)) = transactions.next() {
|
||||
let env = EnvWithHandlerCfg::new_with_cfg_env(cfg.clone(), block_env.clone(), tx);
|
||||
|
||||
let mut inspector = TracingInspector::new(config);
|
||||
let mut inspector = inspector_setup();
|
||||
let (res, _) = inspect(&mut db, env, &mut inspector)?;
|
||||
let ResultAndState { result, state } = res;
|
||||
results.push(f(tx_info, inspector, result, &state, &db)?);
|
||||
|
||||
Reference in New Issue
Block a user