@@ -72,11 +72,11 @@ pub struct Executor {
72
72
// only interested in the database. REVM's `EVM` is a thin
73
73
// wrapper around spawning a new EVM on every call anyway,
74
74
// so the performance difference should be negligible.
75
- pub backend : Backend ,
75
+ backend : Backend ,
76
76
/// The EVM environment.
77
- pub env : EnvWithHandlerCfg ,
77
+ env : EnvWithHandlerCfg ,
78
78
/// The Revm inspector stack.
79
- pub inspector : InspectorStack ,
79
+ inspector : InspectorStack ,
80
80
/// The gas limit for calls and deployments. This is different from the gas limit imposed by
81
81
/// the passed in environment, as those limits are used by the EVM for certain opcodes like
82
82
/// `gaslimit`.
@@ -99,7 +99,7 @@ impl Executor {
99
99
gas_limit : u64 ,
100
100
) -> Self {
101
101
// Need to create a non-empty contract on the cheatcodes address so `extcodesize` checks
102
- // does not fail
102
+ // do not fail.
103
103
backend. insert_account_info (
104
104
CHEATCODE_ADDRESS ,
105
105
revm:: primitives:: AccountInfo {
@@ -114,16 +114,51 @@ impl Executor {
114
114
Self { backend, env, inspector, gas_limit }
115
115
}
116
116
117
- /// Returns the spec ID of the executor.
117
+ fn clone_with_backend ( & self , backend : Backend ) -> Self {
118
+ let env = EnvWithHandlerCfg :: new_with_spec_id ( Box :: new ( self . env ( ) . clone ( ) ) , self . spec_id ( ) ) ;
119
+ Self :: new ( backend, env, self . inspector ( ) . clone ( ) , self . gas_limit )
120
+ }
121
+
122
+ /// Returns a reference to the EVM backend.
123
+ pub fn backend ( & self ) -> & Backend {
124
+ & self . backend
125
+ }
126
+
127
+ /// Returns a mutable reference to the EVM backend.
128
+ pub fn backend_mut ( & mut self ) -> & mut Backend {
129
+ & mut self . backend
130
+ }
131
+
132
+ /// Returns a reference to the EVM environment.
133
+ pub fn env ( & self ) -> & Env {
134
+ & self . env . env
135
+ }
136
+
137
+ /// Returns a mutable reference to the EVM environment.
138
+ pub fn env_mut ( & mut self ) -> & mut Env {
139
+ & mut self . env . env
140
+ }
141
+
142
+ /// Returns a reference to the EVM inspector.
143
+ pub fn inspector ( & self ) -> & InspectorStack {
144
+ & self . inspector
145
+ }
146
+
147
+ /// Returns a mutable reference to the EVM inspector.
148
+ pub fn inspector_mut ( & mut self ) -> & mut InspectorStack {
149
+ & mut self . inspector
150
+ }
151
+
152
+ /// Returns the EVM spec ID.
118
153
pub fn spec_id ( & self ) -> SpecId {
119
- self . env . handler_cfg . spec_id
154
+ self . env . spec_id ( )
120
155
}
121
156
122
157
/// Creates the default CREATE2 Contract Deployer for local tests and scripts.
123
158
pub fn deploy_create2_deployer ( & mut self ) -> eyre:: Result < ( ) > {
124
159
trace ! ( "deploying local create2 deployer" ) ;
125
160
let create2_deployer_account = self
126
- . backend
161
+ . backend ( )
127
162
. basic_ref ( DEFAULT_CREATE2_DEPLOYER ) ?
128
163
. ok_or_else ( || DatabaseError :: MissingAccount ( DEFAULT_CREATE2_DEPLOYER ) ) ?;
129
164
@@ -145,53 +180,52 @@ impl Executor {
145
180
}
146
181
147
182
/// Set the balance of an account.
148
- pub fn set_balance ( & mut self , address : Address , amount : U256 ) -> DatabaseResult < & mut Self > {
183
+ pub fn set_balance ( & mut self , address : Address , amount : U256 ) -> DatabaseResult < ( ) > {
149
184
trace ! ( ?address, ?amount, "setting account balance" ) ;
150
- let mut account = self . backend . basic_ref ( address) ?. unwrap_or_default ( ) ;
185
+ let mut account = self . backend ( ) . basic_ref ( address) ?. unwrap_or_default ( ) ;
151
186
account. balance = amount;
152
-
153
- self . backend . insert_account_info ( address, account) ;
154
- Ok ( self )
187
+ self . backend_mut ( ) . insert_account_info ( address, account) ;
188
+ Ok ( ( ) )
155
189
}
156
190
157
191
/// Gets the balance of an account
158
192
pub fn get_balance ( & self , address : Address ) -> DatabaseResult < U256 > {
159
- Ok ( self . backend . basic_ref ( address) ?. map ( |acc| acc. balance ) . unwrap_or_default ( ) )
193
+ Ok ( self . backend ( ) . basic_ref ( address) ?. map ( |acc| acc. balance ) . unwrap_or_default ( ) )
160
194
}
161
195
162
196
/// Set the nonce of an account.
163
- pub fn set_nonce ( & mut self , address : Address , nonce : u64 ) -> DatabaseResult < & mut Self > {
164
- let mut account = self . backend . basic_ref ( address) ?. unwrap_or_default ( ) ;
197
+ pub fn set_nonce ( & mut self , address : Address , nonce : u64 ) -> DatabaseResult < ( ) > {
198
+ let mut account = self . backend ( ) . basic_ref ( address) ?. unwrap_or_default ( ) ;
165
199
account. nonce = nonce;
166
- self . backend . insert_account_info ( address, account) ;
167
- Ok ( self )
200
+ self . backend_mut ( ) . insert_account_info ( address, account) ;
201
+ Ok ( ( ) )
168
202
}
169
203
170
204
/// Returns the nonce of an account.
171
205
pub fn get_nonce ( & self , address : Address ) -> DatabaseResult < u64 > {
172
- Ok ( self . backend . basic_ref ( address) ?. map ( |acc| acc. nonce ) . unwrap_or_default ( ) )
206
+ Ok ( self . backend ( ) . basic_ref ( address) ?. map ( |acc| acc. nonce ) . unwrap_or_default ( ) )
173
207
}
174
208
175
209
/// Returns `true` if the account has no code.
176
210
pub fn is_empty_code ( & self , address : Address ) -> DatabaseResult < bool > {
177
- Ok ( self . backend . basic_ref ( address) ?. map ( |acc| acc. is_empty_code_hash ( ) ) . unwrap_or ( true ) )
211
+ Ok ( self . backend ( ) . basic_ref ( address) ?. map ( |acc| acc. is_empty_code_hash ( ) ) . unwrap_or ( true ) )
178
212
}
179
213
180
214
#[ inline]
181
215
pub fn set_tracing ( & mut self , tracing : bool ) -> & mut Self {
182
- self . inspector . tracing ( tracing) ;
216
+ self . inspector_mut ( ) . tracing ( tracing) ;
183
217
self
184
218
}
185
219
186
220
#[ inline]
187
221
pub fn set_debugger ( & mut self , debugger : bool ) -> & mut Self {
188
- self . inspector . enable_debugger ( debugger) ;
222
+ self . inspector_mut ( ) . enable_debugger ( debugger) ;
189
223
self
190
224
}
191
225
192
226
#[ inline]
193
227
pub fn set_trace_printer ( & mut self , trace_printer : bool ) -> & mut Self {
194
- self . inspector . print ( trace_printer) ;
228
+ self . inspector_mut ( ) . print ( trace_printer) ;
195
229
self
196
230
}
197
231
@@ -242,7 +276,7 @@ impl Executor {
242
276
243
277
// also mark this library as persistent, this will ensure that the state of the library is
244
278
// persistent across fork swaps in forking mode
245
- self . backend . add_persistent_account ( address) ;
279
+ self . backend_mut ( ) . add_persistent_account ( address) ;
246
280
247
281
debug ! ( %address, "deployed contract" ) ;
248
282
@@ -264,15 +298,15 @@ impl Executor {
264
298
trace ! ( ?from, ?to, "setting up contract" ) ;
265
299
266
300
let from = from. unwrap_or ( CALLER ) ;
267
- self . backend . set_test_contract ( to) . set_caller ( from) ;
301
+ self . backend_mut ( ) . set_test_contract ( to) . set_caller ( from) ;
268
302
let calldata = Bytes :: from_static ( & ITest :: setUpCall:: SELECTOR ) ;
269
303
let mut res = self . transact_raw ( from, to, calldata, U256 :: ZERO ) ?;
270
304
res = res. into_result ( rd) ?;
271
305
272
306
// record any changes made to the block's environment during setup
273
- self . env . block = res. env . block . clone ( ) ;
307
+ self . env_mut ( ) . block = res. env . block . clone ( ) ;
274
308
// and also the chainid, which can be set manually
275
- self . env . cfg . chain_id = res. env . cfg . chain_id ;
309
+ self . env_mut ( ) . cfg . chain_id = res. env . cfg . chain_id ;
276
310
277
311
let success =
278
312
self . is_raw_call_success ( to, Cow :: Borrowed ( & res. state_changeset ) , & res, false ) ;
@@ -356,16 +390,16 @@ impl Executor {
356
390
///
357
391
/// The state after the call is **not** persisted.
358
392
pub fn call_with_env ( & self , mut env : EnvWithHandlerCfg ) -> eyre:: Result < RawCallResult > {
359
- let mut inspector = self . inspector . clone ( ) ;
360
- let mut backend = CowBackend :: new ( & self . backend ) ;
393
+ let mut inspector = self . inspector ( ) . clone ( ) ;
394
+ let mut backend = CowBackend :: new_borrowed ( self . backend ( ) ) ;
361
395
let result = backend. inspect ( & mut env, & mut inspector) ?;
362
396
convert_executed_result ( env, inspector, result, backend. has_snapshot_failure ( ) )
363
397
}
364
398
365
399
/// Execute the transaction configured in `env.tx`.
366
400
pub fn transact_with_env ( & mut self , mut env : EnvWithHandlerCfg ) -> eyre:: Result < RawCallResult > {
367
- let mut inspector = self . inspector . clone ( ) ;
368
- let backend = & mut self . backend ;
401
+ let mut inspector = self . inspector ( ) . clone ( ) ;
402
+ let backend = self . backend_mut ( ) ;
369
403
let result = backend. inspect ( & mut env, & mut inspector) ?;
370
404
let mut result =
371
405
convert_executed_result ( env, inspector, result, backend. has_snapshot_failure ( ) ) ?;
@@ -379,11 +413,11 @@ impl Executor {
379
413
/// This should not be exposed to the user, as it should be called only by `transact*`.
380
414
fn commit ( & mut self , result : & mut RawCallResult ) {
381
415
// Persist changes to db.
382
- self . backend . commit ( result. state_changeset . clone ( ) ) ;
416
+ self . backend_mut ( ) . commit ( result. state_changeset . clone ( ) ) ;
383
417
384
418
// Persist cheatcode state.
385
- self . inspector . cheatcodes = result. cheatcodes . take ( ) ;
386
- if let Some ( cheats) = self . inspector . cheatcodes . as_mut ( ) {
419
+ self . inspector_mut ( ) . cheatcodes = result. cheatcodes . take ( ) ;
420
+ if let Some ( cheats) = self . inspector_mut ( ) . cheatcodes . as_mut ( ) {
387
421
// Clear broadcastable transactions
388
422
cheats. broadcastable_transactions . clear ( ) ;
389
423
debug ! ( target: "evm::executors" , "cleared broadcastable transactions" ) ;
@@ -393,7 +427,7 @@ impl Executor {
393
427
}
394
428
395
429
// Persist the changed environment.
396
- self . inspector . set_env ( & result. env ) ;
430
+ self . inspector_mut ( ) . set_env ( & result. env ) ;
397
431
}
398
432
399
433
/// Checks if a call to a test contract was successful.
@@ -474,20 +508,20 @@ impl Executor {
474
508
reverted : bool ,
475
509
state_changeset : Cow < ' _ , StateChangeset > ,
476
510
) -> bool {
477
- if self . backend . has_snapshot_failure ( ) {
511
+ if self . backend ( ) . has_snapshot_failure ( ) {
478
512
// a failure occurred in a reverted snapshot, which is considered a failed test
479
513
return false ;
480
514
}
481
515
482
516
let mut success = !reverted;
483
517
if success {
484
518
// Construct a new bare-bones backend to evaluate success.
485
- let mut backend = self . backend . clone_empty ( ) ;
519
+ let mut backend = self . backend ( ) . clone_empty ( ) ;
486
520
487
521
// We only clone the test contract and cheatcode accounts,
488
522
// that's all we need to evaluate success.
489
523
for address in [ address, CHEATCODE_ADDRESS ] {
490
- let Ok ( acc) = self . backend . basic_ref ( address) else { return false } ;
524
+ let Ok ( acc) = self . backend ( ) . basic_ref ( address) else { return false } ;
491
525
backend. insert_account_info ( address, acc. unwrap_or_default ( ) ) ;
492
526
}
493
527
@@ -498,8 +532,7 @@ impl Executor {
498
532
backend. commit ( state_changeset. into_owned ( ) ) ;
499
533
500
534
// Check if a DSTest assertion failed
501
- let executor =
502
- Self :: new ( backend, self . env . clone ( ) , self . inspector . clone ( ) , self . gas_limit ) ;
535
+ let executor = self . clone_with_backend ( backend) ;
503
536
let call = executor. call_sol ( CALLER , address, & ITest :: failedCall { } , U256 :: ZERO , None ) ;
504
537
match call {
505
538
Ok ( CallResult { raw : _, decoded_result : ITest :: failedReturn { failed } } ) => {
@@ -526,14 +559,14 @@ impl Executor {
526
559
value : U256 ,
527
560
) -> EnvWithHandlerCfg {
528
561
let env = Env {
529
- cfg : self . env . cfg . clone ( ) ,
562
+ cfg : self . env ( ) . cfg . clone ( ) ,
530
563
// We always set the gas price to 0 so we can execute the transaction regardless of
531
564
// network conditions - the actual gas price is kept in `self.block` and is applied by
532
565
// the cheatcode handler if it is enabled
533
566
block : BlockEnv {
534
567
basefee : U256 :: ZERO ,
535
568
gas_limit : U256 :: from ( self . gas_limit ) ,
536
- ..self . env . block . clone ( )
569
+ ..self . env ( ) . block . clone ( )
537
570
} ,
538
571
tx : TxEnv {
539
572
caller,
@@ -544,11 +577,11 @@ impl Executor {
544
577
gas_price : U256 :: ZERO ,
545
578
gas_priority_fee : None ,
546
579
gas_limit : self . gas_limit ,
547
- ..self . env . tx . clone ( )
580
+ ..self . env ( ) . tx . clone ( )
548
581
} ,
549
582
} ;
550
583
551
- EnvWithHandlerCfg :: new_with_spec_id ( Box :: new ( env) , self . env . handler_cfg . spec_id )
584
+ EnvWithHandlerCfg :: new_with_spec_id ( Box :: new ( env) , self . spec_id ( ) )
552
585
}
553
586
}
554
587
0 commit comments