foundry_evm/executors/
trace.rs

1use crate::{
2    Env,
3    executors::{Executor, ExecutorBuilder},
4};
5use alloy_primitives::{Address, U256, map::HashMap};
6use alloy_rpc_types::state::StateOverride;
7use eyre::Context;
8use foundry_compilers::artifacts::EvmVersion;
9use foundry_config::{Chain, Config, utils::evm_spec_id};
10use foundry_evm_core::{backend::Backend, fork::CreateFork, opts::EvmOpts};
11use foundry_evm_networks::NetworkConfigs;
12use foundry_evm_traces::TraceMode;
13use revm::{primitives::hardfork::SpecId, state::Bytecode};
14use std::ops::{Deref, DerefMut};
15
16/// A default executor with tracing enabled
17pub struct TracingExecutor {
18    executor: Executor,
19}
20
21impl TracingExecutor {
22    pub fn new(
23        env: Env,
24        fork: Option<CreateFork>,
25        version: Option<EvmVersion>,
26        trace_mode: TraceMode,
27        networks: NetworkConfigs,
28        create2_deployer: Address,
29        state_overrides: Option<StateOverride>,
30    ) -> eyre::Result<Self> {
31        let db = Backend::spawn(fork)?;
32        // configures a bare version of the evm executor: no cheatcode inspector is enabled,
33        // tracing will be enabled only for the targeted transaction
34        let mut executor = ExecutorBuilder::new()
35            .inspectors(|stack| {
36                stack.trace_mode(trace_mode).networks(networks).create2_deployer(create2_deployer)
37            })
38            .spec_id(evm_spec_id(version.unwrap_or_default()))
39            .build(env, db);
40
41        // Apply the state overrides.
42        if let Some(state_overrides) = state_overrides {
43            for (address, overrides) in state_overrides {
44                if let Some(balance) = overrides.balance {
45                    executor.set_balance(address, balance)?;
46                }
47                if let Some(nonce) = overrides.nonce {
48                    executor.set_nonce(address, nonce)?;
49                }
50                if let Some(code) = overrides.code {
51                    let bytecode = Bytecode::new_raw_checked(code)
52                        .wrap_err("invalid bytecode in state override")?;
53                    executor.set_code(address, bytecode)?;
54                }
55                if let Some(state) = overrides.state {
56                    let state: HashMap<U256, U256> = state
57                        .into_iter()
58                        .map(|(slot, value)| (slot.into(), value.into()))
59                        .collect();
60                    executor.set_storage(address, state)?;
61                }
62                if let Some(state_diff) = overrides.state_diff {
63                    for (slot, value) in state_diff {
64                        executor.set_storage_slot(address, slot.into(), value.into())?;
65                    }
66                }
67            }
68        }
69
70        Ok(Self { executor })
71    }
72
73    /// Returns the spec id of the executor
74    pub fn spec_id(&self) -> SpecId {
75        self.executor.spec_id()
76    }
77
78    /// uses the fork block number from the config
79    pub async fn get_fork_material(
80        config: &mut Config,
81        mut evm_opts: EvmOpts,
82    ) -> eyre::Result<(Env, Option<CreateFork>, Option<Chain>, NetworkConfigs)> {
83        evm_opts.fork_url = Some(config.get_rpc_url_or_localhost_http()?.into_owned());
84        evm_opts.fork_block_number = config.fork_block_number;
85
86        let env = evm_opts.evm_env().await?;
87
88        let fork = evm_opts.get_fork(config, env.clone());
89        let networks = evm_opts.networks.with_chain_id(env.evm_env.cfg_env.chain_id);
90        config.labels.extend(networks.precompiles_label());
91
92        Ok((env, fork, evm_opts.get_remote_chain_id().await, networks))
93    }
94}
95
96impl Deref for TracingExecutor {
97    type Target = Executor;
98
99    fn deref(&self) -> &Self::Target {
100        &self.executor
101    }
102}
103
104impl DerefMut for TracingExecutor {
105    fn deref_mut(&mut self) -> &mut Self::Target {
106        &mut self.executor
107    }
108}