op_revm/
evm.rs

1//! Contains the `[OpEvm]` type and its implementation of the execution EVM traits.
2use crate::precompiles::OpPrecompiles;
3use revm::{
4    context::{ContextError, ContextSetters, Evm, FrameStack},
5    context_interface::ContextTr,
6    handler::{
7        evm::FrameTr,
8        instructions::{EthInstructions, InstructionProvider},
9        EthFrame, EvmTr, FrameInitOrResult, ItemOrResult, PrecompileProvider,
10    },
11    inspector::{InspectorEvmTr, JournalExt},
12    interpreter::{interpreter::EthInterpreter, InterpreterResult},
13    Database, Inspector,
14};
15
16/// Optimism EVM extends the [`Evm`] type with Optimism specific types and logic.
17#[derive(Debug, Clone)]
18pub struct OpEvm<
19    CTX,
20    INSP,
21    I = EthInstructions<EthInterpreter, CTX>,
22    P = OpPrecompiles,
23    F = EthFrame<EthInterpreter>,
24>(
25    /// Inner EVM type.
26    pub Evm<CTX, INSP, I, P, F>,
27);
28
29impl<CTX: ContextTr, INSP> OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, OpPrecompiles> {
30    /// Create a new Optimism EVM.
31    pub fn new(ctx: CTX, inspector: INSP) -> Self {
32        Self(Evm {
33            ctx,
34            inspector,
35            instruction: EthInstructions::new_mainnet(),
36            precompiles: OpPrecompiles::default(),
37            frame_stack: FrameStack::new(),
38        })
39    }
40}
41
42impl<CTX, INSP, I, P> OpEvm<CTX, INSP, I, P> {
43    /// Consumed self and returns a new Evm type with given Inspector.
44    pub fn with_inspector<OINSP>(self, inspector: OINSP) -> OpEvm<CTX, OINSP, I, P> {
45        OpEvm(self.0.with_inspector(inspector))
46    }
47
48    /// Consumes self and returns a new Evm type with given Precompiles.
49    pub fn with_precompiles<OP>(self, precompiles: OP) -> OpEvm<CTX, INSP, I, OP> {
50        OpEvm(self.0.with_precompiles(precompiles))
51    }
52
53    /// Consumes self and returns the inner Inspector.
54    pub fn into_inspector(self) -> INSP {
55        self.0.into_inspector()
56    }
57}
58
59impl<CTX, INSP, I, P> InspectorEvmTr for OpEvm<CTX, INSP, I, P>
60where
61    CTX: ContextTr<Journal: JournalExt> + ContextSetters,
62    I: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
63    P: PrecompileProvider<CTX, Output = InterpreterResult>,
64    INSP: Inspector<CTX, I::InterpreterTypes>,
65{
66    type Inspector = INSP;
67
68    fn inspector(&mut self) -> &mut Self::Inspector {
69        &mut self.0.inspector
70    }
71
72    fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) {
73        (&mut self.0.ctx, &mut self.0.inspector)
74    }
75
76    fn ctx_inspector_frame(
77        &mut self,
78    ) -> (&mut Self::Context, &mut Self::Inspector, &mut Self::Frame) {
79        (
80            &mut self.0.ctx,
81            &mut self.0.inspector,
82            self.0.frame_stack.get(),
83        )
84    }
85
86    fn ctx_inspector_frame_instructions(
87        &mut self,
88    ) -> (
89        &mut Self::Context,
90        &mut Self::Inspector,
91        &mut Self::Frame,
92        &mut Self::Instructions,
93    ) {
94        (
95            &mut self.0.ctx,
96            &mut self.0.inspector,
97            self.0.frame_stack.get(),
98            &mut self.0.instruction,
99        )
100    }
101}
102
103impl<CTX, INSP, I, P> EvmTr for OpEvm<CTX, INSP, I, P, EthFrame<EthInterpreter>>
104where
105    CTX: ContextTr,
106    I: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
107    P: PrecompileProvider<CTX, Output = InterpreterResult>,
108{
109    type Context = CTX;
110    type Instructions = I;
111    type Precompiles = P;
112    type Frame = EthFrame<EthInterpreter>;
113
114    fn ctx(&mut self) -> &mut Self::Context {
115        &mut self.0.ctx
116    }
117
118    fn ctx_ref(&self) -> &Self::Context {
119        &self.0.ctx
120    }
121
122    fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) {
123        (&mut self.0.ctx, &mut self.0.instruction)
124    }
125
126    fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles) {
127        (&mut self.0.ctx, &mut self.0.precompiles)
128    }
129
130    fn frame_stack(&mut self) -> &mut FrameStack<Self::Frame> {
131        &mut self.0.frame_stack
132    }
133
134    fn frame_init(
135        &mut self,
136        frame_input: <Self::Frame as FrameTr>::FrameInit,
137    ) -> Result<
138        ItemOrResult<&mut Self::Frame, <Self::Frame as FrameTr>::FrameResult>,
139        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
140    > {
141        self.0.frame_init(frame_input)
142    }
143
144    fn frame_run(
145        &mut self,
146    ) -> Result<
147        FrameInitOrResult<Self::Frame>,
148        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
149    > {
150        self.0.frame_run()
151    }
152
153    #[doc = " Returns the result of the frame to the caller. Frame is popped from the frame stack."]
154    #[doc = " Consumes the frame result or returns it if there is more frames to run."]
155    fn frame_return_result(
156        &mut self,
157        result: <Self::Frame as FrameTr>::FrameResult,
158    ) -> Result<
159        Option<<Self::Frame as FrameTr>::FrameResult>,
160        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
161    > {
162        self.0.frame_return_result(result)
163    }
164}