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