revm_inspectors/tracing/
arena.rs1use super::types::{CallTrace, CallTraceNode, TraceMemberOrder};
2use alloc::vec::Vec;
3use alloy_primitives::Address;
4
5#[derive(Clone, Debug, PartialEq, Eq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct CallTraceArena {
11 pub(crate) arena: Vec<CallTraceNode>,
13}
14
15impl Default for CallTraceArena {
16 fn default() -> Self {
17 let mut this = Self { arena: Vec::with_capacity(8) };
18 this.clear();
19 this
20 }
21}
22
23impl CallTraceArena {
24 #[inline]
26 pub fn nodes(&self) -> &[CallTraceNode] {
27 &self.arena
28 }
29
30 #[inline]
32 pub fn nodes_mut(&mut self) -> &mut Vec<CallTraceNode> {
33 &mut self.arena
34 }
35
36 #[inline]
38 pub fn into_nodes(self) -> Vec<CallTraceNode> {
39 self.arena
40 }
41
42 pub fn clear(&mut self) {
46 self.arena.clear();
47 self.arena.push(Default::default());
48 }
49
50 pub fn trace_addresses(&self) -> impl Iterator<Item = Address> + '_ {
53 self.nodes().iter().flat_map(|node| [node.trace.address, node.trace.caller].into_iter())
54 }
55
56 pub(crate) fn push_trace(
62 &mut self,
63 mut entry: usize,
64 kind: PushTraceKind,
65 new_trace: CallTrace,
66 ) -> usize {
67 if new_trace.depth == 0 {
69 self.arena[0].trace = new_trace;
70 return 0;
71 }
72
73 while self.arena[entry].trace.depth != new_trace.depth - 1 {
75 entry = *self.arena[entry].children.last().expect("Disconnected trace");
76 }
77
78 let idx = self.arena.len();
79 self.arena.push(CallTraceNode {
80 parent: Some(entry),
81 trace: new_trace,
82 idx,
83 ..Default::default()
84 });
85
86 if kind.is_attach_to_parent() {
88 let parent = &mut self.arena[entry];
89 let trace_location = parent.children.len();
90 parent.ordering.push(TraceMemberOrder::Call(trace_location));
91 parent.children.push(idx);
92 }
93
94 idx
95 }
96}
97
98#[derive(Clone, Copy, Debug, PartialEq, Eq)]
100pub(crate) enum PushTraceKind {
101 PushOnly,
103 PushAndAttachToParent,
106}
107
108impl PushTraceKind {
109 #[inline]
110 const fn is_attach_to_parent(&self) -> bool {
111 matches!(self, Self::PushAndAttachToParent)
112 }
113}