@@ -21,23 +21,36 @@ pub trait InspectEvm: ExecuteEvm {
2121 fn inspect_one_tx ( & mut self , tx : Self :: Tx ) -> Result < Self :: ExecutionResult , Self :: Error > ;
2222
2323 /// Inspect the EVM and finalize the state.
24+ ///
25+ /// # Outcome of Error
26+ ///
27+ /// If the transaction fails, the journal is finalized (cleared) so that the
28+ /// next transaction starts from a clean state. This mirrors [`ExecuteEvm::transact`].
2429 fn inspect_tx (
2530 & mut self ,
2631 tx : Self :: Tx ,
2732 ) -> Result < ExecResultAndState < Self :: ExecutionResult , Self :: State > , Self :: Error > {
28- let output = self . inspect_one_tx ( tx) ?;
33+ // finalize the journal unconditionally, even on error, so the
34+ // EIP-2929 warm set and state do not leak into the next transaction.
35+ let output_or_error = self . inspect_one_tx ( tx) ;
2936 let state = self . finalize ( ) ;
37+ let output = output_or_error?;
3038 Ok ( ExecResultAndState :: new ( output, state) )
3139 }
3240
3341 /// Inspect the EVM with the given inspector and transaction, and finalize the state.
42+ ///
43+ /// # Outcome of Error
44+ ///
45+ /// Same as [`InspectEvm::inspect_tx`]: the journal is finalized on error.
3446 fn inspect (
3547 & mut self ,
3648 tx : Self :: Tx ,
3749 inspector : Self :: Inspector ,
3850 ) -> Result < ExecResultAndState < Self :: ExecutionResult , Self :: State > , Self :: Error > {
39- let output = self . inspect_one ( tx, inspector) ? ;
51+ let output_or_error = self . inspect_one ( tx, inspector) ;
4052 let state = self . finalize ( ) ;
53+ let output = output_or_error?;
4154 Ok ( ExecResultAndState :: new ( output, state) )
4255 }
4356
@@ -59,20 +72,34 @@ pub trait InspectEvm: ExecuteEvm {
5972pub trait InspectCommitEvm : InspectEvm + ExecuteCommitEvm {
6073 /// Inspect the EVM with the current inspector and previous transaction by replaying, similar to [`InspectEvm::inspect_tx`]
6174 /// and commit the state diff to the database.
75+ ///
76+ /// # Outcome of Error
77+ ///
78+ /// If the transaction fails, the journal is finalized (not committed) so it
79+ /// does not leak into the next transaction.
6280 fn inspect_tx_commit ( & mut self , tx : Self :: Tx ) -> Result < Self :: ExecutionResult , Self :: Error > {
63- let output = self . inspect_one_tx ( tx) ?;
81+ let output = self . inspect_one_tx ( tx) . inspect_err ( |_| {
82+ // finalize (clear) the journal on error; do not commit it.
83+ let _ = self . finalize ( ) ;
84+ } ) ?;
6485 self . commit_inner ( ) ;
6586 Ok ( output)
6687 }
6788
6889 /// Inspect the EVM with the given transaction and inspector similar to [`InspectEvm::inspect`]
6990 /// and commit the state diff to the database.
91+ ///
92+ /// # Outcome of Error
93+ ///
94+ /// Same as [`InspectCommitEvm::inspect_tx_commit`]: the journal is finalized on error.
7095 fn inspect_commit (
7196 & mut self ,
7297 tx : Self :: Tx ,
7398 inspector : Self :: Inspector ,
7499 ) -> Result < Self :: ExecutionResult , Self :: Error > {
75- let output = self . inspect_one ( tx, inspector) ?;
100+ let output = self . inspect_one ( tx, inspector) . inspect_err ( |_| {
101+ let _ = self . finalize ( ) ;
102+ } ) ?;
76103 self . commit_inner ( ) ;
77104 Ok ( output)
78105 }
@@ -109,28 +136,38 @@ pub trait InspectSystemCallEvm: InspectEvm + SystemCallEvm {
109136 /// Inspect a system call and finalize the state.
110137 ///
111138 /// Similar to [`InspectEvm::inspect_tx`] but for system calls.
139+ ///
140+ /// # Outcome of Error
141+ ///
142+ /// Same as [`InspectEvm::inspect_tx`]: the journal is finalized on error.
112143 fn inspect_system_call (
113144 & mut self ,
114145 system_contract_address : Address ,
115146 data : Bytes ,
116147 ) -> Result < ExecResultAndState < Self :: ExecutionResult , Self :: State > , Self :: Error > {
117- let output = self . inspect_one_system_call ( system_contract_address, data) ? ;
148+ let output_or_error = self . inspect_one_system_call ( system_contract_address, data) ;
118149 let state = self . finalize ( ) ;
150+ let output = output_or_error?;
119151 Ok ( ExecResultAndState :: new ( output, state) )
120152 }
121153
122154 /// Inspect a system call with a custom caller and finalize the state.
123155 ///
124156 /// Similar to [`InspectEvm::inspect_tx`] but for system calls with a custom caller.
157+ ///
158+ /// # Outcome of Error
159+ ///
160+ /// Same as [`InspectEvm::inspect_tx`]: the journal is finalized on error.
125161 fn inspect_system_call_with_caller (
126162 & mut self ,
127163 caller : Address ,
128164 system_contract_address : Address ,
129165 data : Bytes ,
130166 ) -> Result < ExecResultAndState < Self :: ExecutionResult , Self :: State > , Self :: Error > {
131- let output =
132- self . inspect_one_system_call_with_caller ( caller, system_contract_address, data) ? ;
167+ let output_or_error =
168+ self . inspect_one_system_call_with_caller ( caller, system_contract_address, data) ;
133169 let state = self . finalize ( ) ;
170+ let output = output_or_error?;
134171 Ok ( ExecResultAndState :: new ( output, state) )
135172 }
136173
@@ -150,15 +187,20 @@ pub trait InspectSystemCallEvm: InspectEvm + SystemCallEvm {
150187 /// Inspect a system call with a given inspector and finalize the state.
151188 ///
152189 /// Similar to [`InspectEvm::inspect`] but for system calls.
190+ ///
191+ /// # Outcome of Error
192+ ///
193+ /// Same as [`InspectEvm::inspect_tx`]: the journal is finalized on error.
153194 fn inspect_system_call_with_inspector (
154195 & mut self ,
155196 system_contract_address : Address ,
156197 data : Bytes ,
157198 inspector : Self :: Inspector ,
158199 ) -> Result < ExecResultAndState < Self :: ExecutionResult , Self :: State > , Self :: Error > {
159- let output =
160- self . inspect_one_system_call_with_inspector ( system_contract_address, data, inspector) ? ;
200+ let output_or_error =
201+ self . inspect_one_system_call_with_inspector ( system_contract_address, data, inspector) ;
161202 let state = self . finalize ( ) ;
203+ let output = output_or_error?;
162204 Ok ( ExecResultAndState :: new ( output, state) )
163205 }
164206
@@ -179,20 +221,25 @@ pub trait InspectSystemCallEvm: InspectEvm + SystemCallEvm {
179221 /// Inspect a system call with a given inspector and finalize the state.
180222 ///
181223 /// Similar to [`InspectEvm::inspect`] but for system calls.
224+ ///
225+ /// # Outcome of Error
226+ ///
227+ /// Same as [`InspectEvm::inspect_tx`]: the journal is finalized on error.
182228 fn inspect_system_call_with_inspector_and_caller (
183229 & mut self ,
184230 caller : Address ,
185231 system_contract_address : Address ,
186232 data : Bytes ,
187233 inspector : Self :: Inspector ,
188234 ) -> Result < ExecResultAndState < Self :: ExecutionResult , Self :: State > , Self :: Error > {
189- let output = self . inspect_one_system_call_with_inspector_and_caller (
235+ let output_or_error = self . inspect_one_system_call_with_inspector_and_caller (
190236 caller,
191237 system_contract_address,
192238 data,
193239 inspector,
194- ) ? ;
240+ ) ;
195241 let state = self . finalize ( ) ;
242+ let output = output_or_error?;
196243 Ok ( ExecResultAndState :: new ( output, state) )
197244 }
198245}
0 commit comments