Skip to main content

anvil/eth/backend/mem/
optimism.rs

1//! Optimism-specific transact helpers for the in-memory backend.
2
3use super::Backend;
4use crate::eth::error::BlockchainError;
5use alloy_evm::{Database, Evm, EvmEnv, EvmFactory};
6use alloy_network::Network;
7use alloy_op_evm::{OpEvmContext, OpEvmFactory, OpTx};
8use foundry_evm::backend::DatabaseError;
9use op_revm::{OpHaltReason, OpTransaction};
10use revm::{
11    DatabaseRef, Inspector,
12    context::{
13        TxEnv,
14        result::{EVMError, HaltReason, ResultAndState},
15    },
16    database_interface::WrapDatabaseRef,
17};
18
19impl<N: Network> Backend<N> {
20    /// Optimism path of [`Backend::transact_with_inspector_ref`].
21    ///
22    /// Creates an OP EVM, injects precompiles, transacts, and maps the
23    /// OP-specific halt reason back to the shared [`HaltReason`].
24    pub(super) fn transact_op_with_inspector_ref<'db, I, DB>(
25        &self,
26        db: &'db DB,
27        evm_env: &EvmEnv,
28        inspector: &mut I,
29        tx_env: OpTransaction<TxEnv>,
30    ) -> Result<ResultAndState<HaltReason>, BlockchainError>
31    where
32        DB: DatabaseRef + ?Sized,
33        I: Inspector<OpEvmContext<WrapDatabaseRef<&'db DB>>>,
34        WrapDatabaseRef<&'db DB>: Database<Error = DatabaseError>,
35    {
36        let op_env = EvmEnv::new(
37            evm_env.cfg_env.clone().with_spec_and_mainnet_gas_params(self.hardfork().into()),
38            evm_env.block_env.clone(),
39        );
40        let mut evm = OpEvmFactory::default().create_evm_with_inspector(
41            WrapDatabaseRef(db),
42            op_env,
43            inspector,
44        );
45        self.inject_precompiles(evm.precompiles_mut());
46        let result = evm.transact(OpTx(tx_env)).map_err(|e| match e {
47            EVMError::Database(db) => EVMError::Database(db),
48            EVMError::Header(h) => EVMError::Header(h),
49            EVMError::Custom(s) => EVMError::Custom(s),
50            EVMError::CustomAny(err) => EVMError::CustomAny(err),
51            EVMError::Transaction(t) => EVMError::Transaction(t),
52        })?;
53        Ok(ResultAndState {
54            result: result.result.map_haltreason(|h| match h {
55                OpHaltReason::Base(eth) => eth,
56                _ => HaltReason::PrecompileError,
57            }),
58            state: result.state,
59        })
60    }
61}