fix: record geth selfdestructs (#4264)

This commit is contained in:
Matthias Seitz
2023-08-18 17:39:06 +02:00
committed by GitHub
parent 466934c8f9
commit 890eacbe54
2 changed files with 28 additions and 1 deletions

View File

@@ -118,7 +118,13 @@ impl GethTraceBuilder {
let include_logs = opts.with_log.unwrap_or_default();
// first fill up the root
let main_trace_node = &self.nodes[0];
let root_call_frame = main_trace_node.geth_empty_call_frame(include_logs);
let mut root_call_frame = main_trace_node.geth_empty_call_frame(include_logs);
// selfdestructs are not recorded as individual call traces but are derived from
// the call trace and are added as additional `CallFrame` objects to the parent call
if let Some(selfdestruct) = main_trace_node.geth_selfdestruct_call_trace() {
root_call_frame.calls.push(selfdestruct);
}
if opts.only_top_call.unwrap_or_default() {
return root_call_frame
@@ -129,7 +135,13 @@ impl GethTraceBuilder {
// so we can populate the call frame tree by walking up the call tree
let mut call_frames = Vec::with_capacity(self.nodes.len());
call_frames.push((0, root_call_frame));
for (idx, trace) in self.nodes.iter().enumerate().skip(1) {
// selfdestructs are not recorded as individual call traces but are derived from
// the call trace and are added as additional `CallFrame` objects to the parent call
if let Some(selfdestruct) = trace.geth_selfdestruct_call_trace() {
call_frames.last_mut().expect("not empty").1.calls.push(selfdestruct);
}
call_frames.push((idx, trace.geth_empty_call_frame(include_logs)));
}

View File

@@ -386,6 +386,21 @@ impl CallTraceNode {
}
}
/// If the trace is a selfdestruct, returns the `CallFrame` for a geth call trace
pub(crate) fn geth_selfdestruct_call_trace(&self) -> Option<CallFrame> {
if self.is_selfdestruct() {
Some(CallFrame {
typ: "SELFDESTRUCT".to_string(),
from: self.trace.caller,
to: self.trace.selfdestruct_refund_target,
value: Some(self.trace.value),
..Default::default()
})
} else {
None
}
}
/// If the trace is a selfdestruct, returns the `TransactionTrace` for a parity trace.
pub(crate) fn parity_selfdestruct_trace(
&self,