|
1 | 1 | use crate::{ |
2 | 2 | states::EvmBlockComplete, BasicContext, Block, BlockComplete, BlockContext, Cfg, ErroredState, |
3 | 3 | EvmErrored, EvmExtUnchecked, EvmNeedsCfg, EvmNeedsFirstBlock, EvmNeedsNextBlock, EvmNeedsTx, |
4 | | - EvmReady, EvmTransacted, HasCfg, HasContext, HasOutputs, NeedsBlock, NeedsCfg, NeedsNextBlock, |
5 | | - NeedsTx, Ready, TransactedState, Tx, |
| 4 | + EvmReady, EvmTransacted, HasBlock, HasCfg, HasContext, HasOutputs, HasTx, NeedsBlock, NeedsCfg, |
| 5 | + NeedsNextBlock, NeedsTx, Ready, TransactedState, Tx, |
6 | 6 | }; |
7 | 7 | use alloy_primitives::{Address, Bytes, U256}; |
8 | 8 | use revm::{ |
@@ -481,6 +481,22 @@ impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState: HasCfg> Trevm<'a, Ext, |
481 | 481 | self.set_code_size_limit(0x6000) |
482 | 482 | } |
483 | 483 |
|
| 484 | + /// Run a function with the provided configuration, then restore the |
| 485 | + /// previous configuration. This will not affect the block and tx, if those |
| 486 | + /// have been filled. |
| 487 | + pub fn with_cfg<F, C, NewState>(mut self, f: F, cfg: &C) -> Trevm<'a, Ext, Db, NewState> |
| 488 | + where |
| 489 | + F: FnOnce(Self) -> Trevm<'a, Ext, Db, NewState>, |
| 490 | + C: Cfg, |
| 491 | + NewState: HasCfg, |
| 492 | + { |
| 493 | + let previous = std::mem::take(self.inner.cfg_mut()); |
| 494 | + cfg.fill_cfg_env(self.inner.cfg_mut()); |
| 495 | + let mut this = f(self); |
| 496 | + *this.inner.cfg_mut() = previous; |
| 497 | + this |
| 498 | + } |
| 499 | + |
484 | 500 | /// Set the KZG settings used for point evaluation precompiles. By default |
485 | 501 | /// this is set to the settings used in the Ethereum mainnet. |
486 | 502 | /// |
@@ -742,6 +758,24 @@ impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState: NeedsBlock> |
742 | 758 | } |
743 | 759 | } |
744 | 760 |
|
| 761 | +// --- HAS BLOCK |
| 762 | + |
| 763 | +impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState: HasBlock> Trevm<'a, Ext, Db, TrevmState> { |
| 764 | + /// Run a function with the provided block, then restore the previous block. |
| 765 | + pub fn with_block<F, B, NewState>(mut self, f: F, b: &B) -> Trevm<'a, Ext, Db, NewState> |
| 766 | + where |
| 767 | + F: FnOnce(Self) -> Trevm<'a, Ext, Db, NewState>, |
| 768 | + B: Block, |
| 769 | + NewState: HasBlock, |
| 770 | + { |
| 771 | + let previous = std::mem::take(self.inner.block_mut()); |
| 772 | + b.fill_block_env(self.inner.block_mut()); |
| 773 | + let mut this = f(self); |
| 774 | + *this.inner.block_mut() = previous; |
| 775 | + this |
| 776 | + } |
| 777 | +} |
| 778 | + |
745 | 779 | // --- HAS OUTPUTS |
746 | 780 |
|
747 | 781 | impl<'a, Ext, Db: Database + DatabaseCommit, Missing: HasOutputs> |
@@ -811,7 +845,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState: HasContext> |
811 | 845 | } |
812 | 846 | } |
813 | 847 |
|
814 | | -// --- NEEDS FIRST TX |
| 848 | +// --- NEEDS TX |
815 | 849 |
|
816 | 850 | impl<'a, Ext, Db: Database + DatabaseCommit, C: BlockContext<Ext, Db>> EvmNeedsTx<'a, Ext, Db, C> { |
817 | 851 | /// Close the current block, applying some logic, and returning the EVM |
@@ -860,6 +894,25 @@ impl<'a, Ext, Db: Database + DatabaseCommit, C: BlockContext<Ext, Db>> EvmNeedsT |
860 | 894 | } |
861 | 895 | } |
862 | 896 |
|
| 897 | +// --- HAS TX |
| 898 | + |
| 899 | +impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState: HasTx> Trevm<'a, Ext, Db, TrevmState> { |
| 900 | + /// Run a function with the provided transaction, then restore the previous |
| 901 | + /// transaction. |
| 902 | + pub fn with_tx<F, T, NewState>(mut self, f: F, t: &T) -> Trevm<'a, Ext, Db, NewState> |
| 903 | + where |
| 904 | + F: FnOnce(Self) -> Trevm<'a, Ext, Db, NewState>, |
| 905 | + T: Tx, |
| 906 | + NewState: HasTx, |
| 907 | + { |
| 908 | + let previous = std::mem::take(self.inner.tx_mut()); |
| 909 | + t.fill_tx_env(self.inner.tx_mut()); |
| 910 | + let mut this = f(self); |
| 911 | + *this.inner.tx_mut() = previous; |
| 912 | + this |
| 913 | + } |
| 914 | +} |
| 915 | + |
863 | 916 | // --- READY |
864 | 917 |
|
865 | 918 | impl<'a, Ext, Db: Database + DatabaseCommit, C: BlockContext<Ext, Db>> EvmReady<'a, Ext, Db, C> { |
|
0 commit comments