trevm/evm/
all_states.rs

1use crate::{
2    db::{StateAcc, TryStateAcc},
3    helpers::{Ctx, Evm, Instruction},
4    inspectors::Layered,
5    ErroredState, EvmErrored, EvmExtUnchecked, Trevm,
6};
7use alloy::{
8    primitives::{Address, U256},
9    rpc::types::state::StateOverride,
10};
11use core::convert::Infallible;
12use revm::{
13    bytecode::opcode::DIFFICULTY,
14    context::{result::EVMError, Cfg as _, ContextTr},
15    handler::EthPrecompiles,
16    inspector::NoOpInspector,
17    interpreter::instructions::block_info,
18    primitives::hardfork::SpecId,
19    state::{AccountInfo, Bytecode, EvmState},
20    Database, DatabaseCommit, DatabaseRef, Inspector,
21};
22
23impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
24where
25    Db: Database,
26    Insp: Inspector<Ctx<Db>>,
27{
28    /// Get a reference to the current [`Evm`].
29    ///
30    /// [`Evm`]: revm::context::Evm
31    pub fn inner(&self) -> &Evm<Db, Insp> {
32        self.as_ref()
33    }
34
35    /// Get a mutable reference to the current [`Evm`]. This should be used with
36    /// caution, as modifying the EVM may lead to inconsistent Trevmstate or
37    /// invalid execution.
38    ///
39    /// [`Evm`]: revm::context::Evm
40    pub fn inner_mut_unchecked(&mut self) -> &mut Evm<Db, Insp> {
41        &mut self.inner
42    }
43
44    /// Destructure the [`Trevm`] into its inner EVM.
45    pub fn into_inner(self) -> Box<Evm<Db, Insp>> {
46        self.inner
47    }
48
49    /// Deconstruct the [`Trevm`] into the backing DB, dropping all other types.
50    pub fn into_db(self) -> Db {
51        self.inner.ctx.journaled_state.database
52    }
53
54    /// Get a reference to the inspector.
55    pub fn inspector(&self) -> &Insp {
56        &self.inner.inspector
57    }
58
59    /// Get a mutable reference to the inspector.
60    pub fn inspector_mut(&mut self) -> &mut Insp {
61        &mut self.inner.inspector
62    }
63
64    /// Replace the current inspector with a new inspector of the same type.
65    pub fn replace_inspector(mut self, inspector: Insp) -> Self {
66        *self.inspector_mut() = inspector;
67        self
68    }
69
70    /// Layer a new inspector on top of the current one.
71    pub fn layer_inspector<Insp2>(
72        self,
73        inspector: Insp2,
74    ) -> Trevm<Db, Layered<Insp2, Insp>, TrevmState>
75    where
76        Insp2: Inspector<Ctx<Db>>,
77    {
78        let inner = Box::new(Evm {
79            ctx: self.inner.ctx,
80            inspector: Layered::new(inspector, self.inner.inspector),
81            instruction: self.inner.instruction,
82            precompiles: self.inner.precompiles,
83            frame_stack: self.inner.frame_stack,
84        });
85        Trevm { inner, state: self.state }
86    }
87
88    /// Take the inspector out of the Trevm, replacing it with a
89    /// [`NoOpInspector`].
90    pub fn take_inspector(self) -> (Insp, Trevm<Db, NoOpInspector, TrevmState>) {
91        let inspector = self.inner.inspector;
92        let inner = Box::new(Evm {
93            ctx: self.inner.ctx,
94            inspector: NoOpInspector,
95            instruction: self.inner.instruction,
96            precompiles: self.inner.precompiles,
97            frame_stack: self.inner.frame_stack,
98        });
99        (inspector, Trevm { inner, state: self.state })
100    }
101
102    /// Replace the current inspector with a new one, dropping the old one.
103    pub fn set_inspector<Insp2>(self, inspector: Insp2) -> Trevm<Db, Insp2, TrevmState>
104    where
105        Insp2: Inspector<Ctx<Db>>,
106    {
107        let inner = Box::new(Evm {
108            ctx: self.inner.ctx,
109            inspector,
110            instruction: self.inner.instruction,
111            precompiles: self.inner.precompiles,
112            frame_stack: self.inner.frame_stack,
113        });
114        Trevm { inner, state: self.state }
115    }
116
117    /// Run the closure with a different inspector, then restore the previous
118    /// one.
119    pub fn with_inspector<Insp2, F, NewState>(
120        self,
121        inspector: Insp2,
122        f: F,
123    ) -> Trevm<Db, Insp, NewState>
124    where
125        Insp2: Inspector<Ctx<Db>>,
126        F: FnOnce(Trevm<Db, Insp2, TrevmState>) -> Trevm<Db, Insp2, NewState>,
127    {
128        let (old, this) = self.take_inspector();
129        let this = f(this.set_inspector(inspector));
130        this.set_inspector(old)
131    }
132
133    /// Run a fallible function with the provided inspector, then restore the
134    /// previous inspector. If the function returns an error, it will be
135    /// wrapped in an [`EvmErrored`] along with the current EVM state.
136    pub fn try_with_inspector<F, Insp2, NewState, E>(
137        self,
138        inspector: Insp2,
139        f: F,
140    ) -> Result<Trevm<Db, Insp, NewState>, EvmErrored<Db, Insp, E>>
141    where
142        Insp2: Inspector<Ctx<Db>>,
143        F: FnOnce(
144            Trevm<Db, Insp2, TrevmState>,
145        ) -> Result<Trevm<Db, Insp2, NewState>, EvmErrored<Db, Insp2, E>>,
146    {
147        let (previous, this) = self.take_inspector();
148        let this = this.set_inspector(inspector);
149
150        match f(this) {
151            Ok(evm) => Ok(evm.set_inspector(previous)),
152            Err(evm) => Err(evm.set_inspector(previous)),
153        }
154    }
155
156    /// Get the id of the currently running hardfork spec.
157    pub fn spec_id(&self) -> SpecId {
158        self.inner.ctx.cfg().spec()
159    }
160
161    /// Set the [SpecId], modifying the EVM handlers accordingly. This function
162    /// should be called at hardfork boundaries when running multi-block trevm
163    /// flows.
164    pub fn set_spec_id(&mut self, spec_id: SpecId) {
165        self.inner.modify_cfg(|cfg| cfg.spec = spec_id);
166    }
167
168    /// Run a closure with a different [SpecId], then restore the previous
169    /// setting.
170    pub fn with_spec_id<F, NewState>(mut self, spec_id: SpecId, f: F) -> Trevm<Db, Insp, NewState>
171    where
172        F: FnOnce(Self) -> Trevm<Db, Insp, NewState>,
173    {
174        let old = self.spec_id();
175        self.set_spec_id(spec_id);
176        let mut this = f(self);
177        this.set_spec_id(old);
178        this
179    }
180
181    /// Convert self into [`EvmErrored`] by supplying an error
182    pub fn errored<E>(self, error: E) -> EvmErrored<Db, Insp, E> {
183        EvmErrored { inner: self.inner, state: ErroredState { error } }
184    }
185
186    /// Apply [`StateOverride`]s to the current state. Errors if the overrides
187    /// contain invalid bytecode.
188    pub fn apply_state_overrides(
189        mut self,
190        overrides: &StateOverride,
191    ) -> Result<Self, EVMError<<Db as Database>::Error>>
192    where
193        Db: DatabaseCommit,
194    {
195        for (address, account_override) in overrides {
196            if let Some(balance) = account_override.balance {
197                self.inner.set_balance(*address, balance).map_err(EVMError::Database)?;
198            }
199            if let Some(nonce) = account_override.nonce {
200                self.inner.set_nonce(*address, nonce).map_err(EVMError::Database)?;
201            }
202            if let Some(code) = account_override.code.as_ref() {
203                self.inner
204                    .set_bytecode(
205                        *address,
206                        Bytecode::new_raw_checked(code.clone())
207                            .map_err(|_| EVMError::Custom("Invalid bytecode".to_string()))?,
208                    )
209                    .map_err(EVMError::Database)?;
210            }
211            if let Some(state) = account_override.state.as_ref() {
212                for (slot, value) in state {
213                    self.inner
214                        .set_storage(
215                            *address,
216                            U256::from_be_bytes((*slot).into()),
217                            U256::from_be_bytes((*value).into()),
218                        )
219                        .map_err(EVMError::Database)?;
220                }
221            }
222        }
223        Ok(self)
224    }
225
226    /// Apply [`StateOverride`]s to the current state, if they are provided.
227    pub fn maybe_apply_state_overrides(
228        self,
229        overrides: Option<&StateOverride>,
230    ) -> Result<Self, EVMError<<Db as Database>::Error>>
231    where
232        Db: DatabaseCommit,
233    {
234        if let Some(overrides) = overrides {
235            self.apply_state_overrides(overrides)
236        } else {
237            Ok(self)
238        }
239    }
240
241    /// Overide an opcode with a custom handler. Returns the previous
242    /// instruction handler for the opcode.
243    pub fn override_opcode(&mut self, opcode: u8, handler: Instruction<Db>) -> Instruction<Db> {
244        std::mem::replace(&mut self.inner.instruction.instruction_table[opcode as usize], handler)
245    }
246
247    /// Disable an opcode by replacing it with unknown opcode behavior. This is
248    /// a shortcut for [`Self::override_opcode`] with [`crate::helpers::forbidden`].
249    pub fn disable_opcode(&mut self, opcode: u8) -> Instruction<Db> {
250        self.override_opcode(opcode, Instruction::new(crate::helpers::forbidden, 0))
251    }
252
253    /// Run some closure with an opcode override, then restore the previous
254    /// setting.
255    pub fn with_opcode_override<F, NewState>(
256        mut self,
257        opcode: u8,
258        handler: Instruction<Db>,
259        f: F,
260    ) -> Trevm<Db, Insp, NewState>
261    where
262        F: FnOnce(Self) -> Trevm<Db, Insp, NewState>,
263    {
264        let old = self.override_opcode(opcode, handler);
265        self.inner.instruction.insert_instruction(opcode, handler);
266        let mut this = f(self);
267        this.override_opcode(opcode, old);
268        this
269    }
270
271    /// Disable the prevrandao opcode, by replacing it with unknown opcode
272    /// behavior. This is useful for block simulation, where the prevrandao
273    /// opcode may produce incorrect results.
274    pub fn disable_prevrandao(&mut self) -> Instruction<Db> {
275        self.disable_opcode(DIFFICULTY)
276    }
277
278    /// Enable the prevrandao opcode. If the prevrandao opcode was not
279    /// previously disabled or replaced, this will have no effect on behavior.
280    pub fn enable_prevrandao(&mut self) -> Instruction<Db> {
281        self.override_opcode(DIFFICULTY, Instruction::new(block_info::difficulty, 2))
282    }
283
284    /// Run some code with the prevrandao opcode disabled, then restore the
285    /// previous setting. This is useful for block simulation, where the
286    /// prevrandao opcode may produce incorrect results.
287    pub fn without_prevrandao<F, NewState>(self, f: F) -> Trevm<Db, Insp, NewState>
288    where
289        F: FnOnce(Self) -> Trevm<Db, Insp, NewState>,
290    {
291        self.with_opcode_override(DIFFICULTY, Instruction::new(crate::helpers::forbidden, 0), f)
292    }
293
294    /// Set the precompiles for the EVM. This will replace the current
295    /// precompiles with the provided ones.
296    pub fn override_precompiles(&mut self, precompiles: EthPrecompiles) -> EthPrecompiles {
297        std::mem::replace(&mut self.inner.precompiles, precompiles)
298    }
299
300    /// Run a closure with a different set of precompiles, then restore the
301    /// previous setting.
302    pub fn with_precompiles<F, NewState>(
303        mut self,
304        precompiles: EthPrecompiles,
305        f: F,
306    ) -> Trevm<Db, Insp, NewState>
307    where
308        F: FnOnce(Self) -> Trevm<Db, Insp, NewState>,
309    {
310        let old = self.override_precompiles(precompiles);
311        let mut this = f(self);
312        this.override_precompiles(old);
313        this
314    }
315}
316
317// Fallible DB Reads with &mut self
318impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
319where
320    Db: Database,
321    Insp: Inspector<Ctx<Db>>,
322{
323    /// Get the current account info for a specific address.
324    ///
325    /// Note: due to revm's DB model, this requires a mutable pointer.
326    pub fn try_read_account(
327        &mut self,
328        address: Address,
329    ) -> Result<Option<AccountInfo>, <Db as Database>::Error> {
330        self.inner.db_mut().basic(address)
331    }
332
333    /// Get the current nonce for a specific address
334    ///
335    /// Note: due to revm's DB model, this requires a mutable pointer.
336    pub fn try_read_nonce(&mut self, address: Address) -> Result<u64, <Db as Database>::Error> {
337        self.try_read_account(address).map(|a| a.map(|a| a.nonce).unwrap_or_default())
338    }
339
340    /// Get the current nonce for a specific address
341    ///
342    /// Note: due to revm's DB model, this requires a mutable pointer.
343    pub fn try_read_balance(&mut self, address: Address) -> Result<U256, <Db as Database>::Error> {
344        self.try_read_account(address).map(|a| a.map(|a| a.balance).unwrap_or_default())
345    }
346
347    /// Get the value of a storage slot.
348    ///
349    /// Note: due to revm's DB model, this requires a mutable pointer.
350    pub fn try_read_storage(
351        &mut self,
352        address: Address,
353        slot: U256,
354    ) -> Result<U256, <Db as Database>::Error> {
355        self.inner.db_mut().storage(address, slot)
356    }
357
358    /// Get the code at the given account, if any.
359    ///
360    /// Note: due to revm's DB model, this requires a mutable pointer.
361    pub fn try_read_code(
362        &mut self,
363        address: Address,
364    ) -> Result<Option<Bytecode>, <Db as Database>::Error> {
365        let acct_info = self.try_read_account(address)?;
366        match acct_info {
367            Some(acct) => Ok(Some(self.inner.db_mut().code_by_hash(acct.code_hash)?)),
368            None => Ok(None),
369        }
370    }
371
372    /// Get the gas allowance for a specific caller and gas price.
373    pub fn try_gas_allowance(
374        &mut self,
375        caller: Address,
376        gas_price: u128,
377    ) -> Result<u64, <Db as Database>::Error> {
378        if gas_price == 0 {
379            return Ok(u64::MAX);
380        }
381        let gas_price = U256::from(gas_price);
382        let balance = self.try_read_balance(caller)?;
383        Ok((balance / gas_price).saturating_to())
384    }
385}
386
387// Fallible DB Reads with &self
388impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
389where
390    Db: Database + DatabaseRef,
391    Insp: Inspector<Ctx<Db>>,
392{
393    /// Get the current account info for a specific address.
394    pub fn try_read_account_ref(
395        &self,
396        address: Address,
397    ) -> Result<Option<AccountInfo>, <Db as DatabaseRef>::Error> {
398        self.inner.db_ref().basic_ref(address)
399    }
400
401    /// Get the current nonce for a specific address
402    ///
403    /// Note: due to revm's DB model, this requires a mutable pointer.
404    pub fn try_read_nonce_ref(&self, address: Address) -> Result<u64, <Db as DatabaseRef>::Error> {
405        self.try_read_account_ref(address).map(|a| a.map(|a| a.nonce).unwrap_or_default())
406    }
407
408    /// Get the current nonce for a specific address
409    ///
410    /// Note: due to revm's DB model, this requires a mutable pointer.
411    pub fn try_read_balance_ref(
412        &self,
413        address: Address,
414    ) -> Result<U256, <Db as DatabaseRef>::Error> {
415        self.try_read_account_ref(address).map(|a| a.map(|a| a.balance).unwrap_or_default())
416    }
417
418    /// Get the value of a storage slot.
419    pub fn try_read_storage_ref(
420        &self,
421        address: Address,
422        slot: U256,
423    ) -> Result<U256, <Db as DatabaseRef>::Error> {
424        self.inner.db_ref().storage_ref(address, slot)
425    }
426
427    /// Get the code at the given account, if any.
428    pub fn try_read_code_ref(
429        &self,
430        address: Address,
431    ) -> Result<Option<Bytecode>, <Db as DatabaseRef>::Error> {
432        let acct_info = self.try_read_account_ref(address)?;
433        match acct_info {
434            Some(acct) => Ok(Some(self.inner.db_ref().code_by_hash_ref(acct.code_hash)?)),
435            None => Ok(None),
436        }
437    }
438
439    /// Get the gas allowance for a specific caller and gas price.
440    pub fn try_gas_allowance_ref(
441        &self,
442        caller: Address,
443        gas_price: U256,
444    ) -> Result<u64, <Db as DatabaseRef>::Error> {
445        if gas_price.is_zero() {
446            return Ok(u64::MAX);
447        }
448        let gas_price = U256::from(gas_price);
449        let balance = self.try_read_balance_ref(caller)?;
450        Ok((balance / gas_price).saturating_to())
451    }
452}
453
454// Infallible DB Reads with &mut self
455impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
456where
457    Db: Database<Error = Infallible>,
458    Insp: Inspector<Ctx<Db>>,
459{
460    /// Get the current account info for a specific address.
461    ///
462    /// Note: due to revm's DB model, this requires a mutable pointer.
463    pub fn read_account(&mut self, address: Address) -> Option<AccountInfo> {
464        self.inner.db_mut().basic(address).expect("infallible")
465    }
466
467    /// Get the current nonce for a specific address
468    ///
469    /// Note: due to revm's DB model, this requires a mutable pointer.
470    pub fn read_nonce(&mut self, address: Address) -> u64 {
471        self.read_account(address).map(|a: AccountInfo| a.nonce).unwrap_or_default()
472    }
473
474    /// Get the current nonce for a specific address
475    ///
476    /// Note: due to revm's DB model, this requires a mutable pointer.
477    pub fn read_balance(&mut self, address: Address) -> U256 {
478        self.read_account(address).map(|a: AccountInfo| a.balance).unwrap_or_default()
479    }
480
481    /// Get the value of a storage slot.
482    ///
483    /// Note: due to revm's DB model, this requires a mutable pointer.
484    pub fn read_storage(&mut self, address: Address, slot: U256) -> U256 {
485        self.inner.db_mut().storage(address, slot).expect("infallible")
486    }
487
488    /// Get the code at the given account, if any.
489    ///
490    /// Note: due to revm's DB model, this requires a mutable pointer.
491    pub fn read_code(&mut self, address: Address) -> Option<Bytecode> {
492        let acct_info = self.read_account(address)?;
493        Some(self.inner.db_mut().code_by_hash(acct_info.code_hash).expect("infallible"))
494    }
495}
496
497// Infalible DB Reads with &self
498impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
499where
500    Db: Database + DatabaseRef,
501    Insp: Inspector<Ctx<Db>>,
502{
503    /// Get the current account info for a specific address.
504    ///
505    /// Note: due to revm's DB model, this requires a mutable pointer.
506    pub fn read_account_ref(&self, address: Address) -> Option<AccountInfo> {
507        self.inner.db_ref().basic_ref(address).expect("infallible")
508    }
509
510    /// Get the current nonce for a specific address
511    pub fn read_nonce_ref(&self, address: Address) -> u64 {
512        self.read_account_ref(address).map(|a: AccountInfo| a.nonce).unwrap_or_default()
513    }
514
515    /// Get the current nonce for a specific address
516    pub fn read_balance_ref(&self, address: Address) -> U256 {
517        self.read_account_ref(address).map(|a: AccountInfo| a.balance).unwrap_or_default()
518    }
519
520    /// Get the value of a storage slot.
521    ///
522    /// Note: due to revm's DB model, this requires a mutable pointer.
523    pub fn read_storage_ref(&self, address: Address, slot: U256) -> U256 {
524        self.inner.db_ref().storage_ref(address, slot).expect("infallible")
525    }
526
527    /// Get the code at the given account, if any.
528    ///
529    /// Note: due to revm's DB model, this requires a mutable pointer.
530    pub fn read_code_ref(&self, address: Address) -> Option<Bytecode> {
531        let acct_info = self.read_account_ref(address)?;
532        Some(self.inner.db_ref().code_by_hash_ref(acct_info.code_hash).expect("infallible"))
533    }
534}
535
536impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
537where
538    Db: Database,
539    Insp: Inspector<Ctx<Db>>,
540{
541    /// Commit a set of state changes to the database. This is a low-level API,
542    /// and is not intended for general use. Regular users should prefer
543    /// executing a transaction.
544    pub fn commit_unchecked(&mut self, state: EvmState)
545    where
546        Db: DatabaseCommit,
547    {
548        self.inner.db_mut().commit(state);
549    }
550
551    /// Modify an account with a closure and commit the modified account. This
552    /// is a low-level API, and is not intended for general use.
553    pub fn try_modify_account_unchecked<F: FnOnce(&mut AccountInfo)>(
554        &mut self,
555        address: Address,
556        f: F,
557    ) -> Result<AccountInfo, <Db as Database>::Error>
558    where
559        Db: DatabaseCommit,
560    {
561        self.inner.modify_account(address, f)
562    }
563
564    /// Set the nonce of an account, returning the previous nonce. This is a
565    /// low-level API, and is not intended for general use.
566    pub fn try_set_nonce_unchecked(
567        &mut self,
568        address: Address,
569        nonce: u64,
570    ) -> Result<u64, <Db as Database>::Error>
571    where
572        Db: DatabaseCommit,
573    {
574        self.inner.set_nonce(address, nonce)
575    }
576
577    /// Increment the nonce of an account, returning the previous nonce. This is
578    /// a low-level API, and is not intended for general use.
579    ///
580    /// If the nonce is already at the maximum value, it will not be
581    /// incremented.
582    pub fn try_increment_nonce_unchecked(
583        &mut self,
584        address: Address,
585    ) -> Result<u64, <Db as Database>::Error>
586    where
587        Db: DatabaseCommit,
588    {
589        self.inner.increment_nonce(address)
590    }
591
592    /// Decrement the nonce of an account, returning the previous nonce. This is
593    /// a low-level API, and is not intended for general use.
594    ///
595    /// If the nonce is already 0, it will not be decremented.
596    pub fn try_decrement_nonce_unchecked(
597        &mut self,
598        address: Address,
599    ) -> Result<u64, <Db as Database>::Error>
600    where
601        Db: DatabaseCommit,
602    {
603        self.inner.decrement_nonce(address)
604    }
605
606    /// Set the EVM storage at a slot. This is a low-level API, and is not
607    /// intended for general use.
608    pub fn try_set_storage_unchecked(
609        &mut self,
610        address: Address,
611        slot: U256,
612        value: U256,
613    ) -> Result<U256, <Db as Database>::Error>
614    where
615        Db: DatabaseCommit,
616    {
617        self.inner.set_storage(address, slot, value)
618    }
619
620    /// Set the bytecode at a specific address, returning the previous bytecode
621    /// at that address. This is a low-level API, and is not intended for
622    /// general use.
623    pub fn try_set_bytecode_unchecked(
624        &mut self,
625        address: Address,
626        bytecode: Bytecode,
627    ) -> Result<Option<Bytecode>, <Db as Database>::Error>
628    where
629        Db: DatabaseCommit,
630    {
631        self.inner.set_bytecode(address, bytecode)
632    }
633
634    /// Increase the balance of an account. Returns the previous balance. This
635    /// is a low-level API, and is not intended for general use.
636    ///
637    /// If this would cause an overflow, the balance will be increased to the
638    /// maximum value.
639    pub fn try_increase_balance_unchecked(
640        &mut self,
641        address: Address,
642        amount: U256,
643    ) -> Result<U256, <Db as Database>::Error>
644    where
645        Db: DatabaseCommit,
646    {
647        self.inner.increase_balance(address, amount)
648    }
649
650    /// Decrease the balance of an account. Returns the previous balance. This
651    /// is a low-level API, and is not intended for general use.
652    ///
653    /// If this would cause an underflow, the balance will be decreased to 0.
654    pub fn try_decrease_balance_unchecked(
655        &mut self,
656        address: Address,
657        amount: U256,
658    ) -> Result<U256, <Db as Database>::Error>
659    where
660        Db: DatabaseCommit,
661    {
662        self.inner.decrease_balance(address, amount)
663    }
664
665    /// Set the balance of an account. Returns the previous balance. This is a
666    /// low-level API, and is not intended for general use.
667    pub fn try_set_balance_unchecked(
668        &mut self,
669        address: Address,
670        amount: U256,
671    ) -> Result<U256, <Db as Database>::Error>
672    where
673        Db: DatabaseCommit,
674    {
675        self.inner.set_balance(address, amount)
676    }
677}
678
679impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
680where
681    Db: Database<Error = Infallible>,
682    Insp: Inspector<Ctx<Db>>,
683{
684    /// Modify an account with a closure and commit the modified account. This
685    /// is a low-level API, and is not intended for general use.
686    pub fn modify_account_unchecked(
687        &mut self,
688        address: Address,
689        f: impl FnOnce(&mut AccountInfo),
690    ) -> AccountInfo
691    where
692        Db: DatabaseCommit,
693    {
694        self.try_modify_account_unchecked(address, f).expect("infallible")
695    }
696
697    /// Set the nonce of an account, returning the previous nonce. This is a
698    /// low-level API, and is not intended for general use.
699    pub fn set_nonce_unchecked(&mut self, address: Address, nonce: u64) -> u64
700    where
701        Db: DatabaseCommit,
702    {
703        self.try_set_nonce_unchecked(address, nonce).expect("infallible")
704    }
705
706    /// Increment the nonce of an account, returning the previous nonce. This is
707    /// a low-level API, and is not intended for general use.
708    ///
709    /// If this would cause the nonce to overflow, the nonce will be set to the
710    /// maximum value.
711    pub fn increment_nonce_unchecked(&mut self, address: Address) -> u64
712    where
713        Db: DatabaseCommit,
714    {
715        self.try_increment_nonce_unchecked(address).expect("infallible")
716    }
717
718    /// Decrement the nonce of an account, returning the previous nonce. This is
719    /// a low-level API, and is not intended for general use.
720    ///
721    /// If this would cause the nonce to underflow, the nonce will be set to 0.
722    pub fn decrement_nonce_unchecked(&mut self, address: Address) -> u64
723    where
724        Db: DatabaseCommit,
725    {
726        self.try_decrement_nonce_unchecked(address).expect("infallible")
727    }
728
729    /// Set the EVM storage at a slot. This is a low-level API, and is not
730    /// intended for general use.
731    pub fn set_storage_unchecked(&mut self, address: Address, slot: U256, value: U256) -> U256
732    where
733        Db: DatabaseCommit,
734    {
735        self.try_set_storage_unchecked(address, slot, value).expect("infallible")
736    }
737
738    /// Set the bytecode at a specific address, returning the previous bytecode
739    /// at that address. This is a low-level API, and is not intended for
740    /// general use.
741    pub fn set_bytecode_unchecked(
742        &mut self,
743        address: Address,
744        bytecode: Bytecode,
745    ) -> Option<Bytecode>
746    where
747        Db: DatabaseCommit,
748    {
749        self.try_set_bytecode_unchecked(address, bytecode).expect("infallible")
750    }
751
752    /// Increase the balance of an account. Returns the previous balance. This
753    /// is a low-level API, and is not intended for general use.
754    pub fn increase_balance_unchecked(&mut self, address: Address, amount: U256) -> U256
755    where
756        Db: DatabaseCommit,
757    {
758        self.try_increase_balance_unchecked(address, amount).expect("infallible")
759    }
760
761    /// Decrease the balance of an account. Returns the previous balance. This
762    /// is a low-level API, and is not intended for general use.
763    pub fn decrease_balance_unchecked(&mut self, address: Address, amount: U256) -> U256
764    where
765        Db: DatabaseCommit,
766    {
767        self.try_decrease_balance_unchecked(address, amount).expect("infallible")
768    }
769
770    /// Set the balance of an account. Returns the previous balance. This is a
771    /// low-level API, and is not intended for general use.
772    pub fn set_balance_unchecked(&mut self, address: Address, amount: U256) -> U256
773    where
774        Db: DatabaseCommit,
775    {
776        self.try_set_balance_unchecked(address, amount).expect("infallible")
777    }
778}
779
780// Layered inspector
781impl<Db, Outer, Inner, TrevmState> Trevm<Db, Layered<Outer, Inner>, TrevmState>
782where
783    Db: Database,
784    Outer: Inspector<Ctx<Db>>,
785    Inner: Inspector<Ctx<Db>>,
786{
787    /// Remove the outer-layer inspector, leaving the inner-layer inspector in
788    /// place.
789    pub fn take_outer(self) -> (Outer, Trevm<Db, Inner, TrevmState>) {
790        let (outer, inner) = self.inner.inspector.into_parts();
791
792        (
793            outer,
794            Trevm {
795                inner: Box::new(Evm {
796                    ctx: self.inner.ctx,
797                    inspector: inner,
798                    instruction: self.inner.instruction,
799                    precompiles: self.inner.precompiles,
800                    frame_stack: self.inner.frame_stack,
801                }),
802                state: self.state,
803            },
804        )
805    }
806
807    /// Remove the outer-layer inspector, leaving the inner-layer inspector in
808    /// place.
809    pub fn remove_outer(self) -> Trevm<Db, Inner, TrevmState> {
810        self.take_outer().1
811    }
812
813    /// Remove the inner-layer inspector, leaving the outer-layer inspector in
814    /// place.
815    pub fn take_inner(self) -> (Inner, Trevm<Db, Outer, TrevmState>) {
816        let (outer, inner) = self.inner.inspector.into_parts();
817
818        (
819            inner,
820            Trevm {
821                inner: Box::new(Evm {
822                    ctx: self.inner.ctx,
823                    inspector: outer,
824                    instruction: self.inner.instruction,
825                    precompiles: self.inner.precompiles,
826                    frame_stack: self.inner.frame_stack,
827                }),
828                state: self.state,
829            },
830        )
831    }
832
833    /// Remove the inner-layer inspector, leaving the outer-layer inspector in
834    /// place.
835    pub fn remove_inner(self) -> Trevm<Db, Outer, TrevmState> {
836        self.take_inner().1
837    }
838}
839
840// --- ALL STATES, WITH State<Db>
841
842impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
843where
844    Db: Database + StateAcc,
845    Insp: Inspector<Ctx<Db>>,
846{
847    /// Set the [EIP-161] state clear flag, activated in the Spurious Dragon
848    /// hardfork.
849    pub fn set_state_clear_flag(&mut self, flag: bool) {
850        self.inner.db_mut().set_state_clear_flag(flag)
851    }
852}
853
854impl<Db, Insp, TrevmState> Trevm<Db, Insp, TrevmState>
855where
856    Db: Database + TryStateAcc,
857    Insp: Inspector<Ctx<Db>>,
858{
859    /// Fallibly set the [EIP-161] state clear flag, activated in the Spurious
860    /// Dragon hardfork. This function is intended to be used by shared states,
861    /// where mutable access may fail, e.g. an `Arc<Db>`.
862    ///
863    /// Prefer [`Self::set_state_clear_flag`] when available.
864    pub fn try_set_state_clear_flag(
865        &mut self,
866        flag: bool,
867    ) -> Result<(), <Db as TryStateAcc>::Error> {
868        self.inner.db_mut().try_set_state_clear_flag(flag)
869    }
870}
871
872// Some code above and documentation is adapted from the revm crate, and is
873// reproduced here under the terms of the MIT license.
874//
875// MIT License
876//
877// Copyright (c) 2021-2024 draganrakita
878//
879// Permission is hereby granted, free of charge, to any person obtaining a copy
880// of this software and associated documentation files (the "Software"), to deal
881// in the Software without restriction, including without limitation the rights
882// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
883// copies of the Software, and to permit persons to whom the Software is
884// furnished to do so, subject to the following conditions:
885//
886// The above copyright notice and this permission notice shall be included in all
887// copies or substantial portions of the Software.
888//
889// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
890// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
891// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
892// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
893// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
894// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
895// SOFTWARE.
896
897// Some code above is reproduced from `reth`. It is reused here under the MIT
898// license.
899//
900// The MIT License (MIT)
901//
902// Copyright (c) 2022-2024 Reth Contributors
903//
904// Permission is hereby granted, free of charge, to any person obtaining a copy
905// of this software and associated documentation files (the "Software"), to deal
906// in the Software without restriction, including without limitation the rights
907// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
908// copies of the Software, and to permit persons to whom the Software is
909// furnished to do so, subject to the following conditions:
910//
911// The above copyright notice and this permission notice shall be included in
912// all copies or substantial portions of the Software.
913//
914// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
915// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
916// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
917// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
918// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
919// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
920// THE SOFTWARE.