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}