Skip to content

Commit 92a1a9a

Browse files
committed
add TransferInspector to anvil Inspector
1 parent 623f852 commit 92a1a9a

File tree

3 files changed

+41
-27
lines changed

3 files changed

+41
-27
lines changed

Diff for: crates/anvil/src/eth/backend/mem/inspector.rs

+26-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use alloy_primitives::{Address, Log};
55
use foundry_evm::{
66
call_inspectors,
77
decode::decode_console_logs,
8-
inspectors::{LogCollector, TracingInspector},
8+
inspectors::{LogCollector, TracingInspector, TransferInspector},
99
revm::{
1010
interpreter::{
1111
CallInputs, CallOutcome, CreateInputs, CreateOutcome, EOFCreateInputs, Interpreter,
@@ -25,6 +25,8 @@ pub struct Inspector {
2525
pub tracer: Option<TracingInspector>,
2626
/// Collects all `console.sol` logs
2727
pub log_collector: Option<LogCollector>,
28+
/// Collects all internal ETH transfers as ERC20 transfer events.
29+
pub transfer: Option<TransferInspector>,
2830
}
2931

3032
impl Inspector {
@@ -80,6 +82,12 @@ impl Inspector {
8082
self.tracer = Some(TracingInspector::new(TracingInspectorConfig::all().with_state_diffs()));
8183
self
8284
}
85+
86+
/// Configures the `Tracer` [`revm::Inspector`] with a transfer event collector
87+
pub fn with_transfers(mut self) -> Self {
88+
self.transfer = Some(TransferInspector::new(false).with_logs(true));
89+
self
90+
}
8391
}
8492

8593
/// Prints the traces for the inspector
@@ -132,7 +140,7 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
132140
fn call(&mut self, ecx: &mut EvmContext<DB>, inputs: &mut CallInputs) -> Option<CallOutcome> {
133141
call_inspectors!(
134142
#[ret]
135-
[&mut self.tracer, &mut self.log_collector],
143+
[&mut self.tracer, &mut self.log_collector, &mut self.transfer],
136144
|inspector| inspector.call(ecx, inputs).map(Some),
137145
);
138146
None
@@ -156,11 +164,11 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
156164
ecx: &mut EvmContext<DB>,
157165
inputs: &mut CreateInputs,
158166
) -> Option<CreateOutcome> {
159-
if let Some(tracer) = &mut self.tracer {
160-
if let Some(out) = tracer.create(ecx, inputs) {
161-
return Some(out);
162-
}
163-
}
167+
call_inspectors!(
168+
#[ret]
169+
[&mut self.tracer, &mut self.transfer],
170+
|inspector| { inspector.create(ecx, inputs).map(Some) },
171+
);
164172
None
165173
}
166174

@@ -183,11 +191,11 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
183191
ecx: &mut EvmContext<DB>,
184192
inputs: &mut EOFCreateInputs,
185193
) -> Option<CreateOutcome> {
186-
if let Some(tracer) = &mut self.tracer {
187-
if let Some(out) = tracer.eofcreate(ecx, inputs) {
188-
return Some(out);
189-
}
190-
}
194+
call_inspectors!(
195+
#[ret]
196+
[&mut self.tracer, &mut self.transfer],
197+
|inspector| { inspector.eofcreate(ecx, inputs).map(Some) },
198+
);
191199
None
192200
}
193201

@@ -207,9 +215,12 @@ impl<DB: Database> revm::Inspector<DB> for Inspector {
207215

208216
#[inline]
209217
fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) {
210-
if let Some(tracer) = &mut self.tracer {
211-
revm::Inspector::<DB>::selfdestruct(tracer, contract, target, value);
212-
}
218+
call_inspectors!(
219+
[&mut self.tracer, &mut self.transfer],
220+
|inspector| {
221+
revm::Inspector::<DB>::selfdestruct(inspector, contract, target, value);
222+
},
223+
);
213224
}
214225
}
215226

Diff for: crates/anvil/src/eth/backend/mem/mod.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ use revm::{
106106
primitives::{BlobExcessGasAndPrice, HashMap, OptimismFields, ResultAndState},
107107
DatabaseCommit,
108108
};
109-
use revm_inspectors::transfer::TransferInspector;
110109
use std::{
111110
collections::BTreeMap,
112111
io::{Read, Write},
@@ -1561,28 +1560,32 @@ impl Backend {
15611560
env.block.basefee = U256::from(0);
15621561
}
15631562

1564-
// transact
1565-
let ResultAndState { result, state } = if trace_transfers {
1563+
let mut inspector = self.build_inspector();
1564+
if trace_transfers {
15661565
// prepare inspector to capture transfer inside the evm so they are
15671566
// recorded and included in logs
1568-
let mut inspector = TransferInspector::new(false).with_logs(true);
1567+
inspector = inspector.with_transfers();
1568+
}
1569+
1570+
// transact
1571+
let ResultAndState { result, state } = {
15691572
let mut evm =
1570-
self.new_evm_with_inspector_ref(cache_db.as_dyn(), env, &mut inspector);
1573+
self.new_evm_with_inspector_ref(cache_db.as_dyn(), env, &mut inspector);
1574+
15711575
trace!(target: "backend", env=?evm.context.env(), spec=?evm.spec_id(), "simulate evm env");
15721576
evm.transact()?
1573-
} else {
1574-
let mut inspector = self.build_inspector();
1575-
let mut evm =
1576-
self.new_evm_with_inspector_ref(cache_db.as_dyn(), env, &mut inspector);
1577-
trace!(target: "backend", env=?evm.context.env(),spec=?evm.spec_id(), "simulate evm env");
1578-
evm.transact()?
15791577
};
15801578
trace!(target: "backend", ?result, ?request, "simulate call");
15811579

15821580
// commit the transaction
15831581
cache_db.commit(state);
15841582
gas_used += result.gas_used();
15851583

1584+
inspector.print_logs();
1585+
if self.print_traces {
1586+
inspector.into_print_traces();
1587+
}
1588+
15861589
// TODO: this is likely incomplete
15871590
// create the transaction from a request
15881591
let from = request.from.unwrap_or_default();

Diff for: crates/evm/evm/src/inspectors/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub use foundry_evm_coverage::CoverageCollector;
55
pub use foundry_evm_fuzz::Fuzzer;
66
pub use foundry_evm_traces::{StackSnapshotType, TracingInspector, TracingInspectorConfig};
77

8-
pub use revm_inspectors::access_list::AccessListInspector;
8+
pub use revm_inspectors::{access_list::AccessListInspector, transfer::TransferInspector};
99

1010
mod chisel_state;
1111
pub use chisel_state::ChiselState;

0 commit comments

Comments
 (0)