revm_inspector/
inspect.rs

1use context::result::ExecResultAndState;
2use handler::{system_call::SYSTEM_ADDRESS, ExecuteCommitEvm, ExecuteEvm, SystemCallEvm};
3use primitives::{Address, Bytes};
4
5/// InspectEvm is a API that allows inspecting the EVM.
6///
7/// It extends the `ExecuteEvm` trait and enabled setting inspector
8///
9pub trait InspectEvm: ExecuteEvm {
10    /// The inspector type used for inspecting EVM execution.
11    type Inspector;
12
13    /// Set the inspector for the EVM.
14    ///
15    /// this function is used to change inspector during execution.
16    /// This function can't change Inspector type, changing inspector type can be done in
17    /// `Evm` with `with_inspector` function.
18    fn set_inspector(&mut self, inspector: Self::Inspector);
19
20    /// Inspect the EVM with the given transaction.
21    fn inspect_one_tx(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error>;
22
23    /// Inspect the EVM and finalize the state.
24    fn inspect_tx(
25        &mut self,
26        tx: Self::Tx,
27    ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
28        let output = self.inspect_one_tx(tx)?;
29        let state = self.finalize();
30        Ok(ExecResultAndState::new(output, state))
31    }
32
33    /// Inspect the EVM with the given inspector and transaction, and finalize the state.
34    fn inspect(
35        &mut self,
36        tx: Self::Tx,
37        inspector: Self::Inspector,
38    ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
39        let output = self.inspect_one(tx, inspector)?;
40        let state = self.finalize();
41        Ok(ExecResultAndState::new(output, state))
42    }
43
44    /// Inspect the EVM with the given inspector and transaction.
45    fn inspect_one(
46        &mut self,
47        tx: Self::Tx,
48        inspector: Self::Inspector,
49    ) -> Result<Self::ExecutionResult, Self::Error> {
50        self.set_inspector(inspector);
51        self.inspect_one_tx(tx)
52    }
53}
54
55/// InspectCommitEvm is a API that allows inspecting similar to `InspectEvm` but it has
56/// functions that commit the state diff to the database.
57///
58/// Functions return CommitOutput from [`ExecuteCommitEvm`] trait.
59pub trait InspectCommitEvm: InspectEvm + ExecuteCommitEvm {
60    /// Inspect the EVM with the current inspector and previous transaction by replaying, similar to [`InspectEvm::inspect_tx`]
61    /// and commit the state diff to the database.
62    fn inspect_tx_commit(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
63        let output = self.inspect_one_tx(tx)?;
64        self.commit_inner();
65        Ok(output)
66    }
67
68    /// Inspect the EVM with the given transaction and inspector similar to [`InspectEvm::inspect`]
69    /// and commit the state diff to the database.
70    fn inspect_commit(
71        &mut self,
72        tx: Self::Tx,
73        inspector: Self::Inspector,
74    ) -> Result<Self::ExecutionResult, Self::Error> {
75        let output = self.inspect_one(tx, inspector)?;
76        self.commit_inner();
77        Ok(output)
78    }
79}
80
81/// InspectSystemCallEvm is an API that allows inspecting system calls in the EVM.
82///
83/// It extends [`InspectEvm`] and [`SystemCallEvm`] traits to provide inspection
84/// capabilities for system transactions, enabling tracing and debugging of
85/// system calls similar to regular transactions.
86pub trait InspectSystemCallEvm: InspectEvm + SystemCallEvm {
87    /// Inspect a system call with the current inspector.
88    ///
89    /// Similar to [`InspectEvm::inspect_one_tx`] but for system calls.
90    /// Uses [`SYSTEM_ADDRESS`] as the caller.
91    fn inspect_one_system_call(
92        &mut self,
93        system_contract_address: Address,
94        data: Bytes,
95    ) -> Result<Self::ExecutionResult, Self::Error> {
96        self.inspect_one_system_call_with_caller(SYSTEM_ADDRESS, system_contract_address, data)
97    }
98
99    /// Inspect a system call with the current inspector and a custom caller.
100    ///
101    /// Similar to [`InspectEvm::inspect_one_tx`] but for system calls with a custom caller.
102    fn inspect_one_system_call_with_caller(
103        &mut self,
104        caller: Address,
105        system_contract_address: Address,
106        data: Bytes,
107    ) -> Result<Self::ExecutionResult, Self::Error>;
108
109    /// Inspect a system call and finalize the state.
110    ///
111    /// Similar to [`InspectEvm::inspect_tx`] but for system calls.
112    fn inspect_system_call(
113        &mut self,
114        system_contract_address: Address,
115        data: Bytes,
116    ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
117        let output = self.inspect_one_system_call(system_contract_address, data)?;
118        let state = self.finalize();
119        Ok(ExecResultAndState::new(output, state))
120    }
121
122    /// Inspect a system call with a custom caller and finalize the state.
123    ///
124    /// Similar to [`InspectEvm::inspect_tx`] but for system calls with a custom caller.
125    fn inspect_system_call_with_caller(
126        &mut self,
127        caller: Address,
128        system_contract_address: Address,
129        data: Bytes,
130    ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
131        let output =
132            self.inspect_one_system_call_with_caller(caller, system_contract_address, data)?;
133        let state = self.finalize();
134        Ok(ExecResultAndState::new(output, state))
135    }
136
137    /// Inspect a system call with a given inspector.
138    ///
139    /// Similar to [`InspectEvm::inspect_one`] but for system calls.
140    fn inspect_one_system_call_with_inspector(
141        &mut self,
142        system_contract_address: Address,
143        data: Bytes,
144        inspector: Self::Inspector,
145    ) -> Result<Self::ExecutionResult, Self::Error> {
146        self.set_inspector(inspector);
147        self.inspect_one_system_call(system_contract_address, data)
148    }
149
150    /// Inspect a system call with a given inspector and finalize the state.
151    ///
152    /// Similar to [`InspectEvm::inspect`] but for system calls.
153    fn inspect_system_call_with_inspector(
154        &mut self,
155        system_contract_address: Address,
156        data: Bytes,
157        inspector: Self::Inspector,
158    ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
159        let output =
160            self.inspect_one_system_call_with_inspector(system_contract_address, data, inspector)?;
161        let state = self.finalize();
162        Ok(ExecResultAndState::new(output, state))
163    }
164
165    /// Inspect a system call with a given inspector and caller.
166    ///
167    /// Similar to [`InspectEvm::inspect_one`] but for system calls.
168    fn inspect_one_system_call_with_inspector_and_caller(
169        &mut self,
170        caller: Address,
171        system_contract_address: Address,
172        data: Bytes,
173        inspector: Self::Inspector,
174    ) -> Result<Self::ExecutionResult, Self::Error> {
175        self.set_inspector(inspector);
176        self.inspect_one_system_call_with_caller(caller, system_contract_address, data)
177    }
178
179    /// Inspect a system call with a given inspector and finalize the state.
180    ///
181    /// Similar to [`InspectEvm::inspect`] but for system calls.
182    fn inspect_system_call_with_inspector_and_caller(
183        &mut self,
184        caller: Address,
185        system_contract_address: Address,
186        data: Bytes,
187        inspector: Self::Inspector,
188    ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
189        let output = self.inspect_one_system_call_with_inspector_and_caller(
190            caller,
191            system_contract_address,
192            data,
193            inspector,
194        )?;
195        let state = self.finalize();
196        Ok(ExecResultAndState::new(output, state))
197    }
198}