diff --git a/crates/revm/revm-inspectors/src/tracing/builder/parity.rs b/crates/revm/revm-inspectors/src/tracing/builder/parity.rs index f1eb1b6060..cf2a50dec2 100644 --- a/crates/revm/revm-inspectors/src/tracing/builder/parity.rs +++ b/crates/revm/revm-inspectors/src/tracing/builder/parity.rs @@ -7,7 +7,8 @@ use reth_primitives::{Address, U64}; use reth_rpc_types::{trace::parity::*, TransactionInfo}; use revm::{ db::DatabaseRef, - primitives::{AccountInfo, ExecutionResult, ResultAndState, KECCAK_EMPTY}, + interpreter::opcode::spec_opcode_gas, + primitives::{AccountInfo, ExecutionResult, ResultAndState, SpecId, KECCAK_EMPTY}, }; use std::collections::{HashSet, VecDeque}; @@ -18,6 +19,8 @@ use std::collections::{HashSet, VecDeque}; pub struct ParityTraceBuilder { /// Recorded trace nodes nodes: Vec, + /// The spec id of the EVM. + spec_id: Option, /// How the traces were recorded _config: TracingInspectorConfig, @@ -25,8 +28,12 @@ pub struct ParityTraceBuilder { impl ParityTraceBuilder { /// Returns a new instance of the builder - pub(crate) fn new(nodes: Vec, _config: TracingInspectorConfig) -> Self { - Self { nodes, _config } + pub(crate) fn new( + nodes: Vec, + spec_id: Option, + _config: TracingInspectorConfig, + ) -> Self { + Self { nodes, spec_id, _config } } /// Returns a list of all addresses that appeared as callers. @@ -306,7 +313,7 @@ impl ParityTraceBuilder { None }; - instructions.push(Self::make_instruction(step, maybe_sub)); + instructions.push(self.make_instruction(step, maybe_sub)); } match current.parent { @@ -331,7 +338,7 @@ impl ParityTraceBuilder { /// Creates a VM instruction from a [CallTraceStep] and a [VmTrace] for the subcall if there is /// one - fn make_instruction(step: &CallTraceStep, maybe_sub: Option) -> VmInstruction { + fn make_instruction(&self, step: &CallTraceStep, maybe_sub: Option) -> VmInstruction { let maybe_storage = step.storage_change.map(|storage_change| StorageDelta { key: storage_change.key, val: storage_change.value, @@ -351,12 +358,14 @@ impl ParityTraceBuilder { store: maybe_storage, }); - VmInstruction { - pc: step.pc, - cost: 0, // TODO: use op gas cost - ex: maybe_execution, - sub: maybe_sub, - } + let cost = self + .spec_id + .and_then(|spec_id| { + spec_opcode_gas(spec_id).get(step.op.u8() as usize).map(|op| op.get_gas()) + }) + .unwrap_or_default(); + + VmInstruction { pc: step.pc, cost: cost as u64, ex: maybe_execution, sub: maybe_sub } } } diff --git a/crates/revm/revm-inspectors/src/tracing/mod.rs b/crates/revm/revm-inspectors/src/tracing/mod.rs index de8a3b3b24..be6af4b53e 100644 --- a/crates/revm/revm-inspectors/src/tracing/mod.rs +++ b/crates/revm/revm-inspectors/src/tracing/mod.rs @@ -10,6 +10,7 @@ use revm::{ opcode, return_ok, CallInputs, CallScheme, CreateInputs, Gas, InstructionResult, Interpreter, OpCode, }, + primitives::SpecId, Database, EVMData, Inspector, JournalEntry, }; use types::{CallTrace, CallTraceStep}; @@ -59,6 +60,10 @@ pub struct TracingInspector { last_call_return_data: Option, /// The gas inspector used to track remaining gas. gas_inspector: GasInspector, + /// The spec id of the EVM. + /// + /// This is filled during execution. + spec_id: Option, } // === impl TracingInspector === @@ -73,12 +78,13 @@ impl TracingInspector { step_stack: vec![], last_call_return_data: None, gas_inspector: Default::default(), + spec_id: None, } } /// Consumes the Inspector and returns a [ParityTraceBuilder]. pub fn into_parity_builder(self) -> ParityTraceBuilder { - ParityTraceBuilder::new(self.traces.arena, self.config) + ParityTraceBuilder::new(self.traces.arena, self.spec_id, self.config) } /// Consumes the Inspector and returns a [GethTraceBuilder]. @@ -170,6 +176,10 @@ impl TracingInspector { // this is the root call which should get the original gas limit of the transaction, // because initialization costs are already subtracted from gas_limit gas_limit = data.env.tx.gas_limit; + + // we set the spec id here because we only need to do this once and this condition is + // hit exactly once + self.spec_id = Some(data.env.cfg.spec_id); } self.trace_stack.push(self.traces.push_trace(