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
21pub 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
42type 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}