custom_precompile_journal/
custom_evm.rs

1//! Custom EVM implementation with journal-accessing precompiles.
2
3use crate::precompile_provider::CustomPrecompileProvider;
4use revm::{
5    context::{ContextError, ContextSetters, ContextTr, Evm, FrameStack},
6    handler::{
7        evm::FrameTr, instructions::EthInstructions, EthFrame, EvmTr, FrameInitOrResult,
8        ItemOrResult,
9    },
10    inspector::{InspectorEvmTr, JournalExt},
11    interpreter::interpreter::EthInterpreter,
12    primitives::hardfork::SpecId,
13    Database, Inspector,
14};
15
16/// Custom EVM variant with journal-accessing precompiles.
17///
18/// This EVM extends the standard behavior by using a custom precompile provider
19/// that includes journal access functionality. It follows the same pattern as MyEvm
20/// but uses CustomPrecompileProvider instead of EthPrecompiles.
21#[derive(Debug)]
22pub struct CustomEvm<CTX, INSP>(
23    pub  Evm<
24        CTX,
25        INSP,
26        EthInstructions<EthInterpreter, CTX>,
27        CustomPrecompileProvider,
28        EthFrame<EthInterpreter>,
29    >,
30);
31
32impl<CTX, INSP> CustomEvm<CTX, INSP>
33where
34    CTX: ContextTr<Cfg: revm::context::Cfg<Spec = SpecId>>,
35{
36    /// Creates a new instance of CustomEvm with the provided context and inspector.
37    ///
38    /// # Arguments
39    ///
40    /// * `ctx` - The execution context that manages state, environment, and journaling
41    /// * `inspector` - The inspector for debugging and tracing execution
42    ///
43    /// # Returns
44    ///
45    /// A new CustomEvm instance configured with:
46    /// - The provided context and inspector
47    /// - Mainnet instruction set
48    /// - Custom precompiles with journal access
49    /// - A fresh frame stack for execution
50    pub fn new(ctx: CTX, inspector: INSP) -> Self {
51        Self(Evm {
52            ctx,
53            inspector,
54            instruction: EthInstructions::new_mainnet(),
55            precompiles: CustomPrecompileProvider::new_with_spec(SpecId::CANCUN),
56            frame_stack: FrameStack::new(),
57        })
58    }
59}
60
61impl<CTX, INSP> EvmTr for CustomEvm<CTX, INSP>
62where
63    CTX: ContextTr<Cfg: revm::context::Cfg<Spec = SpecId>>,
64{
65    type Context = CTX;
66    type Instructions = EthInstructions<EthInterpreter, CTX>;
67    type Precompiles = CustomPrecompileProvider;
68    type Frame = EthFrame<EthInterpreter>;
69
70    fn ctx(&mut self) -> &mut Self::Context {
71        &mut self.0.ctx
72    }
73
74    fn ctx_ref(&self) -> &Self::Context {
75        self.0.ctx_ref()
76    }
77
78    fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) {
79        self.0.ctx_instructions()
80    }
81
82    fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles) {
83        self.0.ctx_precompiles()
84    }
85
86    fn frame_stack(&mut self) -> &mut FrameStack<Self::Frame> {
87        self.0.frame_stack()
88    }
89
90    fn frame_init(
91        &mut self,
92        frame_input: <Self::Frame as FrameTr>::FrameInit,
93    ) -> Result<
94        ItemOrResult<&mut Self::Frame, <Self::Frame as FrameTr>::FrameResult>,
95        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
96    > {
97        self.0.frame_init(frame_input)
98    }
99
100    fn frame_run(
101        &mut self,
102    ) -> Result<
103        FrameInitOrResult<Self::Frame>,
104        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
105    > {
106        self.0.frame_run()
107    }
108
109    fn frame_return_result(
110        &mut self,
111        frame_result: <Self::Frame as FrameTr>::FrameResult,
112    ) -> Result<
113        Option<<Self::Frame as FrameTr>::FrameResult>,
114        ContextError<<<Self::Context as ContextTr>::Db as Database>::Error>,
115    > {
116        self.0.frame_return_result(frame_result)
117    }
118}
119
120impl<CTX, INSP> InspectorEvmTr for CustomEvm<CTX, INSP>
121where
122    CTX: ContextSetters<Cfg: revm::context::Cfg<Spec = SpecId>, Journal: JournalExt>,
123    INSP: Inspector<CTX, EthInterpreter>,
124{
125    type Inspector = INSP;
126
127    fn inspector(&mut self) -> &mut Self::Inspector {
128        self.0.inspector()
129    }
130
131    fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) {
132        self.0.ctx_inspector()
133    }
134
135    fn ctx_inspector_frame(
136        &mut self,
137    ) -> (&mut Self::Context, &mut Self::Inspector, &mut Self::Frame) {
138        self.0.ctx_inspector_frame()
139    }
140
141    fn ctx_inspector_frame_instructions(
142        &mut self,
143    ) -> (
144        &mut Self::Context,
145        &mut Self::Inspector,
146        &mut Self::Frame,
147        &mut Self::Instructions,
148    ) {
149        self.0.ctx_inspector_frame_instructions()
150    }
151}