Skip to main content

anvil/evm/
optimism.rs

1//! Optimism-specific EVM helpers.
2
3#[cfg(test)]
4mod tests {
5    use std::convert::Infallible;
6
7    use super::super::tests::{
8        CustomPrecompileFactory, ETH_PRAGUE_PRECOMPILE, PAYLOAD, PRECOMPILE_ADDR,
9    };
10    use crate::PrecompileFactory;
11    use alloy_evm::{Evm, EvmEnv, EvmFactory, precompiles::PrecompilesMap};
12    use alloy_op_evm::{OpEvm, OpEvmFactory, OpTx};
13    use alloy_primitives::{Address, TxKind, U256, address};
14    use itertools::Itertools;
15    use op_revm::{OpSpecId, OpTransaction};
16    use revm::{
17        context::{BlockEnv, CfgEnv, TxEnv},
18        database::{EmptyDB, EmptyDBTyped},
19        inspector::NoOpInspector,
20        primitives::hardfork::SpecId,
21    };
22
23    // A precompile activated in the `Isthmus` spec.
24    const OP_ISTHMUS_PRECOMPILE: Address = address!("0x0000000000000000000000000000000000000100");
25
26    /// Creates a new OP EVM instance.
27    fn create_op_evm(
28        _spec: SpecId,
29        op_spec: OpSpecId,
30    ) -> (OpTx, OpEvm<EmptyDBTyped<Infallible>, NoOpInspector, PrecompilesMap, OpTx>) {
31        let tx = OpTx(OpTransaction::<TxEnv> {
32            base: TxEnv {
33                kind: TxKind::Call(PRECOMPILE_ADDR),
34                data: PAYLOAD.into(),
35                ..Default::default()
36            },
37            ..Default::default()
38        });
39
40        let mut evm = OpEvmFactory::<OpTx>::default().create_evm_with_inspector(
41            EmptyDB::default(),
42            EvmEnv::new(CfgEnv::new_with_spec(op_spec), BlockEnv::default()),
43            NoOpInspector,
44        );
45
46        if op_spec == OpSpecId::ISTHMUS {
47            evm.ctx_mut().chain.operator_fee_constant = Some(U256::ZERO);
48            evm.ctx_mut().chain.operator_fee_scalar = Some(U256::ZERO);
49        }
50
51        (tx, evm)
52    }
53
54    #[test]
55    fn build_op_evm_with_extra_precompiles_isthmus_spec() {
56        let (tx, mut evm) = create_op_evm(SpecId::OSAKA, OpSpecId::ISTHMUS);
57
58        assert!(evm.precompiles().addresses().contains(&OP_ISTHMUS_PRECOMPILE));
59        assert!(evm.precompiles().addresses().contains(&ETH_PRAGUE_PRECOMPILE));
60        assert!(!evm.precompiles().addresses().contains(&PRECOMPILE_ADDR));
61
62        evm.precompiles_mut().extend_precompiles(CustomPrecompileFactory.precompiles());
63
64        assert!(evm.precompiles().addresses().contains(&PRECOMPILE_ADDR));
65
66        let result = evm.transact(tx).unwrap();
67        assert!(result.result.is_success());
68        assert_eq!(result.result.output(), Some(&PAYLOAD.into()));
69    }
70
71    #[test]
72    fn build_op_evm_with_extra_precompiles_bedrock_spec() {
73        let (tx, mut evm) = create_op_evm(SpecId::OSAKA, OpSpecId::BEDROCK);
74
75        assert!(!evm.precompiles().addresses().contains(&OP_ISTHMUS_PRECOMPILE));
76        assert!(!evm.precompiles().addresses().contains(&ETH_PRAGUE_PRECOMPILE));
77        assert!(!evm.precompiles().addresses().contains(&PRECOMPILE_ADDR));
78
79        evm.precompiles_mut().extend_precompiles(CustomPrecompileFactory.precompiles());
80
81        assert!(evm.precompiles().addresses().contains(&PRECOMPILE_ADDR));
82
83        let result = evm.transact(tx).unwrap();
84        assert!(result.result.is_success());
85        assert_eq!(result.result.output(), Some(&PAYLOAD.into()));
86    }
87}