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
20pub 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
41type 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}