mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix: exclude calls to precompiles in parity tracers (#2987)
This commit is contained in:
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -5538,8 +5538,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "revm"
|
name = "revm"
|
||||||
version = "3.3.0"
|
version = "3.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/bluealloy/revm/?branch=release/v25#88337924f4d16ed1f5e4cde12a03d0cb755cd658"
|
||||||
checksum = "f293f351c4c203d321744e54ed7eed3d2b6eef4c140228910dde3ac9a5ea8031"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"auto_impl",
|
"auto_impl",
|
||||||
"revm-interpreter",
|
"revm-interpreter",
|
||||||
@ -5549,8 +5548,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "revm-interpreter"
|
name = "revm-interpreter"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/bluealloy/revm/?branch=release/v25#88337924f4d16ed1f5e4cde12a03d0cb755cd658"
|
||||||
checksum = "a53980a26f9b5a66d13511c35074d4b53631e157850a1d7cf1af4efc2c2b72c9"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"enumn",
|
"enumn",
|
||||||
@ -5560,9 +5558,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "revm-precompile"
|
name = "revm-precompile"
|
||||||
version = "2.0.2"
|
version = "2.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/bluealloy/revm/?branch=release/v25#88337924f4d16ed1f5e4cde12a03d0cb755cd658"
|
||||||
checksum = "10a3eabf08ea9e4063f5531b8735e29344d9d6eaebaa314c58253f6c17fcdf2d"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"k256 0.13.1",
|
"k256 0.13.1",
|
||||||
"num",
|
"num",
|
||||||
@ -5578,8 +5575,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "revm-primitives"
|
name = "revm-primitives"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/bluealloy/revm/?branch=release/v25#88337924f4d16ed1f5e4cde12a03d0cb755cd658"
|
||||||
checksum = "304d998f466ffef72d76c7f20b05bf08a96801736a6fb1fdef47d49a292618df"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arbitrary",
|
"arbitrary",
|
||||||
"auto_impl",
|
"auto_impl",
|
||||||
|
|||||||
@ -73,6 +73,9 @@ incremental = false
|
|||||||
# patched for quantity U256 responses <https://github.com/recmo/uint/issues/224>
|
# patched for quantity U256 responses <https://github.com/recmo/uint/issues/224>
|
||||||
ruint = { git = "https://github.com/paradigmxyz/uint" }
|
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]
|
[workspace.dependencies]
|
||||||
## eth
|
## eth
|
||||||
revm = { version = "3" }
|
revm = { version = "3" }
|
||||||
|
|||||||
@ -124,6 +124,11 @@ impl ParityTraceBuilder {
|
|||||||
let mut diff = StateDiff::default();
|
let mut diff = StateDiff::default();
|
||||||
|
|
||||||
for (node, trace_address) in self.nodes.iter().zip(trace_addresses) {
|
for (node, trace_address) in self.nodes.iter().zip(trace_addresses) {
|
||||||
|
// skip precompiles
|
||||||
|
if node.is_precompile() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if with_traces {
|
if with_traces {
|
||||||
let trace = node.parity_transaction_trace(trace_address);
|
let trace = node.parity_transaction_trace(trace_address);
|
||||||
traces.push(trace);
|
traces.push(trace);
|
||||||
@ -145,6 +150,7 @@ impl ParityTraceBuilder {
|
|||||||
self.nodes
|
self.nodes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(trace_addresses)
|
.zip(trace_addresses)
|
||||||
|
.filter(|(node, _)| !node.is_precompile())
|
||||||
.map(|(node, trace_address)| node.parity_transaction_trace(trace_address))
|
.map(|(node, trace_address)| node.parity_transaction_trace(trace_address))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,8 @@ pub struct TracingInspectorConfig {
|
|||||||
pub record_stack_snapshots: bool,
|
pub record_stack_snapshots: bool,
|
||||||
/// Whether to record state diffs.
|
/// Whether to record state diffs.
|
||||||
pub record_state_diff: bool,
|
pub record_state_diff: bool,
|
||||||
|
/// Whether to ignore precompile calls.
|
||||||
|
pub exclude_precompile_calls: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TracingInspectorConfig {
|
impl TracingInspectorConfig {
|
||||||
@ -24,6 +26,7 @@ impl TracingInspectorConfig {
|
|||||||
record_memory_snapshots: true,
|
record_memory_snapshots: true,
|
||||||
record_stack_snapshots: true,
|
record_stack_snapshots: true,
|
||||||
record_state_diff: false,
|
record_state_diff: false,
|
||||||
|
exclude_precompile_calls: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,6 +39,7 @@ impl TracingInspectorConfig {
|
|||||||
record_memory_snapshots: false,
|
record_memory_snapshots: false,
|
||||||
record_stack_snapshots: false,
|
record_stack_snapshots: false,
|
||||||
record_state_diff: false,
|
record_state_diff: false,
|
||||||
|
exclude_precompile_calls: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +52,7 @@ impl TracingInspectorConfig {
|
|||||||
record_memory_snapshots: true,
|
record_memory_snapshots: true,
|
||||||
record_stack_snapshots: true,
|
record_stack_snapshots: true,
|
||||||
record_state_diff: 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
|
/// Configure whether individual opcode level steps should be recorded
|
||||||
pub fn set_steps(mut self, record_steps: bool) -> Self {
|
pub fn set_steps(mut self, record_steps: bool) -> Self {
|
||||||
self.record_steps = record_steps;
|
self.record_steps = record_steps;
|
||||||
|
|||||||
@ -101,6 +101,7 @@ impl TracingInspector {
|
|||||||
/// Starts tracking a new trace.
|
/// Starts tracking a new trace.
|
||||||
///
|
///
|
||||||
/// Invoked on [Inspector::call].
|
/// Invoked on [Inspector::call].
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn start_trace_on_call(
|
fn start_trace_on_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
@ -109,6 +110,7 @@ impl TracingInspector {
|
|||||||
value: U256,
|
value: U256,
|
||||||
kind: CallKind,
|
kind: CallKind,
|
||||||
caller: Address,
|
caller: Address,
|
||||||
|
maybe_precompile: Option<bool>,
|
||||||
) {
|
) {
|
||||||
self.trace_stack.push(self.traces.push_trace(
|
self.trace_stack.push(self.traces.push_trace(
|
||||||
0,
|
0,
|
||||||
@ -121,6 +123,7 @@ impl TracingInspector {
|
|||||||
status: InstructionResult::Continue,
|
status: InstructionResult::Continue,
|
||||||
caller,
|
caller,
|
||||||
last_call_return_value: self.last_call_return_data.clone(),
|
last_call_return_value: self.last_call_return_data.clone(),
|
||||||
|
maybe_precompile,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
@ -318,6 +321,12 @@ where
|
|||||||
_ => (inputs.context.caller, inputs.context.address),
|
_ => (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(
|
self.start_trace_on_call(
|
||||||
data.journaled_state.depth() as usize,
|
data.journaled_state.depth() as usize,
|
||||||
to,
|
to,
|
||||||
@ -325,6 +334,7 @@ where
|
|||||||
inputs.transfer.value,
|
inputs.transfer.value,
|
||||||
inputs.context.scheme.into(),
|
inputs.context.scheme.into(),
|
||||||
from,
|
from,
|
||||||
|
maybe_precompile,
|
||||||
);
|
);
|
||||||
|
|
||||||
(InstructionResult::Continue, Gas::new(0), Bytes::new())
|
(InstructionResult::Continue, Gas::new(0), Bytes::new())
|
||||||
@ -367,6 +377,7 @@ where
|
|||||||
inputs.value,
|
inputs.value,
|
||||||
inputs.scheme.into(),
|
inputs.scheme.into(),
|
||||||
inputs.caller,
|
inputs.caller,
|
||||||
|
Some(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
(InstructionResult::Continue, None, Gas::new(inputs.gas_limit), Bytes::default())
|
(InstructionResult::Continue, None, Gas::new(inputs.gas_limit), Bytes::default())
|
||||||
@ -421,3 +432,12 @@ struct StackStep {
|
|||||||
trace_idx: usize,
|
trace_idx: usize,
|
||||||
step_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<DB: Database>(data: &EVMData<'_, DB>, to: &Address, value: U256) -> bool {
|
||||||
|
if data.precompiles.contains(to) {
|
||||||
|
return data.journaled_state.depth() > 0 && value == U256::ZERO
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
/// In other words, this is the callee if the [CallKind::Call] or the address of the created
|
||||||
/// contract if [CallKind::Create].
|
/// contract if [CallKind::Create].
|
||||||
pub(crate) address: Address,
|
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<bool>,
|
||||||
/// Holds the target for the selfdestruct refund target if `status` is
|
/// Holds the target for the selfdestruct refund target if `status` is
|
||||||
/// [InstructionResult::SelfDestruct]
|
/// [InstructionResult::SelfDestruct]
|
||||||
pub(crate) selfdestruct_refund_target: Option<Address>,
|
pub(crate) selfdestruct_refund_target: Option<Address>,
|
||||||
@ -168,6 +172,7 @@ impl Default for CallTrace {
|
|||||||
kind: Default::default(),
|
kind: Default::default(),
|
||||||
value: Default::default(),
|
value: Default::default(),
|
||||||
data: Default::default(),
|
data: Default::default(),
|
||||||
|
maybe_precompile: None,
|
||||||
output: Default::default(),
|
output: Default::default(),
|
||||||
last_call_return_value: None,
|
last_call_return_value: None,
|
||||||
gas_used: Default::default(),
|
gas_used: Default::default(),
|
||||||
@ -233,6 +238,11 @@ impl CallTraceNode {
|
|||||||
stack
|
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
|
/// Returns the kind of call the trace belongs to
|
||||||
pub(crate) fn kind(&self) -> CallKind {
|
pub(crate) fn kind(&self) -> CallKind {
|
||||||
self.trace.kind
|
self.trace.kind
|
||||||
|
|||||||
Reference in New Issue
Block a user