op_revm/api/
exec.rs

1//! Implementation of the [`ExecuteEvm`] trait for the [`OpEvm`].
2use crate::{
3    evm::OpEvm, handler::OpHandler, transaction::OpTxTr, L1BlockInfo, OpHaltReason, OpSpecId,
4    OpTransactionError,
5};
6use revm::{
7    context::{result::ExecResultAndState, ContextSetters},
8    context_interface::{
9        result::{EVMError, ExecutionResult},
10        Cfg, ContextTr, Database, JournalTr,
11    },
12    handler::{
13        instructions::EthInstructions, system_call::SystemCallEvm, EthFrame, Handler,
14        PrecompileProvider, SystemCallTx,
15    },
16    inspector::{
17        InspectCommitEvm, InspectEvm, InspectSystemCallEvm, Inspector, InspectorHandler, JournalExt,
18    },
19    interpreter::{interpreter::EthInterpreter, InterpreterResult},
20    primitives::{Address, Bytes},
21    state::EvmState,
22    DatabaseCommit, ExecuteCommitEvm, ExecuteEvm,
23};
24
25/// Type alias for Optimism context
26pub trait OpContextTr:
27    ContextTr<
28    Journal: JournalTr<State = EvmState>,
29    Tx: OpTxTr,
30    Cfg: Cfg<Spec = OpSpecId>,
31    Chain = L1BlockInfo,
32>
33{
34}
35
36impl<T> OpContextTr for T where
37    T: ContextTr<
38        Journal: JournalTr<State = EvmState>,
39        Tx: OpTxTr,
40        Cfg: Cfg<Spec = OpSpecId>,
41        Chain = L1BlockInfo,
42    >
43{
44}
45
46/// Type alias for the error type of the OpEvm.
47pub type OpError<CTX> = EVMError<<<CTX as ContextTr>::Db as Database>::Error, OpTransactionError>;
48
49impl<CTX, INSP, PRECOMPILE> ExecuteEvm
50    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
51where
52    CTX: OpContextTr + ContextSetters,
53    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
54{
55    type Tx = <CTX as ContextTr>::Tx;
56    type Block = <CTX as ContextTr>::Block;
57    type State = EvmState;
58    type Error = OpError<CTX>;
59    type ExecutionResult = ExecutionResult<OpHaltReason>;
60
61    fn set_block(&mut self, block: Self::Block) {
62        self.0.ctx.set_block(block);
63    }
64
65    fn transact_one(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
66        self.0.ctx.set_tx(tx);
67        let mut h = OpHandler::<_, _, EthFrame<EthInterpreter>>::new();
68        h.run(self)
69    }
70
71    fn finalize(&mut self) -> Self::State {
72        self.0.ctx.journal_mut().finalize()
73    }
74
75    fn replay(
76        &mut self,
77    ) -> Result<ExecResultAndState<Self::ExecutionResult, Self::State>, Self::Error> {
78        let mut h = OpHandler::<_, _, EthFrame<EthInterpreter>>::new();
79        h.run(self).map(|result| {
80            let state = self.finalize();
81            ExecResultAndState::new(result, state)
82        })
83    }
84}
85
86impl<CTX, INSP, PRECOMPILE> ExecuteCommitEvm
87    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
88where
89    CTX: OpContextTr<Db: DatabaseCommit> + ContextSetters,
90    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
91{
92    fn commit(&mut self, state: Self::State) {
93        self.0.ctx.db_mut().commit(state);
94    }
95}
96
97impl<CTX, INSP, PRECOMPILE> InspectEvm
98    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
99where
100    CTX: OpContextTr<Journal: JournalExt> + ContextSetters,
101    INSP: Inspector<CTX, EthInterpreter>,
102    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
103{
104    type Inspector = INSP;
105
106    fn set_inspector(&mut self, inspector: Self::Inspector) {
107        self.0.inspector = inspector;
108    }
109
110    fn inspect_one_tx(&mut self, tx: Self::Tx) -> Result<Self::ExecutionResult, Self::Error> {
111        self.0.ctx.set_tx(tx);
112        let mut h = OpHandler::<_, _, EthFrame<EthInterpreter>>::new();
113        h.inspect_run(self)
114    }
115}
116
117impl<CTX, INSP, PRECOMPILE> InspectCommitEvm
118    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
119where
120    CTX: OpContextTr<Journal: JournalExt, Db: DatabaseCommit> + ContextSetters,
121    INSP: Inspector<CTX, EthInterpreter>,
122    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
123{
124}
125
126impl<CTX, INSP, PRECOMPILE> SystemCallEvm
127    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
128where
129    CTX: OpContextTr<Tx: SystemCallTx> + ContextSetters,
130    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
131{
132    fn system_call_one_with_caller(
133        &mut self,
134        caller: Address,
135        system_contract_address: Address,
136        data: Bytes,
137    ) -> Result<Self::ExecutionResult, Self::Error> {
138        self.0.ctx.set_tx(CTX::Tx::new_system_tx_with_caller(
139            caller,
140            system_contract_address,
141            data,
142        ));
143        let mut h = OpHandler::<_, _, EthFrame<EthInterpreter>>::new();
144        h.run_system_call(self)
145    }
146}
147
148impl<CTX, INSP, PRECOMPILE> InspectSystemCallEvm
149    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
150where
151    CTX: OpContextTr<Journal: JournalExt, Tx: SystemCallTx> + ContextSetters,
152    INSP: Inspector<CTX, EthInterpreter>,
153    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
154{
155    fn inspect_one_system_call_with_caller(
156        &mut self,
157        caller: Address,
158        system_contract_address: Address,
159        data: Bytes,
160    ) -> Result<Self::ExecutionResult, Self::Error> {
161        self.0.ctx.set_tx(CTX::Tx::new_system_tx_with_caller(
162            caller,
163            system_contract_address,
164            data,
165        ));
166        let mut h = OpHandler::<_, _, EthFrame<EthInterpreter>>::new();
167        h.inspect_run_system_call(self)
168    }
169}