diff --git a/crates/anvil/src/eth/backend/mem/inspector.rs b/crates/anvil/src/eth/backend/mem/inspector.rs index 0c37875180517..9b6f22f05e01a 100644 --- a/crates/anvil/src/eth/backend/mem/inspector.rs +++ b/crates/anvil/src/eth/backend/mem/inspector.rs @@ -19,6 +19,7 @@ use revm::{ interpreter::EthInterpreter, }, }; +use revm_inspectors::transfer::TransferInspector; use std::sync::Arc; /// The [`revm::Inspector`] used when transacting in the evm @@ -28,6 +29,8 @@ pub struct AnvilInspector { pub tracer: Option, /// Collects all `console.sol` logs pub log_collector: Option, + /// Collects all internal ETH transfers as ERC20 transfer events. + pub transfer: Option, } impl AnvilInspector { @@ -79,6 +82,12 @@ impl AnvilInspector { self } + /// Configures the `Tracer` [`revm::Inspector`] with a transfer event collector + pub fn with_transfers(mut self) -> Self { + self.transfer = Some(TransferInspector::new(false).with_logs(true)); + self + } + /// Configures the `Tracer` [`revm::Inspector`] with a trace printer pub fn with_trace_printer(mut self) -> Self { self.tracer = Some(TracingInspector::new(TracingInspectorConfig::all().with_state_diffs())); @@ -139,7 +148,7 @@ where fn call(&mut self, ecx: &mut CTX, inputs: &mut CallInputs) -> Option { call_inspectors!( #[ret] - [&mut self.tracer, &mut self.log_collector], + [&mut self.tracer, &mut self.log_collector, &mut self.transfer], |inspector| inspector.call(ecx, inputs).map(Some), ); None @@ -152,11 +161,11 @@ where } fn create(&mut self, ecx: &mut CTX, inputs: &mut CreateInputs) -> Option { - if let Some(tracer) = &mut self.tracer - && let Some(out) = tracer.create(ecx, inputs) - { - return Some(out); - } + call_inspectors!( + #[ret] + [&mut self.tracer, &mut self.transfer], + |inspector| inspector.create(ecx, inputs).map(Some), + ); None } @@ -168,9 +177,9 @@ where #[inline] fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) { - if let Some(tracer) = &mut self.tracer { - >::selfdestruct(tracer, contract, target, value); - } + call_inspectors!([&mut self.tracer, &mut self.transfer], |inspector| { + Inspector::::selfdestruct(inspector, contract, target, value) + }); } } diff --git a/crates/anvil/src/eth/backend/mem/mod.rs b/crates/anvil/src/eth/backend/mem/mod.rs index e9ee34c63f8ce..d133464bab0d7 100644 --- a/crates/anvil/src/eth/backend/mem/mod.rs +++ b/crates/anvil/src/eth/backend/mem/mod.rs @@ -118,7 +118,6 @@ use revm::{ primitives::{KECCAK_EMPTY, hardfork::SpecId}, state::AccountInfo, }; -use revm_inspectors::transfer::TransferInspector; use std::{ collections::BTreeMap, fmt::Debug, @@ -1693,11 +1692,13 @@ impl Backend { env.evm_env.block_env.basefee = 0; } + let mut inspector = self.build_inspector(); + // transact let ResultAndState { result, state } = if trace_transfers { // prepare inspector to capture transfer inside the evm so they are // recorded and included in logs - let mut inspector = TransferInspector::new(false).with_logs(true); + inspector = inspector.with_transfers(); let mut evm= self.new_evm_with_inspector_ref( &cache_db as &dyn DatabaseRef, &env, @@ -1707,7 +1708,6 @@ impl Backend { trace!(target: "backend", env=?env.evm_env, spec=?env.evm_env.spec_id(),"simulate evm env"); evm.transact(env.tx)? } else { - let mut inspector = self.build_inspector(); let mut evm = self.new_evm_with_inspector_ref( &cache_db as &dyn DatabaseRef, &env, @@ -1718,6 +1718,11 @@ impl Backend { }; trace!(target: "backend", ?result, ?request, "simulate call"); + inspector.print_logs(); + if self.print_traces { + inspector.into_print_traces(self.call_trace_decoder.clone()); + } + // commit the transaction cache_db.commit(state); gas_used += result.gas_used();