op_revm/
evm.rs

1//! Contains the `[OpEvm]` type and its implementation of the execution EVM traits.
2use crate::{precompiles::OpPrecompiles, OpSpecId};
3use revm::{
4    context::{Cfg, 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<Cfg: Cfg<Spec: Into<OpSpecId> + Clone>>, INSP>
30    OpEvm<CTX, INSP, EthInstructions<EthInterpreter, CTX>, OpPrecompiles>
31{
32    /// Create a new Optimism EVM.
33    pub fn new(ctx: CTX, inspector: INSP) -> Self {
34        let spec: OpSpecId = ctx.cfg().spec().into();
35        Self(Evm {
36            ctx,
37            inspector,
38            instruction: EthInstructions::new_mainnet_with_spec(spec.into()),
39            precompiles: OpPrecompiles::new_with_spec(spec),
40            frame_stack: FrameStack::new_prealloc(8),
41        })
42    }
43
44    /// Consumes self and returns the inner context.
45    pub fn into_context(self) -> CTX {
46        self.0.ctx
47    }
48}
49
50impl<CTX, INSP, I, P> OpEvm<CTX, INSP, I, P> {
51    /// Consumed self and returns a new Evm type with given Inspector.
52    pub fn with_inspector<OINSP>(self, inspector: OINSP) -> OpEvm<CTX, OINSP, I, P> {
53        OpEvm(self.0.with_inspector(inspector))
54    }
55
56    /// Consumes self and returns a new Evm type with given Precompiles.
57    pub fn with_precompiles<OP>(self, precompiles: OP) -> OpEvm<CTX, INSP, I, OP> {
58        OpEvm(self.0.with_precompiles(precompiles))
59    }
60
61    /// Consumes self and returns the inner Inspector.
62    pub fn into_inspector(self) -> INSP {
63        self.0.into_inspector()
64    }
65}
66
67impl<CTX, INSP, I, P> InspectorEvmTr for OpEvm<CTX, INSP, I, P>
68where
69    CTX: ContextTr<Journal: JournalExt> + ContextSetters,
70    I: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
71    P: PrecompileProvider<CTX, Output = InterpreterResult>,
72    INSP: Inspector<CTX, I::InterpreterTypes>,
73{
74    type Inspector = INSP;
75
76    #[inline]
77    fn all_inspector(
78        &self,
79    ) -> (
80        &Self::Context,
81        &Self::Instructions,
82        &Self::Precompiles,
83        &FrameStack<Self::Frame>,
84        &Self::Inspector,
85    ) {
86        self.0.all_inspector()
87    }
88
89    #[inline]
90    fn all_mut_inspector(
91        &mut self,
92    ) -> (
93        &mut Self::Context,
94        &mut Self::Instructions,
95        &mut Self::Precompiles,
96        &mut FrameStack<Self::Frame>,
97        &mut Self::Inspector,
98    ) {
99        self.0.all_mut_inspector()
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    #[inline]
115    fn all(
116        &self,
117    ) -> (
118        &Self::Context,
119        &Self::Instructions,
120        &Self::Precompiles,
121        &FrameStack<Self::Frame>,
122    ) {
123        self.0.all()
124    }
125
126    #[inline]
127    fn all_mut(
128        &mut self,
129    ) -> (
130        &mut Self::Context,
131        &mut Self::Instructions,
132        &mut Self::Precompiles,
133        &mut FrameStack<Self::Frame>,
134    ) {
135        self.0.all_mut()
136    }
137
138    fn frame_init(
139        &mut self,
140        frame_input: <Self::Frame as FrameTr>::FrameInit,
141    ) -> Result<
142        ItemOrResult<&mut Self::Frame, <Self::Frame as FrameTr>::FrameResult>,
143        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
144    > {
145        self.0.frame_init(frame_input)
146    }
147
148    fn frame_run(
149        &mut self,
150    ) -> Result<
151        FrameInitOrResult<Self::Frame>,
152        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
153    > {
154        self.0.frame_run()
155    }
156
157    #[doc = " Returns the result of the frame to the caller. Frame is popped from the frame stack."]
158    #[doc = " Consumes the frame result or returns it if there is more frames to run."]
159    fn frame_return_result(
160        &mut self,
161        result: <Self::Frame as FrameTr>::FrameResult,
162    ) -> Result<
163        Option<<Self::Frame as FrameTr>::FrameResult>,
164        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
165    > {
166        self.0.frame_return_result(result)
167    }
168}