op_revm/api/
exec.rs

1use crate::{
2    evm::OpEvm, handler::OpHandler, transaction::OpTxTr, L1BlockInfo, OpHaltReason, OpSpecId,
3    OpTransactionError,
4};
5use revm::{
6    context::{ContextSetters, JournalOutput},
7    context_interface::{
8        result::{EVMError, ExecutionResult, ResultAndState},
9        Cfg, ContextTr, Database, JournalTr,
10    },
11    handler::{
12        instructions::EthInstructions, system_call::SystemCallEvm, EthFrame, EvmTr, Handler,
13        PrecompileProvider, SystemCallTx,
14    },
15    inspector::{InspectCommitEvm, InspectEvm, Inspector, InspectorHandler, JournalExt},
16    interpreter::{interpreter::EthInterpreter, InterpreterResult},
17    DatabaseCommit, ExecuteCommitEvm, ExecuteEvm,
18};
19
20// Type alias for Optimism context
21pub trait OpContextTr:
22    ContextTr<
23    Journal: JournalTr<FinalOutput = JournalOutput>,
24    Tx: OpTxTr,
25    Cfg: Cfg<Spec = OpSpecId>,
26    Chain = L1BlockInfo,
27>
28{
29}
30
31impl<T> OpContextTr for T where
32    T: ContextTr<
33        Journal: JournalTr<FinalOutput = JournalOutput>,
34        Tx: OpTxTr,
35        Cfg: Cfg<Spec = OpSpecId>,
36        Chain = L1BlockInfo,
37    >
38{
39}
40
41/// Type alias for the error type of the OpEvm.
42type OpError<CTX> = EVMError<<<CTX as ContextTr>::Db as Database>::Error, OpTransactionError>;
43
44impl<CTX, INSP, PRECOMPILE> ExecuteEvm
45    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
46where
47    CTX: OpContextTr + ContextSetters,
48    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
49{
50    type Output = Result<ResultAndState<OpHaltReason>, OpError<CTX>>;
51
52    type Tx = <CTX as ContextTr>::Tx;
53
54    type Block = <CTX as ContextTr>::Block;
55
56    fn set_tx(&mut self, tx: Self::Tx) {
57        self.0.ctx.set_tx(tx);
58    }
59
60    fn set_block(&mut self, block: Self::Block) {
61        self.0.ctx.set_block(block);
62    }
63
64    fn replay(&mut self) -> Self::Output {
65        let mut h = OpHandler::<_, _, EthFrame<_, _, _>>::new();
66        h.run(self)
67    }
68}
69
70impl<CTX, INSP, PRECOMPILE> ExecuteCommitEvm
71    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
72where
73    CTX: OpContextTr<Db: DatabaseCommit> + ContextSetters,
74    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
75{
76    type CommitOutput = Result<ExecutionResult<OpHaltReason>, OpError<CTX>>;
77
78    fn replay_commit(&mut self) -> Self::CommitOutput {
79        self.replay().map(|r| {
80            self.ctx().db().commit(r.state);
81            r.result
82        })
83    }
84}
85
86impl<CTX, INSP, PRECOMPILE> InspectEvm
87    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
88where
89    CTX: OpContextTr<Journal: JournalExt> + ContextSetters,
90    INSP: Inspector<CTX, EthInterpreter>,
91    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
92{
93    type Inspector = INSP;
94
95    fn set_inspector(&mut self, inspector: Self::Inspector) {
96        self.0.inspector = inspector;
97    }
98
99    fn inspect_replay(&mut self) -> Self::Output {
100        let mut h = OpHandler::<_, _, EthFrame<_, _, _>>::new();
101        h.inspect_run(self)
102    }
103}
104
105impl<CTX, INSP, PRECOMPILE> InspectCommitEvm
106    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
107where
108    CTX: OpContextTr<Journal: JournalExt, Db: DatabaseCommit> + ContextSetters,
109    INSP: Inspector<CTX, EthInterpreter>,
110    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
111{
112    fn inspect_replay_commit(&mut self) -> Self::CommitOutput {
113        self.inspect_replay().map(|r| {
114            self.ctx().db().commit(r.state);
115            r.result
116        })
117    }
118}
119
120impl<CTX, INSP, PRECOMPILE> SystemCallEvm
121    for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
122where
123    CTX: OpContextTr<Tx: SystemCallTx> + ContextSetters,
124    PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
125{
126    fn transact_system_call(
127        &mut self,
128        data: revm::primitives::Bytes,
129        system_contract_address: revm::primitives::Address,
130    ) -> Self::Output {
131        self.set_tx(CTX::Tx::new_system_tx(data, system_contract_address));
132        let mut h = OpHandler::<_, _, EthFrame<_, _, _>>::new();
133        h.run_system_call(self)
134    }
135}