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_prealloc(8),
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    #[inline]
69    fn all_inspector(
70        &self,
71    ) -> (
72        &Self::Context,
73        &Self::Instructions,
74        &Self::Precompiles,
75        &FrameStack<Self::Frame>,
76        &Self::Inspector,
77    ) {
78        self.0.all_inspector()
79    }
80
81    #[inline]
82    fn all_mut_inspector(
83        &mut self,
84    ) -> (
85        &mut Self::Context,
86        &mut Self::Instructions,
87        &mut Self::Precompiles,
88        &mut FrameStack<Self::Frame>,
89        &mut Self::Inspector,
90    ) {
91        self.0.all_mut_inspector()
92    }
93}
94
95impl<CTX, INSP, I, P> EvmTr for OpEvm<CTX, INSP, I, P, EthFrame<EthInterpreter>>
96where
97    CTX: ContextTr,
98    I: InstructionProvider<Context = CTX, InterpreterTypes = EthInterpreter>,
99    P: PrecompileProvider<CTX, Output = InterpreterResult>,
100{
101    type Context = CTX;
102    type Instructions = I;
103    type Precompiles = P;
104    type Frame = EthFrame<EthInterpreter>;
105
106    #[inline]
107    fn all(
108        &self,
109    ) -> (
110        &Self::Context,
111        &Self::Instructions,
112        &Self::Precompiles,
113        &FrameStack<Self::Frame>,
114    ) {
115        self.0.all()
116    }
117
118    #[inline]
119    fn all_mut(
120        &mut self,
121    ) -> (
122        &mut Self::Context,
123        &mut Self::Instructions,
124        &mut Self::Precompiles,
125        &mut FrameStack<Self::Frame>,
126    ) {
127        self.0.all_mut()
128    }
129
130    fn frame_init(
131        &mut self,
132        frame_input: <Self::Frame as FrameTr>::FrameInit,
133    ) -> Result<
134        ItemOrResult<&mut Self::Frame, <Self::Frame as FrameTr>::FrameResult>,
135        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
136    > {
137        self.0.frame_init(frame_input)
138    }
139
140    fn frame_run(
141        &mut self,
142    ) -> Result<
143        FrameInitOrResult<Self::Frame>,
144        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
145    > {
146        self.0.frame_run()
147    }
148
149    #[doc = " Returns the result of the frame to the caller. Frame is popped from the frame stack."]
150    #[doc = " Consumes the frame result or returns it if there is more frames to run."]
151    fn frame_return_result(
152        &mut self,
153        result: <Self::Frame as FrameTr>::FrameResult,
154    ) -> Result<
155        Option<<Self::Frame as FrameTr>::FrameResult>,
156        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
157    > {
158        self.0.frame_return_result(result)
159    }
160}