fix: add missing StructLog fields (#1847)

This commit is contained in:
Matthias Seitz
2023-03-19 20:17:28 +01:00
committed by GitHub
parent 0936523e3d
commit a59806f43b
4 changed files with 44 additions and 8 deletions

View File

@@ -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);

View File

@@ -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
@@ -58,6 +62,7 @@ impl TracingInspector {
traces: Default::default(),
trace_stack: vec![],
step_stack: vec![],
last_call_return_data: None,
gas_inspector: Default::default(),
}
}
@@ -130,6 +135,7 @@ impl TracingInspector {
value,
status: InstructionResult::Continue,
caller,
last_call_return_value: self.last_call_return_data.clone(),
..Default::default()
},
));
@@ -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
@@ -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,

View File

@@ -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
@@ -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(),
@@ -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
@@ -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,
}
}
}

View File

@@ -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