Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/revm/revm-inspectors/src/tracing/builder/geth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,15 @@ impl GethTraceBuilder {
if opts.disable_stack.unwrap_or_default() {
log.stack = None;
}

if !opts.enable_memory.unwrap_or_default() {
log.memory = None;
}

if opts.enable_return_data.unwrap_or_default() {
log.return_data = trace_node.trace.last_call_return_value.clone().map(Into::into);
}

// Add step to geth trace
struct_logs.push(log);

Expand Down
10 changes: 9 additions & 1 deletion crates/revm/revm-inspectors/src/tracing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ pub struct TracingInspector {
config: TracingInspectorConfig,
/// Records all call traces
traces: CallTraceArena,
/// Tracks active calls
trace_stack: Vec<usize>,
/// Tracks active steps
step_stack: Vec<StackStep>,
/// Tracks the return value of the last call
last_call_return_data: Option<Bytes>,
/// The gas inspector used to track remaining gas.
///
/// This is either owned by this inspector directly or part of a stack of inspectors, in which
Expand All @@ -58,6 +62,7 @@ impl TracingInspector {
traces: Default::default(),
trace_stack: vec![],
step_stack: vec![],
last_call_return_data: None,
gas_inspector: Default::default(),
}
}
Expand Down Expand Up @@ -130,6 +135,7 @@ impl TracingInspector {
value,
status: InstructionResult::Continue,
caller,
last_call_return_value: self.last_call_return_data.clone(),
..Default::default()
},
));
Expand All @@ -156,7 +162,8 @@ impl TracingInspector {
trace.status = status;
trace.success = success;
trace.gas_used = gas_used;
trace.output = output;
trace.output = output.clone();
self.last_call_return_data = Some(output);

if let Some(address) = created_address {
// A new contract was created via CREATE
Expand Down Expand Up @@ -193,6 +200,7 @@ impl TracingInspector {
contract: interp.contract.address,
stack,
memory,
memory_size: interp.memory.len(),
gas: self.gas_inspector.as_ref().gas_remaining(),
gas_refund_counter: interp.gas.refunded() as u64,

Expand Down
7 changes: 7 additions & 0 deletions crates/revm/revm-inspectors/src/tracing/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ pub(crate) struct CallTrace {
/// The return data of the call if this was not a contract creation, otherwise it is the
/// runtime bytecode of the created contract
pub(crate) output: Bytes,
/// The return data of the last call, if any
pub(crate) last_call_return_value: Option<Bytes>,
/// The gas cost of the call
pub(crate) gas_used: u64,
/// The status of the trace's call
Expand All @@ -121,6 +123,7 @@ impl Default for CallTrace {
value: Default::default(),
data: Default::default(),
output: Default::default(),
last_call_return_value: None,
gas_used: Default::default(),
status: InstructionResult::Continue,
call_context: Default::default(),
Expand Down Expand Up @@ -239,6 +242,8 @@ pub struct CallTraceStep {
pub stack: Stack,
/// Memory before step execution
pub memory: Memory,
/// Size of memory
pub memory_size: usize,
/// Remaining gas before step execution
pub gas: u64,
/// Gas refund counter before step execution
Expand Down Expand Up @@ -279,7 +284,9 @@ impl From<&CallTraceStep> for StructLog {
refund_counter: (step.gas_refund_counter > 0).then_some(step.gas_refund_counter),
stack: Some(step.stack.data().clone()),
// Filled in `CallTraceArena::geth_trace` as a result of compounding all slot changes
return_data: None,
storage: None,
memory_size: step.memory_size as u64,
}
}
}
30 changes: 23 additions & 7 deletions crates/rpc/rpc-types/src/eth/trace/geth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,39 @@ pub struct DefaultFrame {
/// <https://github.com/ethereum/go-ethereum/blob/366d2169fbc0e0f803b68c042b77b6b480836dbc/eth/tracers/logger/logger.go#L413-L426>
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct StructLog {
pub depth: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
/// program counter
pub pc: u64,
/// opcode to be executed
pub op: String,
/// remaining gas
pub gas: u64,
/// cost for executing op
#[serde(rename = "gasCost")]
pub gas_cost: u64,
/// ref <https://github.com/ethereum/go-ethereum/blob/366d2169fbc0e0f803b68c042b77b6b480836dbc/eth/tracers/logger/logger.go#L450-L452>
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory: Option<Vec<String>>,
pub op: String,
pub pc: u64,
#[serde(default, rename = "refund", skip_serializing_if = "Option::is_none")]
pub refund_counter: Option<u64>,
/// Size of memory.
#[serde(rename = "memSize")]
pub memory_size: u64,
/// EVM stack
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stack: Option<Vec<U256>>,
/// Last call's return data. Enabled via enableReturnData
#[serde(default, rename = "refund", skip_serializing_if = "Option::is_none")]
pub return_data: Option<Bytes>,
/// Storage slots of current contract read from and written to. Only emitted for SLOAD and
/// SSTORE. Disabled via disableStorage
#[serde(default, skip_serializing_if = "Option::is_none")]
pub storage: Option<BTreeMap<H256, H256>>,
/// Current call depth
pub depth: u64,
/// Refund counter
#[serde(default, rename = "refund", skip_serializing_if = "Option::is_none")]
pub refund_counter: Option<u64>,
/// Error message if any
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}

/// Tracing response
Expand Down