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}