foundry_evm/executors/
trace.rs

1use crate::{
2    executors::{Executor, ExecutorBuilder},
3    Env,
4};
5use alloy_primitives::Address;
6use foundry_compilers::artifacts::EvmVersion;
7use foundry_config::{utils::evm_spec_id, Chain, Config};
8use foundry_evm_core::{backend::Backend, fork::CreateFork, opts::EvmOpts};
9use foundry_evm_traces::TraceMode;
10use revm::primitives::hardfork::SpecId;
11use std::ops::{Deref, DerefMut};
12
13/// A default executor with tracing enabled
14pub struct TracingExecutor {
15    executor: Executor,
16}
17
18impl TracingExecutor {
19    pub fn new(
20        env: Env,
21        fork: Option<CreateFork>,
22        version: Option<EvmVersion>,
23        trace_mode: TraceMode,
24        odyssey: bool,
25        create2_deployer: Address,
26    ) -> eyre::Result<Self> {
27        let db = Backend::spawn(fork)?;
28        Ok(Self {
29            // configures a bare version of the evm executor: no cheatcode inspector is enabled,
30            // tracing will be enabled only for the targeted transaction
31            executor: ExecutorBuilder::new()
32                .inspectors(|stack| {
33                    stack.trace_mode(trace_mode).odyssey(odyssey).create2_deployer(create2_deployer)
34                })
35                .spec_id(evm_spec_id(version.unwrap_or_default(), odyssey))
36                .build(env, db),
37        })
38    }
39
40    /// Returns the spec id of the executor
41    pub fn spec_id(&self) -> SpecId {
42        self.executor.spec_id()
43    }
44
45    /// uses the fork block number from the config
46    pub async fn get_fork_material(
47        config: &Config,
48        mut evm_opts: EvmOpts,
49    ) -> eyre::Result<(Env, Option<CreateFork>, Option<Chain>, bool)> {
50        evm_opts.fork_url = Some(config.get_rpc_url_or_localhost_http()?.into_owned());
51        evm_opts.fork_block_number = config.fork_block_number;
52
53        let env = evm_opts.evm_env().await?;
54
55        let fork = evm_opts.get_fork(config, env.clone());
56
57        Ok((env, fork, evm_opts.get_remote_chain_id().await, evm_opts.odyssey))
58    }
59}
60
61impl Deref for TracingExecutor {
62    type Target = Executor;
63
64    fn deref(&self) -> &Self::Target {
65        &self.executor
66    }
67}
68
69impl DerefMut for TracingExecutor {
70    fn deref_mut(&mut self) -> &mut Self::Target {
71        &mut self.executor
72    }
73}