use revm::{ bytecode::opcode::BLOCKHASH, context::{ContextSetters, Evm, FrameStack}, context_interface::ContextTr, handler::{ evm::{ContextDbError, FrameInitResult}, instructions::{EthInstructions, InstructionProvider}, EthFrame, EthPrecompiles, EvmTr, FrameInitOrResult, FrameTr, PrecompileProvider, }, inspector::{InspectorEvmTr, JournalExt}, interpreter::{interpreter::EthInterpreter, Instruction, InterpreterResult}, Inspector, }; use crate::chainspec::MAINNET_CHAIN_ID; pub mod builder; pub mod ctx; mod exec; mod patch; pub struct HlEvmInner< CTX: ContextTr, INSP, I = EthInstructions, P = EthPrecompiles, >(pub Evm>); impl HlEvmInner, EthPrecompiles> { pub fn new(ctx: CTX, inspector: INSP) -> Self { let mut instruction = EthInstructions::new_mainnet(); const NON_PLACEHOLDER_BLOCK_HASH_HEIGHT: u64 = 243_538; if ctx.chain_id() == MAINNET_CHAIN_ID && ctx.block_number() < NON_PLACEHOLDER_BLOCK_HASH_HEIGHT { instruction.insert_instruction( BLOCKHASH, Instruction::new(patch::blockhash_returning_placeholder, 20), ); } Self(Evm { ctx, inspector, instruction, precompiles: EthPrecompiles::default(), frame_stack: FrameStack::new(), }) } /// Consumes self and returns a new Evm type with given Precompiles. pub fn with_precompiles( self, precompiles: OP, ) -> HlEvmInner, OP> { HlEvmInner(self.0.with_precompiles(precompiles)) } } impl InspectorEvmTr for HlEvmInner where CTX: ContextTr + ContextSetters, I: InstructionProvider, INSP: Inspector, P: PrecompileProvider, { type Inspector = INSP; fn inspector(&mut self) -> &mut Self::Inspector { &mut self.0.inspector } fn ctx_inspector(&mut self) -> (&mut Self::Context, &mut Self::Inspector) { (&mut self.0.ctx, &mut self.0.inspector) } fn ctx_inspector_frame( &mut self, ) -> (&mut Self::Context, &mut Self::Inspector, &mut Self::Frame) { (&mut self.0.ctx, &mut self.0.inspector, self.0.frame_stack.get()) } fn ctx_inspector_frame_instructions( &mut self, ) -> (&mut Self::Context, &mut Self::Inspector, &mut Self::Frame, &mut Self::Instructions) { (&mut self.0.ctx, &mut self.0.inspector, self.0.frame_stack.get(), &mut self.0.instruction) } } impl EvmTr for HlEvmInner where CTX: ContextTr, I: InstructionProvider, P: PrecompileProvider, { type Context = CTX; type Instructions = I; type Precompiles = P; type Frame = EthFrame; fn ctx(&mut self) -> &mut Self::Context { &mut self.0.ctx } fn ctx_ref(&self) -> &Self::Context { &self.0.ctx } fn ctx_instructions(&mut self) -> (&mut Self::Context, &mut Self::Instructions) { (&mut self.0.ctx, &mut self.0.instruction) } fn ctx_precompiles(&mut self) -> (&mut Self::Context, &mut Self::Precompiles) { (&mut self.0.ctx, &mut self.0.precompiles) } fn frame_stack(&mut self) -> &mut FrameStack { &mut self.0.frame_stack } fn frame_init( &mut self, frame_input: ::FrameInit, ) -> Result, ContextDbError> { self.0.frame_init(frame_input) } fn frame_run( &mut self, ) -> Result, ContextDbError> { self.0.frame_run() } fn frame_return_result( &mut self, result: ::FrameResult, ) -> Result::FrameResult>, ContextDbError> { self.0.frame_return_result(result) } }