revm_inspector/
inspector.rs

1use auto_impl::auto_impl;
2use context::{Database, Journal, JournalEntry};
3use interpreter::{
4    interpreter::EthInterpreter, CallInputs, CallOutcome, CreateInputs, CreateOutcome,
5    EOFCreateInputs, Interpreter, InterpreterTypes,
6};
7use primitives::{Address, Log, U256};
8use state::EvmState;
9
10/// EVM hooks into execution.
11///
12/// This trait is used to enabled tracing of the EVM execution.
13///
14/// Object that is implemented this trait is used in `InspectorHandler` to trace the EVM execution.
15/// And API that allow calling the inspector can be found in [`crate::InspectEvm`] and [`crate::InspectCommitEvm`].
16#[auto_impl(&mut, Box)]
17pub trait Inspector<CTX, INTR: InterpreterTypes = EthInterpreter> {
18    /// Called before the interpreter is initialized.
19    ///
20    /// If `interp.instruction_result` is set to anything other than [`interpreter::InstructionResult::Continue`]
21    /// then the execution of the interpreter is skipped.
22    #[inline]
23    fn initialize_interp(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
24        let _ = interp;
25        let _ = context;
26    }
27
28    /// Called on each step of the interpreter.
29    ///
30    /// Information about the current execution, including the memory, stack and more is available
31    /// on `interp` (see [Interpreter]).
32    ///
33    /// # Example
34    ///
35    /// To get the current opcode, use `interp.current_opcode()`.
36    #[inline]
37    fn step(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
38        let _ = interp;
39        let _ = context;
40    }
41
42    /// Called after `step` when the instruction has been executed.
43    ///
44    /// Setting `interp.instruction_result` to anything other than [`interpreter::InstructionResult::Continue`]
45    /// alters the execution of the interpreter.
46    #[inline]
47    fn step_end(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
48        let _ = interp;
49        let _ = context;
50    }
51
52    /// Called when a log is emitted.
53    #[inline]
54    fn log(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX, log: Log) {
55        let _ = interp;
56        let _ = context;
57        let _ = log;
58    }
59
60    /// Called whenever a call to a contract is about to start.
61    ///
62    /// InstructionResulting anything other than [`interpreter::InstructionResult::Continue`] overrides the result of the call.
63    #[inline]
64    fn call(&mut self, context: &mut CTX, inputs: &mut CallInputs) -> Option<CallOutcome> {
65        let _ = context;
66        let _ = inputs;
67        None
68    }
69
70    /// Called when a call to a contract has concluded.
71    ///
72    /// The returned [CallOutcome] is used as the result of the call.
73    ///
74    /// This allows the inspector to modify the given `result` before returning it.
75    #[inline]
76    fn call_end(&mut self, context: &mut CTX, inputs: &CallInputs, outcome: &mut CallOutcome) {
77        let _ = context;
78        let _ = inputs;
79        let _ = outcome;
80    }
81
82    /// Called when a contract is about to be created.
83    ///
84    /// If this returns `Some` then the [CreateOutcome] is used to override the result of the creation.
85    ///
86    /// If this returns `None` then the creation proceeds as normal.
87    #[inline]
88    fn create(&mut self, context: &mut CTX, inputs: &mut CreateInputs) -> Option<CreateOutcome> {
89        let _ = context;
90        let _ = inputs;
91        None
92    }
93
94    /// Called when a contract has been created.
95    ///
96    /// InstructionResulting anything other than the values passed to this function (`(ret, remaining_gas,
97    /// address, out)`) will alter the result of the create.
98    #[inline]
99    fn create_end(
100        &mut self,
101        context: &mut CTX,
102        inputs: &CreateInputs,
103        outcome: &mut CreateOutcome,
104    ) {
105        let _ = context;
106        let _ = inputs;
107        let _ = outcome;
108    }
109
110    /// Called when EOF creating is called.
111    ///
112    /// This can happen from create TX or from EOFCREATE opcode.
113    fn eofcreate(
114        &mut self,
115        context: &mut CTX,
116        inputs: &mut EOFCreateInputs,
117    ) -> Option<CreateOutcome> {
118        let _ = context;
119        let _ = inputs;
120        None
121    }
122
123    /// Called when eof creating has ended.
124    fn eofcreate_end(
125        &mut self,
126        context: &mut CTX,
127        inputs: &EOFCreateInputs,
128        outcome: &mut CreateOutcome,
129    ) {
130        let _ = context;
131        let _ = inputs;
132        let _ = outcome;
133    }
134
135    /// Called when a contract has been self-destructed with funds transferred to target.
136    #[inline]
137    fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) {
138        let _ = contract;
139        let _ = target;
140        let _ = value;
141    }
142}
143
144/// Extends the journal with additional methods that are used by the inspector.
145#[auto_impl(&mut, Box)]
146pub trait JournalExt {
147    /// Get all logs from the journal.
148    fn logs(&self) -> &[Log];
149
150    /// Get the journal entries that are created from last checkpoint.
151    /// new checkpoint is created when sub call is made.
152    fn last_journal(&self) -> &[JournalEntry];
153
154    /// Return the current Journaled state.
155    fn evm_state(&self) -> &EvmState;
156
157    /// Return the mutable current Journaled state.
158    fn evm_state_mut(&mut self) -> &mut EvmState;
159}
160
161impl<DB: Database> JournalExt for Journal<DB> {
162    #[inline]
163    fn logs(&self) -> &[Log] {
164        &self.logs
165    }
166
167    #[inline]
168    fn last_journal(&self) -> &[JournalEntry] {
169        self.journal.last().expect("Journal is never empty")
170    }
171
172    #[inline]
173    fn evm_state(&self) -> &EvmState {
174        &self.state
175    }
176
177    #[inline]
178    fn evm_state_mut(&mut self) -> &mut EvmState {
179        &mut self.state
180    }
181}