Skip to main content

anvil/eth/backend/mem/
optimism.rs

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