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)]
32
extern crate alloc;
33

            
34
pub mod evm;
35
pub mod gasometer;
36
pub mod runtime;
37

            
38
pub use self::evm::EvmEvent;
39
pub use gasometer::GasometerEvent;
40
pub use runtime::RuntimeEvent;
41

            
42
use ethereum_types::{H160, U256};
43
use parity_scale_codec::{Decode, Encode};
44
use sp_runtime_interface::pass_by::PassByCodec;
45

            
46
environmental::environmental!(listener: dyn Listener + 'static);
47

            
48
pub fn using<R, F: FnOnce() -> R>(l: &mut (dyn Listener + 'static), f: F) -> R {
49
	listener::using(l, f)
50
}
51

            
52
/// Allow to configure which data of the Step event
53
/// we want to keep or discard. Not discarding the data requires cloning the data
54
/// in the runtime which have a significant cost for each step.
55
#[derive(Clone, Copy, Eq, PartialEq, Debug, Encode, Decode, Default, PassByCodec)]
56
pub struct StepEventFilter {
57
	pub enable_stack: bool,
58
	pub enable_memory: bool,
59
}
60

            
61
#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode)]
62
pub enum Event {
63
	Evm(evm::EvmEvent),
64
	Gasometer(gasometer::GasometerEvent),
65
	Runtime(runtime::RuntimeEvent),
66
	CallListNew(),
67
}
68

            
69
impl Event {
70
	/// Access the global reference and call it's `event` method, passing the `Event` itself as
71
	/// argument.
72
	///
73
	/// This only works if we are `using` a global reference to a `Listener` implementor.
74
315
	pub fn emit(self) {
75
315
		listener::with(|listener| listener.event(self));
76
315
	}
77
}
78

            
79
/// Main trait to proxy emitted messages.
80
/// Used 2 times :
81
/// - Inside the runtime to proxy the events through the host functions
82
/// - Inside the client to forward those events to the client listener.
83
pub trait Listener {
84
	fn event(&mut self, event: Event);
85

            
86
	/// Allow the runtime to know which data should be discarded and not cloned.
87
	/// WARNING: It is only called once when the runtime tracing is instantiated to avoid
88
	/// performing many ext calls.
89
	fn step_event_filter(&self) -> StepEventFilter;
90
}
91

            
92
252
pub fn step_event_filter() -> Option<StepEventFilter> {
93
252
	let mut filter = None;
94
252
	listener::with(|listener| filter = Some(listener.step_event_filter()));
95
252
	filter
96
252
}
97

            
98
#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)]
99
pub struct Context {
100
	/// Execution address.
101
	pub address: H160,
102
	/// Caller of the EVM.
103
	pub caller: H160,
104
	/// Apparent value of the EVM.
105
	pub apparent_value: U256,
106
}
107

            
108
impl From<evm_runtime::Context> for Context {
109
	fn from(i: evm_runtime::Context) -> Self {
110
		Self {
111
			address: i.address,
112
			caller: i.caller,
113
			apparent_value: i.apparent_value,
114
		}
115
	}
116
}