evm_tracing_events/lib.rs
1// Copyright 2019-2025 PureStake Inc.
2// This file is part of Moonbeam.
3
4// Moonbeam is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Moonbeam is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.
16
17//! A Proxy in this context is an environmental trait implementor meant to be used for capturing
18//! EVM trace events sent to a Host function from the Runtime. Works like:
19//! - Runtime Api call `using` environmental.
20//! - Runtime calls a Host function with some scale-encoded Evm event.
21//! - Host function emits an additional event to this Listener.
22//! - Proxy listens for the event and format the actual trace response.
23//!
24//! There are two proxy types: `Raw` and `CallList`.
25//! - `Raw` - used for opcode-level traces.
26//! - `CallList` - used for block tracing (stack of call stacks) and custom tracing outputs.
27//!
28//! The EVM event types may contain references and not implement Encode/Decode.
29//! This module provide mirror types and conversion into them from the original events.
30
31#![cfg_attr(not(feature = "std"), no_std)]
32extern crate alloc;
33
34pub mod evm;
35pub mod gasometer;
36pub mod runtime;
37
38pub use self::evm::EvmEvent;
39pub use gasometer::GasometerEvent;
40pub use runtime::RuntimeEvent;
41
42use ethereum_types::{H160, U256};
43use parity_scale_codec::{Decode, Encode};
44
45environmental::environmental!(listener: dyn Listener + 'static);
46
47pub fn using<R, F: FnOnce() -> R>(l: &mut (dyn Listener + 'static), f: F) -> R {
48 listener::using(l, f)
49}
50
51/// Allow to configure which data of the Step event
52/// we want to keep or discard. Not discarding the data requires cloning the data
53/// in the runtime which have a significant cost for each step.
54#[derive(Clone, Copy, Eq, PartialEq, Debug, Encode, Decode, Default)]
55pub struct StepEventFilter {
56 pub enable_stack: bool,
57 pub enable_memory: bool,
58}
59
60#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode)]
61pub enum Event {
62 Evm(evm::EvmEvent),
63 Gasometer(gasometer::GasometerEvent),
64 Runtime(runtime::RuntimeEvent),
65 CallListNew(),
66}
67
68impl Event {
69 /// Access the global reference and call it's `event` method, passing the `Event` itself as
70 /// argument.
71 ///
72 /// This only works if we are `using` a global reference to a `Listener` implementor.
73 pub fn emit(self) {
74 listener::with(|listener| listener.event(self));
75 }
76}
77
78/// Main trait to proxy emitted messages.
79/// Used 2 times :
80/// - Inside the runtime to proxy the events through the host functions
81/// - Inside the client to forward those events to the client listener.
82pub trait Listener {
83 fn event(&mut self, event: Event);
84
85 /// Allow the runtime to know which data should be discarded and not cloned.
86 /// WARNING: It is only called once when the runtime tracing is instantiated to avoid
87 /// performing many ext calls.
88 fn step_event_filter(&self) -> StepEventFilter;
89}
90
91pub fn step_event_filter() -> Option<StepEventFilter> {
92 let mut filter = None;
93 listener::with(|listener| filter = Some(listener.step_event_filter()));
94 filter
95}
96
97#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)]
98pub struct Context {
99 /// Execution address.
100 pub address: H160,
101 /// Caller of the EVM.
102 pub caller: H160,
103 /// Apparent value of the EVM.
104 pub apparent_value: U256,
105}
106
107impl From<evm_runtime::Context> for Context {
108 fn from(i: evm_runtime::Context) -> Self {
109 Self {
110 address: i.address,
111 caller: i.caller,
112 apparent_value: i.apparent_value,
113 }
114 }
115}