diff --git a/Cargo.lock b/Cargo.lock index 63600a87e..02b9ddf6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5538,8 +5538,7 @@ dependencies = [ [[package]] name = "revm" version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f293f351c4c203d321744e54ed7eed3d2b6eef4c140228910dde3ac9a5ea8031" +source = "git+https://github.com/bluealloy/revm/?branch=release/v25#88337924f4d16ed1f5e4cde12a03d0cb755cd658" dependencies = [ "auto_impl", "revm-interpreter", @@ -5549,8 +5548,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a53980a26f9b5a66d13511c35074d4b53631e157850a1d7cf1af4efc2c2b72c9" +source = "git+https://github.com/bluealloy/revm/?branch=release/v25#88337924f4d16ed1f5e4cde12a03d0cb755cd658" dependencies = [ "derive_more", "enumn", @@ -5560,9 +5558,8 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a3eabf08ea9e4063f5531b8735e29344d9d6eaebaa314c58253f6c17fcdf2d" +version = "2.0.3" +source = "git+https://github.com/bluealloy/revm/?branch=release/v25#88337924f4d16ed1f5e4cde12a03d0cb755cd658" dependencies = [ "k256 0.13.1", "num", @@ -5578,8 +5575,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "304d998f466ffef72d76c7f20b05bf08a96801736a6fb1fdef47d49a292618df" +source = "git+https://github.com/bluealloy/revm/?branch=release/v25#88337924f4d16ed1f5e4cde12a03d0cb755cd658" dependencies = [ "arbitrary", "auto_impl", diff --git a/Cargo.toml b/Cargo.toml index 06996bb17..0a26c11eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,6 +73,9 @@ incremental = false # patched for quantity U256 responses ruint = { git = "https://github.com/paradigmxyz/uint" } +revm = { git = "https://github.com/bluealloy/revm/", branch = "release/v25" } +revm-primitives = { git = "https://github.com/bluealloy/revm/", branch = "release/v25" } + [workspace.dependencies] ## eth revm = { version = "3" } diff --git a/crates/revm/revm-inspectors/src/tracing/builder/parity.rs b/crates/revm/revm-inspectors/src/tracing/builder/parity.rs index 2ec9ec313..d79973f82 100644 --- a/crates/revm/revm-inspectors/src/tracing/builder/parity.rs +++ b/crates/revm/revm-inspectors/src/tracing/builder/parity.rs @@ -124,6 +124,11 @@ impl ParityTraceBuilder { let mut diff = StateDiff::default(); for (node, trace_address) in self.nodes.iter().zip(trace_addresses) { + // skip precompiles + if node.is_precompile() { + continue + } + if with_traces { let trace = node.parity_transaction_trace(trace_address); traces.push(trace); @@ -145,6 +150,7 @@ impl ParityTraceBuilder { self.nodes .into_iter() .zip(trace_addresses) + .filter(|(node, _)| !node.is_precompile()) .map(|(node, trace_address)| node.parity_transaction_trace(trace_address)) } diff --git a/crates/revm/revm-inspectors/src/tracing/config.rs b/crates/revm/revm-inspectors/src/tracing/config.rs index c476866c0..76821b29f 100644 --- a/crates/revm/revm-inspectors/src/tracing/config.rs +++ b/crates/revm/revm-inspectors/src/tracing/config.rs @@ -14,6 +14,8 @@ pub struct TracingInspectorConfig { pub record_stack_snapshots: bool, /// Whether to record state diffs. pub record_state_diff: bool, + /// Whether to ignore precompile calls. + pub exclude_precompile_calls: bool, } impl TracingInspectorConfig { @@ -24,6 +26,7 @@ impl TracingInspectorConfig { record_memory_snapshots: true, record_stack_snapshots: true, record_state_diff: false, + exclude_precompile_calls: false, } } @@ -36,6 +39,7 @@ impl TracingInspectorConfig { record_memory_snapshots: false, record_stack_snapshots: false, record_state_diff: false, + exclude_precompile_calls: true, } } @@ -48,6 +52,7 @@ impl TracingInspectorConfig { record_memory_snapshots: true, record_stack_snapshots: true, record_state_diff: true, + exclude_precompile_calls: false, } } @@ -61,6 +66,14 @@ impl TracingInspectorConfig { } } + /// Configure whether calls to precompiles should be ignored. + /// + /// If set to `true`, calls to precompiles without value transfers will be ignored. + pub fn set_exclude_precompile_calls(mut self, exclude_precompile_calls: bool) -> Self { + self.exclude_precompile_calls = exclude_precompile_calls; + self + } + /// Configure whether individual opcode level steps should be recorded pub fn set_steps(mut self, record_steps: bool) -> Self { self.record_steps = record_steps; diff --git a/crates/revm/revm-inspectors/src/tracing/mod.rs b/crates/revm/revm-inspectors/src/tracing/mod.rs index 22a09a2f6..d12503b2f 100644 --- a/crates/revm/revm-inspectors/src/tracing/mod.rs +++ b/crates/revm/revm-inspectors/src/tracing/mod.rs @@ -101,6 +101,7 @@ impl TracingInspector { /// Starts tracking a new trace. /// /// Invoked on [Inspector::call]. + #[allow(clippy::too_many_arguments)] fn start_trace_on_call( &mut self, depth: usize, @@ -109,6 +110,7 @@ impl TracingInspector { value: U256, kind: CallKind, caller: Address, + maybe_precompile: Option, ) { self.trace_stack.push(self.traces.push_trace( 0, @@ -121,6 +123,7 @@ impl TracingInspector { status: InstructionResult::Continue, caller, last_call_return_value: self.last_call_return_data.clone(), + maybe_precompile, ..Default::default() }, )); @@ -318,6 +321,12 @@ where _ => (inputs.context.caller, inputs.context.address), }; + // if calls to precompiles should be excluded, check whether this is a call to a precompile + let maybe_precompile = self + .config + .exclude_precompile_calls + .then(|| is_precompile_call(data, &to, inputs.transfer.value)); + self.start_trace_on_call( data.journaled_state.depth() as usize, to, @@ -325,6 +334,7 @@ where inputs.transfer.value, inputs.context.scheme.into(), from, + maybe_precompile, ); (InstructionResult::Continue, Gas::new(0), Bytes::new()) @@ -367,6 +377,7 @@ where inputs.value, inputs.scheme.into(), inputs.caller, + Some(false), ); (InstructionResult::Continue, None, Gas::new(inputs.gas_limit), Bytes::default()) @@ -421,3 +432,12 @@ struct StackStep { trace_idx: usize, step_idx: usize, } + +/// Returns true if this a call to a precompile contract with `depth > 0 && value == 0`. +#[inline] +fn is_precompile_call(data: &EVMData<'_, DB>, to: &Address, value: U256) -> bool { + if data.precompiles.contains(to) { + return data.journaled_state.depth() > 0 && value == U256::ZERO + } + false +} diff --git a/crates/revm/revm-inspectors/src/tracing/types.rs b/crates/revm/revm-inspectors/src/tracing/types.rs index e651eefac..458d85dc6 100644 --- a/crates/revm/revm-inspectors/src/tracing/types.rs +++ b/crates/revm/revm-inspectors/src/tracing/types.rs @@ -121,6 +121,10 @@ pub(crate) struct CallTrace { /// In other words, this is the callee if the [CallKind::Call] or the address of the created /// contract if [CallKind::Create]. pub(crate) address: Address, + /// Whether this is a call to a precompile + /// + /// Note: This is an Option because not all tracers make use of this + pub(crate) maybe_precompile: Option, /// Holds the target for the selfdestruct refund target if `status` is /// [InstructionResult::SelfDestruct] pub(crate) selfdestruct_refund_target: Option
, @@ -168,6 +172,7 @@ impl Default for CallTrace { kind: Default::default(), value: Default::default(), data: Default::default(), + maybe_precompile: None, output: Default::default(), last_call_return_value: None, gas_used: Default::default(), @@ -233,6 +238,11 @@ impl CallTraceNode { stack } + /// Returns true if this is a call to a precompile + pub(crate) fn is_precompile(&self) -> bool { + self.trace.maybe_precompile.unwrap_or(false) + } + /// Returns the kind of call the trace belongs to pub(crate) fn kind(&self) -> CallKind { self.trace.kind