mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: remove InspectorStack (#8073)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -7278,7 +7278,6 @@ dependencies = [
|
||||
"reth-primitives",
|
||||
"reth-provider",
|
||||
"reth-prune",
|
||||
"reth-revm",
|
||||
"reth-rpc",
|
||||
"reth-rpc-engine-api",
|
||||
"reth-stages",
|
||||
|
||||
@ -20,7 +20,6 @@ use reth_revm::{
|
||||
batch::{BlockBatchRecord, BlockExecutorStats},
|
||||
db::states::bundle_state::BundleRetention,
|
||||
eth_dao_fork::{DAO_HARDFORK_BENEFICIARY, DAO_HARDKFORK_ACCOUNTS},
|
||||
stack::InspectorStack,
|
||||
state_change::{apply_beacon_root_contract_call, post_block_balance_increments},
|
||||
Evm, State,
|
||||
};
|
||||
@ -36,7 +35,6 @@ use tracing::debug;
|
||||
pub struct EthExecutorProvider<EvmConfig = EthEvmConfig> {
|
||||
chain_spec: Arc<ChainSpec>,
|
||||
evm_config: EvmConfig,
|
||||
inspector: Option<InspectorStack>,
|
||||
}
|
||||
|
||||
impl EthExecutorProvider {
|
||||
@ -54,13 +52,7 @@ impl EthExecutorProvider {
|
||||
impl<EvmConfig> EthExecutorProvider<EvmConfig> {
|
||||
/// Creates a new executor provider.
|
||||
pub fn new(chain_spec: Arc<ChainSpec>, evm_config: EvmConfig) -> Self {
|
||||
Self { chain_spec, evm_config, inspector: None }
|
||||
}
|
||||
|
||||
/// Configures an optional inspector stack for debugging.
|
||||
pub fn with_inspector(mut self, inspector: Option<InspectorStack>) -> Self {
|
||||
self.inspector = inspector;
|
||||
self
|
||||
Self { chain_spec, evm_config }
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +70,6 @@ where
|
||||
self.evm_config.clone(),
|
||||
State::builder().with_database(db).with_bundle_update().without_state_clear().build(),
|
||||
)
|
||||
.with_inspector(self.inspector.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,20 +212,12 @@ pub struct EthBlockExecutor<EvmConfig, DB> {
|
||||
executor: EthEvmExecutor<EvmConfig>,
|
||||
/// The state to use for execution
|
||||
state: State<DB>,
|
||||
/// Optional inspector stack for debugging
|
||||
inspector: Option<InspectorStack>,
|
||||
}
|
||||
|
||||
impl<EvmConfig, DB> EthBlockExecutor<EvmConfig, DB> {
|
||||
/// Creates a new Ethereum block executor.
|
||||
pub fn new(chain_spec: Arc<ChainSpec>, evm_config: EvmConfig, state: State<DB>) -> Self {
|
||||
Self { executor: EthEvmExecutor { chain_spec, evm_config }, state, inspector: None }
|
||||
}
|
||||
|
||||
/// Sets the inspector stack for debugging.
|
||||
pub fn with_inspector(mut self, inspector: Option<InspectorStack>) -> Self {
|
||||
self.inspector = inspector;
|
||||
self
|
||||
Self { executor: EthEvmExecutor { chain_spec, evm_config }, state }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -292,19 +275,9 @@ where
|
||||
let env = self.evm_env_for_block(&block.header, total_difficulty);
|
||||
|
||||
let (receipts, gas_used) = {
|
||||
if let Some(inspector) = self.inspector.as_mut() {
|
||||
let evm = self.executor.evm_config.evm_with_env_and_inspector(
|
||||
&mut self.state,
|
||||
env,
|
||||
inspector,
|
||||
);
|
||||
self.executor.execute_pre_and_transactions(block, evm)?
|
||||
} else {
|
||||
let evm = self.executor.evm_config.evm_with_env(&mut self.state, env);
|
||||
|
||||
self.executor.execute_pre_and_transactions(block, evm)?
|
||||
}
|
||||
};
|
||||
let evm = self.executor.evm_config.evm_with_env(&mut self.state, env);
|
||||
self.executor.execute_pre_and_transactions(block, evm)
|
||||
}?;
|
||||
|
||||
// 3. apply post execution changes
|
||||
self.post_execution(block, total_difficulty)?;
|
||||
@ -507,7 +480,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn executor_provider(chain_spec: Arc<ChainSpec>) -> EthExecutorProvider<EthEvmConfig> {
|
||||
EthExecutorProvider { chain_spec, evm_config: Default::default(), inspector: None }
|
||||
EthExecutorProvider { chain_spec, evm_config: Default::default() }
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! clap [Args](clap::Args) for debugging purposes
|
||||
|
||||
use clap::Args;
|
||||
use reth_primitives::{TxHash, B256};
|
||||
use reth_primitives::B256;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Parameters for debugging purposes
|
||||
@ -28,37 +28,6 @@ pub struct DebugArgs {
|
||||
#[arg(long = "debug.max-block", help_heading = "Debug")]
|
||||
pub max_block: Option<u64>,
|
||||
|
||||
/// Print opcode level traces directly to console during execution.
|
||||
#[arg(long = "debug.print-inspector", help_heading = "Debug")]
|
||||
pub print_inspector: bool,
|
||||
|
||||
/// Hook on a specific block during execution.
|
||||
#[arg(
|
||||
long = "debug.hook-block",
|
||||
help_heading = "Debug",
|
||||
conflicts_with = "hook_transaction",
|
||||
conflicts_with = "hook_all"
|
||||
)]
|
||||
pub hook_block: Option<u64>,
|
||||
|
||||
/// Hook on a specific transaction during execution.
|
||||
#[arg(
|
||||
long = "debug.hook-transaction",
|
||||
help_heading = "Debug",
|
||||
conflicts_with = "hook_block",
|
||||
conflicts_with = "hook_all"
|
||||
)]
|
||||
pub hook_transaction: Option<TxHash>,
|
||||
|
||||
/// Hook on every transaction in a block.
|
||||
#[arg(
|
||||
long = "debug.hook-all",
|
||||
help_heading = "Debug",
|
||||
conflicts_with = "hook_block",
|
||||
conflicts_with = "hook_transaction"
|
||||
)]
|
||||
pub hook_all: bool,
|
||||
|
||||
/// If provided, the engine will skip `n` consecutive FCUs.
|
||||
#[arg(long = "debug.skip-fcu", help_heading = "Debug")]
|
||||
pub skip_fcu: Option<usize>,
|
||||
|
||||
@ -85,8 +85,7 @@ where
|
||||
) -> eyre::Result<(Self::EVM, Self::Executor)> {
|
||||
let chain_spec = ctx.chain_spec();
|
||||
let evm_config = EthEvmConfig::default();
|
||||
let executor =
|
||||
EthExecutorProvider::new(chain_spec, evm_config).with_inspector(ctx.inspector_stack());
|
||||
let executor = EthExecutorProvider::new(chain_spec, evm_config);
|
||||
|
||||
Ok((evm_config, executor))
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ reth-blockchain-tree.workspace = true
|
||||
reth-exex.workspace = true
|
||||
reth-evm.workspace = true
|
||||
reth-provider.workspace = true
|
||||
reth-revm.workspace = true
|
||||
reth-db.workspace = true
|
||||
reth-rpc-engine-api.workspace = true
|
||||
reth-rpc.workspace = true
|
||||
|
||||
@ -27,7 +27,6 @@ use reth_node_core::{
|
||||
};
|
||||
use reth_primitives::{constants::eip4844::MAINNET_KZG_TRUSTED_SETUP, ChainSpec};
|
||||
use reth_provider::{providers::BlockchainProvider, ChainSpecProvider};
|
||||
use reth_revm::stack::{InspectorStack, InspectorStackConfig};
|
||||
use reth_tasks::TaskExecutor;
|
||||
use reth_transaction_pool::{PoolConfig, TransactionPool};
|
||||
pub use states::*;
|
||||
@ -461,28 +460,6 @@ impl<Node: FullNodeTypes> BuilderContext<Node> {
|
||||
&self.config
|
||||
}
|
||||
|
||||
/// Returns an inspector stack if configured.
|
||||
///
|
||||
/// This can be used to debug block execution.
|
||||
pub fn inspector_stack(&self) -> Option<InspectorStack> {
|
||||
use reth_revm::stack::Hook;
|
||||
let stack_config = InspectorStackConfig {
|
||||
use_printer_tracer: self.config.debug.print_inspector,
|
||||
hook: if let Some(hook_block) = self.config.debug.hook_block {
|
||||
Hook::Block(hook_block)
|
||||
} else if let Some(tx) = self.config.debug.hook_transaction {
|
||||
Hook::Transaction(tx)
|
||||
} else if self.config.debug.hook_all {
|
||||
Hook::All
|
||||
} else {
|
||||
// no inspector
|
||||
return None
|
||||
},
|
||||
};
|
||||
|
||||
Some(InspectorStack::new(stack_config))
|
||||
}
|
||||
|
||||
/// Returns the data dir of the node.
|
||||
///
|
||||
/// This gives access to all relevant files and directories of the node's datadir.
|
||||
|
||||
@ -19,7 +19,6 @@ use reth_primitives::{
|
||||
use reth_revm::{
|
||||
batch::{BlockBatchRecord, BlockExecutorStats},
|
||||
db::states::bundle_state::BundleRetention,
|
||||
stack::InspectorStack,
|
||||
state_change::{apply_beacon_root_contract_call, post_block_balance_increments},
|
||||
Evm, State,
|
||||
};
|
||||
@ -35,7 +34,6 @@ use tracing::{debug, trace};
|
||||
pub struct OpExecutorProvider<EvmConfig = OptimismEvmConfig> {
|
||||
chain_spec: Arc<ChainSpec>,
|
||||
evm_config: EvmConfig,
|
||||
inspector: Option<InspectorStack>,
|
||||
}
|
||||
|
||||
impl OpExecutorProvider {
|
||||
@ -48,13 +46,7 @@ impl OpExecutorProvider {
|
||||
impl<EvmConfig> OpExecutorProvider<EvmConfig> {
|
||||
/// Creates a new executor provider.
|
||||
pub fn new(chain_spec: Arc<ChainSpec>, evm_config: EvmConfig) -> Self {
|
||||
Self { chain_spec, evm_config, inspector: None }
|
||||
}
|
||||
|
||||
/// Configures an optional inspector stack for debugging.
|
||||
pub fn with_inspector(mut self, inspector: Option<InspectorStack>) -> Self {
|
||||
self.inspector = inspector;
|
||||
self
|
||||
Self { chain_spec, evm_config }
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +64,6 @@ where
|
||||
self.evm_config.clone(),
|
||||
State::builder().with_database(db).with_bundle_update().without_state_clear().build(),
|
||||
)
|
||||
.with_inspector(self.inspector.clone())
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,20 +259,12 @@ pub struct OpBlockExecutor<EvmConfig, DB> {
|
||||
executor: OpEvmExecutor<EvmConfig>,
|
||||
/// The state to use for execution
|
||||
state: State<DB>,
|
||||
/// Optional inspector stack for debugging
|
||||
inspector: Option<InspectorStack>,
|
||||
}
|
||||
|
||||
impl<EvmConfig, DB> OpBlockExecutor<EvmConfig, DB> {
|
||||
/// Creates a new Ethereum block executor.
|
||||
pub fn new(chain_spec: Arc<ChainSpec>, evm_config: EvmConfig, state: State<DB>) -> Self {
|
||||
Self { executor: OpEvmExecutor { chain_spec, evm_config }, state, inspector: None }
|
||||
}
|
||||
|
||||
/// Sets the inspector stack for debugging.
|
||||
pub fn with_inspector(mut self, inspector: Option<InspectorStack>) -> Self {
|
||||
self.inspector = inspector;
|
||||
self
|
||||
Self { executor: OpEvmExecutor { chain_spec, evm_config }, state }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -337,19 +320,9 @@ where
|
||||
let env = self.evm_env_for_block(&block.header, total_difficulty);
|
||||
|
||||
let (receipts, gas_used) = {
|
||||
if let Some(inspector) = self.inspector.as_mut() {
|
||||
let evm = self.executor.evm_config.evm_with_env_and_inspector(
|
||||
&mut self.state,
|
||||
env,
|
||||
inspector,
|
||||
);
|
||||
self.executor.execute_pre_and_transactions(block, evm)?
|
||||
} else {
|
||||
let evm = self.executor.evm_config.evm_with_env(&mut self.state, env);
|
||||
|
||||
self.executor.execute_pre_and_transactions(block, evm)?
|
||||
}
|
||||
};
|
||||
let evm = self.executor.evm_config.evm_with_env(&mut self.state, env);
|
||||
self.executor.execute_pre_and_transactions(block, evm)
|
||||
}?;
|
||||
|
||||
// 3. apply post execution changes
|
||||
self.post_execution(block, total_difficulty)?;
|
||||
@ -548,7 +521,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn executor_provider(chain_spec: Arc<ChainSpec>) -> OpExecutorProvider<OptimismEvmConfig> {
|
||||
OpExecutorProvider { chain_spec, evm_config: Default::default(), inspector: None }
|
||||
OpExecutorProvider { chain_spec, evm_config: Default::default() }
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -105,8 +105,7 @@ where
|
||||
) -> eyre::Result<(Self::EVM, Self::Executor)> {
|
||||
let chain_spec = ctx.chain_spec();
|
||||
let evm_config = OptimismEvmConfig::default();
|
||||
let executor =
|
||||
OpExecutorProvider::new(chain_spec, evm_config).with_inspector(ctx.inspector_stack());
|
||||
let executor = OpExecutorProvider::new(chain_spec, evm_config);
|
||||
|
||||
Ok((evm_config, executor))
|
||||
}
|
||||
|
||||
@ -19,11 +19,6 @@ pub mod state_change;
|
||||
/// Ethereum DAO hardfork state change data.
|
||||
pub mod eth_dao_fork;
|
||||
|
||||
/// An inspector stack abstracting the implementation details of
|
||||
/// each inspector and allowing to hook on block/transaction execution,
|
||||
/// used in the main Reth executor.
|
||||
pub mod stack;
|
||||
|
||||
/// Common test helpers
|
||||
#[cfg(any(test, feature = "test-utils"))]
|
||||
pub mod test_utils;
|
||||
|
||||
@ -1,202 +0,0 @@
|
||||
use revm::{
|
||||
inspectors::CustomPrintTracer,
|
||||
interpreter::{CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter},
|
||||
primitives::{Address, Env, Log, B256, U256},
|
||||
Database, EvmContext, Inspector,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
/// A hook to inspect the execution of the EVM.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub enum Hook {
|
||||
/// No hook.
|
||||
#[default]
|
||||
None,
|
||||
/// Hook on a specific block.
|
||||
Block(u64),
|
||||
/// Hook on a specific transaction hash.
|
||||
Transaction(B256),
|
||||
/// Hooks on every transaction in a block.
|
||||
All,
|
||||
}
|
||||
|
||||
impl Hook {
|
||||
/// Returns `true` if this hook should be used.
|
||||
#[inline]
|
||||
pub fn is_enabled(&self, block_number: u64, tx_hash: &B256) -> bool {
|
||||
match self {
|
||||
Hook::None => false,
|
||||
Hook::Block(block) => block_number == *block,
|
||||
Hook::Transaction(hash) => hash == tx_hash,
|
||||
Hook::All => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An inspector that calls multiple inspectors in sequence.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct InspectorStack {
|
||||
/// An inspector that prints the opcode traces to the console.
|
||||
pub custom_print_tracer: Option<CustomPrintTracer>,
|
||||
/// The provided hook
|
||||
pub hook: Hook,
|
||||
}
|
||||
|
||||
impl Debug for InspectorStack {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("InspectorStack")
|
||||
.field("custom_print_tracer", &self.custom_print_tracer.is_some())
|
||||
.field("hook", &self.hook)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl InspectorStack {
|
||||
/// Creates a new inspector stack with the given configuration.
|
||||
#[inline]
|
||||
pub fn new(config: InspectorStackConfig) -> Self {
|
||||
Self {
|
||||
hook: config.hook,
|
||||
custom_print_tracer: config.use_printer_tracer.then(Default::default),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this inspector should be used.
|
||||
#[inline]
|
||||
pub fn should_inspect(&self, env: &Env, tx_hash: &B256) -> bool {
|
||||
self.custom_print_tracer.is_some() &&
|
||||
self.hook.is_enabled(env.block.number.saturating_to(), tx_hash)
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration for the inspectors.
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct InspectorStackConfig {
|
||||
/// Enable revm inspector printer.
|
||||
/// In execution this will print opcode level traces directly to console.
|
||||
pub use_printer_tracer: bool,
|
||||
|
||||
/// Hook on a specific block or transaction.
|
||||
pub hook: Hook,
|
||||
}
|
||||
|
||||
/// Helper macro to call the same method on multiple inspectors without resorting to dynamic
|
||||
/// dispatch.
|
||||
#[macro_export]
|
||||
macro_rules! call_inspectors {
|
||||
([$($inspector:expr),+ $(,)?], |$id:ident $(,)?| $call:expr $(,)?) => {{$(
|
||||
if let Some($id) = $inspector {
|
||||
$call
|
||||
}
|
||||
)+}}
|
||||
}
|
||||
|
||||
impl<DB> Inspector<DB> for InspectorStack
|
||||
where
|
||||
DB: Database,
|
||||
{
|
||||
#[inline]
|
||||
fn initialize_interp(&mut self, interp: &mut Interpreter, context: &mut EvmContext<DB>) {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
inspector.initialize_interp(interp, context);
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn step(&mut self, interp: &mut Interpreter, context: &mut EvmContext<DB>) {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
inspector.step(interp, context);
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn step_end(&mut self, interp: &mut Interpreter, context: &mut EvmContext<DB>) {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
inspector.step_end(interp, context);
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn log(&mut self, context: &mut EvmContext<DB>, log: &Log) {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
inspector.log(context, log);
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn call(
|
||||
&mut self,
|
||||
context: &mut EvmContext<DB>,
|
||||
inputs: &mut CallInputs,
|
||||
) -> Option<CallOutcome> {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
if let Some(outcome) = inspector.call(context, inputs) {
|
||||
return Some(outcome)
|
||||
}
|
||||
});
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn call_end(
|
||||
&mut self,
|
||||
context: &mut EvmContext<DB>,
|
||||
inputs: &CallInputs,
|
||||
outcome: CallOutcome,
|
||||
) -> CallOutcome {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
let new_ret = inspector.call_end(context, inputs, outcome.clone());
|
||||
|
||||
// If the inspector returns a different ret or a revert with a non-empty message,
|
||||
// we assume it wants to tell us something
|
||||
if new_ret != outcome {
|
||||
return new_ret
|
||||
}
|
||||
});
|
||||
|
||||
outcome
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn create(
|
||||
&mut self,
|
||||
context: &mut EvmContext<DB>,
|
||||
inputs: &mut CreateInputs,
|
||||
) -> Option<CreateOutcome> {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
if let Some(out) = inspector.create(context, inputs) {
|
||||
return Some(out)
|
||||
}
|
||||
});
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn create_end(
|
||||
&mut self,
|
||||
context: &mut EvmContext<DB>,
|
||||
inputs: &CreateInputs,
|
||||
outcome: CreateOutcome,
|
||||
) -> CreateOutcome {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
let new_ret = inspector.create_end(context, inputs, outcome.clone());
|
||||
|
||||
// If the inspector returns a different ret or a revert with a non-empty message,
|
||||
// we assume it wants to tell us something
|
||||
if new_ret != outcome {
|
||||
return new_ret
|
||||
}
|
||||
});
|
||||
|
||||
outcome
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) {
|
||||
call_inspectors!([&mut self.custom_print_tracer], |inspector| {
|
||||
Inspector::<DB>::selfdestruct(inspector, contract, target, value);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user