mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: populate gas cost for vm instructions (#4046)
This commit is contained in:
@ -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<CallTraceNode>,
|
||||
/// The spec id of the EVM.
|
||||
spec_id: Option<SpecId>,
|
||||
|
||||
/// 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<CallTraceNode>, _config: TracingInspectorConfig) -> Self {
|
||||
Self { nodes, _config }
|
||||
pub(crate) fn new(
|
||||
nodes: Vec<CallTraceNode>,
|
||||
spec_id: Option<SpecId>,
|
||||
_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<VmTrace>) -> VmInstruction {
|
||||
fn make_instruction(&self, step: &CallTraceStep, maybe_sub: Option<VmTrace>) -> 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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<Bytes>,
|
||||
/// 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<SpecId>,
|
||||
}
|
||||
|
||||
// === 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(
|
||||
|
||||
Reference in New Issue
Block a user