diff --git a/src/driver/alloy.rs b/src/driver/alloy.rs index a6f579c..ddf8011 100644 --- a/src/driver/alloy.rs +++ b/src/driver/alloy.rs @@ -11,10 +11,13 @@ use alloy::{ EthSendBundle, }, }; -use revm::primitives::{EVMError, ExecutionResult, SpecId}; +use revm::{ + primitives::{EVMError, ExecutionResult, SpecId}, + Database, DatabaseCommit, +}; /// Possible errors that can occur while driving a bundle. -pub enum BundleError { +pub enum BundleError { /// The block number of the bundle does not match the block number of the revm block configuration. BlockNumberMismatch, /// The timestamp of the bundle is out of range. @@ -38,7 +41,7 @@ pub enum BundleError { }, } -impl core::fmt::Display for BundleError { +impl core::fmt::Display for BundleError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::BlockNumberMismatch => { @@ -58,25 +61,25 @@ impl core::fmt::Display for BundleError { } } -impl From for BundleError { +impl From for BundleError { fn from(err: alloy::eips::eip2718::Eip2718Error) -> Self { Self::TransactionDecodingError(err) } } -impl From for BundleError { +impl From for BundleError { fn from(err: alloy::primitives::SignatureError) -> Self { Self::TransactionSenderRecoveryError(err) } } -impl From> for BundleError { +impl From> for BundleError { fn from(inner: EVMError) -> Self { Self::EVMError { inner } } } -impl std::error::Error for BundleError { +impl std::error::Error for BundleError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Self::TransactionDecodingError(err) => Some(err), @@ -86,7 +89,7 @@ impl std::error::Error for BundleError { } } -impl core::fmt::Debug for BundleError { +impl core::fmt::Debug for BundleError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::TimestampOutOfRange => write!(f, "TimestampOutOfRange"), @@ -141,7 +144,7 @@ where impl BundleProcessor { /// Decode and validate the transactions in the bundle, performing EIP4844 gas checks. - pub fn decode_and_validate_txs( + pub fn decode_and_validate_txs( txs: &[Bytes], ) -> Result, BundleError> { let txs = txs @@ -175,7 +178,7 @@ impl BundleProcessor { } /// Process a bundle transaction and accumulate the results into a [EthCallBundleTransactionResult]. - pub fn process_call_bundle_tx( + pub fn process_call_bundle_tx( tx: &TxEnvelope, pre_sim_coinbase_balance: U256, post_sim_coinbase_balance: U256, @@ -257,9 +260,9 @@ impl BundleProcessor { } impl BundleDriver for BundleProcessor { - type Error = BundleError; + type Error = BundleError; - fn run_bundle<'a, Db: revm::Database + revm::DatabaseCommit>( + fn run_bundle<'a, Db: Database + revm::DatabaseCommit>( &mut self, trevm: crate::EvmNeedsTx<'a, Ext, Db>, ) -> DriveBundleResult<'a, Ext, Db, Self> { @@ -389,7 +392,7 @@ impl BundleDriver for BundleProcessor( + fn post_bundle( &mut self, _trevm: &crate::EvmNeedsTx<'_, Ext, Db>, ) -> Result<(), Self::Error> { @@ -398,9 +401,9 @@ impl BundleDriver for BundleProcessor BundleDriver for BundleProcessor { - type Error = BundleError; + type Error = BundleError; - fn run_bundle<'a, Db: revm::Database + revm::DatabaseCommit>( + fn run_bundle<'a, Db: Database + revm::DatabaseCommit>( &mut self, trevm: crate::EvmNeedsTx<'a, Ext, Db>, ) -> DriveBundleResult<'a, Ext, Db, Self> { @@ -476,7 +479,7 @@ impl BundleDriver for BundleProcessor { } } - fn post_bundle( + fn post_bundle( &mut self, _trevm: &crate::EvmNeedsTx<'_, Ext, Db>, ) -> Result<(), Self::Error> { @@ -541,9 +544,9 @@ impl From for BundleBlockFiller { } impl BundleDriver for EthCallBundle { - type Error = BundleError; + type Error = BundleError; - fn run_bundle<'a, Db: revm::Database + revm::DatabaseCommit>( + fn run_bundle<'a, Db: Database + revm::DatabaseCommit>( &mut self, trevm: crate::EvmNeedsTx<'a, Ext, Db>, ) -> DriveBundleResult<'a, Ext, Db, Self> { @@ -619,7 +622,7 @@ impl BundleDriver for EthCallBundle { } } - fn post_bundle( + fn post_bundle( &mut self, _trevm: &crate::EvmNeedsTx<'_, Ext, Db>, ) -> Result<(), Self::Error> { @@ -631,9 +634,9 @@ impl BundleDriver for EthCallBundle { /// This allows us to drive a bundle of transactions and accumulate the resulting state in the EVM. /// Allows to simply take an [EthSendBundle] and get the resulting EVM state. impl BundleDriver for EthSendBundle { - type Error = BundleError; + type Error = BundleError; - fn run_bundle<'a, Db: revm::Database + revm::DatabaseCommit>( + fn run_bundle<'a, Db: Database + revm::DatabaseCommit>( &mut self, trevm: crate::EvmNeedsTx<'a, Ext, Db>, ) -> DriveBundleResult<'a, Ext, Db, Self> { @@ -724,7 +727,7 @@ impl BundleDriver for EthSendBundle { Ok(t) } - fn post_bundle( + fn post_bundle( &mut self, _trevm: &crate::EvmNeedsTx<'_, Ext, Db>, ) -> Result<(), Self::Error> { diff --git a/src/driver/block.rs b/src/driver/block.rs index c0e7320..fcab7a0 100644 --- a/src/driver/block.rs +++ b/src/driver/block.rs @@ -1,5 +1,5 @@ use crate::{Block, EvmBlockDriverErrored, EvmNeedsBlock, EvmNeedsTx}; -use revm::{primitives::EVMError, Database}; +use revm::{primitives::EVMError, Database, DatabaseCommit}; /// The result of running transactions for a block driver. pub type RunTxResult<'a, Ext, Db, T> = @@ -17,19 +17,19 @@ pub trait BlockDriver { type Block: Block; /// An error type for this driver. - type Error: core::error::Error + From>; + type Error: core::error::Error + From>; /// Get a reference to the block filler for this driver. fn block(&self) -> &Self::Block; /// Run the transactions for the block. - fn run_txns<'a, Db: Database>( + fn run_txns<'a, Db: Database + DatabaseCommit>( &mut self, trevm: EvmNeedsTx<'a, Ext, Db>, ) -> RunTxResult<'a, Ext, Db, Self>; /// Run post - fn post_block( + fn post_block( &mut self, trevm: &EvmNeedsBlock<'_, Ext, Db>, ) -> Result<(), Self::Error>; diff --git a/src/driver/bundle.rs b/src/driver/bundle.rs index 3350c5a..4d9026e 100644 --- a/src/driver/bundle.rs +++ b/src/driver/bundle.rs @@ -9,7 +9,7 @@ pub type DriveBundleResult<'a, Ext, Db, T> = /// entire lifecycle of a bundle, simulating the entire list of transactions. pub trait BundleDriver { /// An error type for this driver. - type Error: core::error::Error + From>; + type Error: core::error::Error + From>; /// Run the transactions contained in the bundle. fn run_bundle<'a, Db: Database + DatabaseCommit>( diff --git a/src/driver/chain.rs b/src/driver/chain.rs index cba5399..c3d53e9 100644 --- a/src/driver/chain.rs +++ b/src/driver/chain.rs @@ -14,7 +14,7 @@ pub trait ChainDriver { type BlockDriver: BlockDriver; /// An error type for this driver. - type Error: core::error::Error + type Error: core::error::Error + From> + From<>::Error>; diff --git a/src/evm.rs b/src/evm.rs index d4c7dba..32beb9b 100644 --- a/src/evm.rs +++ b/src/evm.rs @@ -61,11 +61,24 @@ impl<'a, Ext, Db: Database, TrevmState> Trevm<'a, Ext, Db, TrevmState> { &mut self.inner } - /// Destructure the [`Trevm`] into its parts. + /// Destructure the [`Trevm`] into its inner EVM. pub fn into_inner(self) -> Box> { self.inner } + /// Deconstruct the [`Trevm`] into the backing DB, dropping the EVM handler + /// table and any `Ext` type. + /// + /// This is a wrapper for [`Evm::into_db_and_env_with_handler_cfg`], and + /// then dropping the [`EnvWithHandlerCfg`]. If you need to retain the + /// [`EnvWithHandlerCfg`], use [`Self::into_inner`] and then call + /// [`Evm::into_db_and_env_with_handler_cfg`] on the inner EVM. + /// + /// [`EnvWithHandlerCfg`]: revm::primitives::EnvWithHandlerCfg + pub fn into_db(self) -> Db { + self.inner.into_db_and_env_with_handler_cfg().0 + } + /// Get a reference to the inner env. This contains the current /// [`BlockEnv`], [`TxEnv`], and [`CfgEnv`]. /// @@ -125,45 +138,6 @@ impl<'a, Ext, Db: Database, TrevmState> Trevm<'a, Ext, Db, TrevmState> { EvmErrored { inner: self.inner, state: ErroredState { error } } } - /// Get the current account info for a specific address. - /// - /// Note: due to revm's DB model, this requires a mutable pointer. - pub fn try_read_account(&mut self, address: Address) -> Result, Db::Error> { - self.inner.db_mut().basic(address) - } - - /// Get the current nonce for a specific address - /// - /// Note: due to revm's DB model, this requires a mutable pointer. - pub fn try_read_nonce(&mut self, address: Address) -> Result { - self.try_read_account(address).map(|a| a.map(|a| a.nonce).unwrap_or_default()) - } - - /// Get the current nonce for a specific address - /// - /// Note: due to revm's DB model, this requires a mutable pointer. - pub fn try_read_balance(&mut self, address: Address) -> Result { - self.try_read_account(address).map(|a| a.map(|a| a.balance).unwrap_or_default()) - } - - /// Get the value of a storage slot. - /// - /// Note: due to revm's DB model, this requires a mutable pointer. - pub fn try_read_storage(&mut self, address: Address, slot: U256) -> Result { - self.inner.db_mut().storage(address, slot) - } - - /// Get the code at the given account, if any. - /// - /// Note: due to revm's DB model, this requires a mutable pointer. - pub fn try_read_code(&mut self, address: Address) -> Result, Db::Error> { - let acct_info = self.try_read_account(address)?; - match acct_info { - Some(acct) => Ok(Some(self.inner.db_mut().code_by_hash(acct.code_hash)?)), - None => Ok(None), - } - } - /// Apply [`StateOverride`]s to the current state. Errors if the overrides /// contain invalid bytecode. pub fn apply_state_overrides( @@ -218,6 +192,48 @@ impl<'a, Ext, Db: Database, TrevmState> Trevm<'a, Ext, Db, TrevmState> { Ok(self) } } +} + +// Fallible DB Reads with &mut self +impl Trevm<'_, Ext, Db, TrevmState> { + /// Get the current account info for a specific address. + /// + /// Note: due to revm's DB model, this requires a mutable pointer. + pub fn try_read_account(&mut self, address: Address) -> Result, Db::Error> { + self.inner.db_mut().basic(address) + } + + /// Get the current nonce for a specific address + /// + /// Note: due to revm's DB model, this requires a mutable pointer. + pub fn try_read_nonce(&mut self, address: Address) -> Result { + self.try_read_account(address).map(|a| a.map(|a| a.nonce).unwrap_or_default()) + } + + /// Get the current nonce for a specific address + /// + /// Note: due to revm's DB model, this requires a mutable pointer. + pub fn try_read_balance(&mut self, address: Address) -> Result { + self.try_read_account(address).map(|a| a.map(|a| a.balance).unwrap_or_default()) + } + + /// Get the value of a storage slot. + /// + /// Note: due to revm's DB model, this requires a mutable pointer. + pub fn try_read_storage(&mut self, address: Address, slot: U256) -> Result { + self.inner.db_mut().storage(address, slot) + } + + /// Get the code at the given account, if any. + /// + /// Note: due to revm's DB model, this requires a mutable pointer. + pub fn try_read_code(&mut self, address: Address) -> Result, Db::Error> { + let acct_info = self.try_read_account(address)?; + match acct_info { + Some(acct) => Ok(Some(self.inner.db_mut().code_by_hash(acct.code_hash)?)), + None => Ok(None), + } + } /// Get the gas allowance for a specific caller and gas price. pub fn try_gas_allowance( @@ -234,6 +250,7 @@ impl<'a, Ext, Db: Database, TrevmState> Trevm<'a, Ext, Db, TrevmState> { } } +// Fallible DB Reads with &self impl Trevm<'_, Ext, Db, TrevmState> { /// Get the current account info for a specific address. pub fn try_read_account_ref( @@ -296,6 +313,7 @@ impl Trevm<'_, Ext, Db, TrevmState> } } +// Infallible DB Reads with &mut self impl, TrevmState> Trevm<'_, Ext, Db, TrevmState> { /// Get the current account info for a specific address. /// @@ -334,6 +352,7 @@ impl, TrevmState> Trevm<'_, Ext, Db, Trevm } } +// Infalible DB Reads with &self impl + DatabaseRef, TrevmState> Trevm<'_, Ext, Db, TrevmState> {