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::{instructions::EthInstructions, EthFrame, EvmTr, Handler, PrecompileProvider},
12 inspector::{InspectCommitEvm, InspectEvm, Inspector, InspectorHandler, JournalExt},
13 interpreter::{interpreter::EthInterpreter, InterpreterResult},
14 DatabaseCommit, ExecuteCommitEvm, ExecuteEvm,
15};
16
17pub trait OpContextTr:
19 ContextTr<
20 Journal: JournalTr<FinalOutput = JournalOutput>,
21 Tx: OpTxTr,
22 Cfg: Cfg<Spec = OpSpecId>,
23 Chain = L1BlockInfo,
24>
25{
26}
27
28impl<T> OpContextTr for T where
29 T: ContextTr<
30 Journal: JournalTr<FinalOutput = JournalOutput>,
31 Tx: OpTxTr,
32 Cfg: Cfg<Spec = OpSpecId>,
33 Chain = L1BlockInfo,
34 >
35{
36}
37
38type OpError<CTX> = EVMError<<<CTX as ContextTr>::Db as Database>::Error, OpTransactionError>;
40
41impl<CTX, INSP, PRECOMPILE> ExecuteEvm
42 for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
43where
44 CTX: OpContextTr + ContextSetters,
45 PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
46{
47 type Output = Result<ResultAndState<OpHaltReason>, OpError<CTX>>;
48
49 type Tx = <CTX as ContextTr>::Tx;
50
51 type Block = <CTX as ContextTr>::Block;
52
53 fn set_tx(&mut self, tx: Self::Tx) {
54 self.0.data.ctx.set_tx(tx);
55 }
56
57 fn set_block(&mut self, block: Self::Block) {
58 self.0.data.ctx.set_block(block);
59 }
60
61 fn replay(&mut self) -> Self::Output {
62 let mut h = OpHandler::<_, _, EthFrame<_, _, _>>::new();
63 h.run(self)
64 }
65}
66
67impl<CTX, INSP, PRECOMPILE> ExecuteCommitEvm
68 for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
69where
70 CTX: OpContextTr<Db: DatabaseCommit> + ContextSetters,
71 PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
72{
73 type CommitOutput = Result<ExecutionResult<OpHaltReason>, OpError<CTX>>;
74
75 fn replay_commit(&mut self) -> Self::CommitOutput {
76 self.replay().map(|r| {
77 self.ctx().db().commit(r.state);
78 r.result
79 })
80 }
81}
82
83impl<CTX, INSP, PRECOMPILE> InspectEvm
84 for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
85where
86 CTX: OpContextTr<Journal: JournalExt> + ContextSetters,
87 INSP: Inspector<CTX, EthInterpreter>,
88 PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
89{
90 type Inspector = INSP;
91
92 fn set_inspector(&mut self, inspector: Self::Inspector) {
93 self.0.data.inspector = inspector;
94 }
95
96 fn inspect_replay(&mut self) -> Self::Output {
97 let mut h = OpHandler::<_, _, EthFrame<_, _, _>>::new();
98 h.inspect_run(self)
99 }
100}
101
102impl<CTX, INSP, PRECOMPILE> InspectCommitEvm
103 for OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, PRECOMPILE>
104where
105 CTX: OpContextTr<Journal: JournalExt, Db: DatabaseCommit> + ContextSetters,
106 INSP: Inspector<CTX, EthInterpreter>,
107 PRECOMPILE: PrecompileProvider<CTX, Output = InterpreterResult>,
108{
109 fn inspect_replay_commit(&mut self) -> Self::CommitOutput {
110 self.inspect_replay().map(|r| {
111 self.ctx().db().commit(r.state);
112 r.result
113 })
114 }
115}