Skip to main content

yevm_core/
trace.rs

1use serde::{Deserialize, Serialize};
2use yevm_base::{Acc, Int};
3use yevm_misc::buf::Buf;
4
5use crate::{
6    Call,
7    evm::{CallMode, HaltReason},
8};
9
10pub mod filter {
11    pub const NONE: u32 = 0;
12    pub const STEP: u32 = 1 << 0;
13    pub const CALL: u32 = 1 << 1;
14    pub const RETURN: u32 = 1 << 2;
15    pub const REVERT: u32 = 1 << 3;
16    pub const HALT: u32 = 1 << 4;
17    pub const GET: u32 = 1 << 5;
18    pub const PUT: u32 = 1 << 6;
19    pub const LOG: u32 = 1 << 7;
20    pub const CREATE: u32 = 1 << 8;
21    pub const DELETE: u32 = 1 << 9;
22    pub const MOVE: u32 = 1 << 10;
23    pub const FEE: u32 = 1 << 11;
24    pub const HASH: u32 = 1 << 12;
25    pub const CODE: u32 = 1 << 13;
26    pub const ALL: u32 = u32::MAX;
27    pub const TOP: u32 = ALL ^ STEP;
28}
29
30#[derive(Clone, Debug, Deserialize, Serialize)]
31pub enum Target {
32    Nonce { acc: Acc, val: Int },
33    Value { acc: Acc, val: Int },
34    Store { acc: Acc, key: Int, val: Int },
35    Temp { acc: Acc, key: Int, val: Int },
36    Code { acc: Acc, hash: Int },
37    Auth { acc: Acc },
38}
39
40#[derive(Clone, Debug, Deserialize, Serialize)]
41pub enum Event {
42    WarmKey(Acc, Int),
43    WarmAcc(Acc),
44    Move(Acc, Acc, Int),
45    Get(Target),
46    Put(Target, Int),
47    Hash(Buf, Int),
48    Code(Buf, Int),
49    Log(Vec<Int>, Buf),
50    Call(Call, CallMode),
51    Return(Buf, u64),      // (data, gas_used)
52    Revert(Buf, u64),      // (data, gas_used)
53    Halt(HaltReason, u64), // (reason, gas_used)
54    Undo(usize, usize),    // seq range [from, to) that was reverted
55    Create(Acc),
56    Delete(Acc),
57    Fee(Acc, Acc, Int, Int, u64), // (sender, coinbase, base_burn, tip, gas_used)
58    Blob(u64, Int),               // EIP-4844 BLOB carrying txs
59
60    Step(Step),
61    // Full(Step, Vec<Int>, Buf),
62}
63
64#[derive(Clone, Debug, Deserialize, Serialize)]
65pub struct Step {
66    pub pc: usize,
67    pub op: u8,
68    pub name: String,
69    #[serde(default)]
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub data: Option<Buf>,
72    pub gas: u64,
73    pub stack: usize,
74    pub memory: usize,
75    pub debug: Vec<String>,
76}
77
78impl Event {
79    pub fn filter_bit(&self) -> u32 {
80        match self {
81            Event::Step(_) => filter::STEP,
82            Event::Call(..) => filter::CALL,
83            Event::Return(..) => filter::RETURN,
84            Event::Revert(..) => filter::REVERT,
85            Event::Undo(..) => filter::REVERT,
86            Event::Halt(..) => filter::HALT,
87            Event::Get(_) => filter::GET,
88            Event::Put(..) => filter::PUT,
89            Event::Log(..) => filter::LOG,
90            Event::Create(_) => filter::CREATE,
91            Event::Delete(_) => filter::DELETE,
92            Event::Move(..) => filter::MOVE,
93            Event::Fee(..) => filter::FEE,
94            Event::Hash(..) => filter::HASH,
95            Event::Code(..) => filter::CODE,
96            _ => filter::NONE,
97        }
98    }
99}
100
101impl PartialEq for Step {
102    fn eq(&self, other: &Self) -> bool {
103        self.pc == other.pc
104            && self.op == other.op
105            && self.name == other.name
106            && self.data == other.data
107            && self.gas == other.gas
108            // revm leaves/pops stack values on halt depending on opcode
109            // && self.stack == other.stack
110            && self.memory == other.memory
111    }
112}
113
114#[derive(Clone, Debug, Deserialize, Serialize)]
115pub struct Trace {
116    pub seq: usize,
117    pub event: Event,
118    pub depth: usize,
119    pub reverted: bool,
120}