use crate::chainspec::CustomChainSpec; use alloy_consensus::{Block, Header}; use alloy_evm::{ block::{ BlockExecutionError, BlockExecutionResult, BlockExecutor, BlockExecutorFactory, BlockExecutorFor, ExecutableTx, OnStateHook, }, Database, Evm, EvmEnv, }; use alloy_op_evm::{OpBlockExecutionCtx, OpBlockExecutor, OpEvm}; use op_revm::{OpSpecId, OpTransaction}; use reth_evm::{ execute::{BlockAssembler, BlockAssemblerInput}, InspectorFor, }; use reth_node_api::ConfigureEvm; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_node::{ OpBlockAssembler, OpEvmConfig, OpEvmFactory, OpNextBlockEnvAttributes, OpRethReceiptBuilder, }; use reth_optimism_primitives::{DepositReceipt, OpPrimitives, OpReceipt, OpTransactionSigned}; use reth_primitives_traits::{Receipt, SealedBlock, SealedHeader}; use revm::{ context::{result::ExecutionResult, TxEnv}, database::State, }; use std::sync::Arc; pub struct CustomBlockExecutor { inner: OpBlockExecutor>, } impl<'db, DB, E> BlockExecutor for CustomBlockExecutor where DB: Database + 'db, E: Evm, Tx = OpTransaction>, { type Transaction = OpTransactionSigned; type Receipt = OpReceipt; type Evm = E; fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> { self.inner.apply_pre_execution_changes() } fn execute_transaction_with_result_closure( &mut self, tx: impl ExecutableTx, f: impl FnOnce(&ExecutionResult<::HaltReason>), ) -> Result { self.inner.execute_transaction_with_result_closure(tx, f) } fn finish(self) -> Result<(Self::Evm, BlockExecutionResult), BlockExecutionError> { self.inner.finish() } fn set_state_hook(&mut self, _hook: Option>) { self.inner.set_state_hook(_hook) } fn evm_mut(&mut self) -> &mut Self::Evm { self.inner.evm_mut() } } #[derive(Clone, Debug)] pub struct CustomBlockAssembler { inner: OpBlockAssembler, } impl BlockAssembler for CustomBlockAssembler where F: for<'a> BlockExecutorFactory< ExecutionCtx<'a> = OpBlockExecutionCtx, Transaction = OpTransactionSigned, Receipt: Receipt + DepositReceipt, >, { // TODO: use custom block here type Block = Block; fn assemble_block( &self, input: BlockAssemblerInput<'_, '_, F>, ) -> Result { let block = self.inner.assemble_block(input)?; Ok(block) } } #[derive(Debug, Clone)] pub struct CustomEvmConfig { inner: OpEvmConfig, block_assembler: CustomBlockAssembler, } impl BlockExecutorFactory for CustomEvmConfig { type EvmFactory = OpEvmFactory; type ExecutionCtx<'a> = OpBlockExecutionCtx; type Transaction = OpTransactionSigned; type Receipt = OpReceipt; fn evm_factory(&self) -> &Self::EvmFactory { self.inner.evm_factory() } fn create_executor<'a, DB, I>( &'a self, evm: OpEvm<&'a mut State, I>, ctx: OpBlockExecutionCtx, ) -> impl BlockExecutorFor<'a, Self, DB, I> where DB: Database + 'a, I: InspectorFor> + 'a, { CustomBlockExecutor { inner: OpBlockExecutor::new( evm, ctx, self.inner.chain_spec().clone(), *self.inner.executor_factory.receipt_builder(), ), } } } impl ConfigureEvm for CustomEvmConfig { type Primitives = OpPrimitives; type Error = ::Error; type NextBlockEnvCtx = ::NextBlockEnvCtx; type BlockExecutorFactory = Self; type BlockAssembler = CustomBlockAssembler; fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { self } fn block_assembler(&self) -> &Self::BlockAssembler { &self.block_assembler } fn evm_env(&self, header: &Header) -> EvmEnv { self.inner.evm_env(header) } fn next_evm_env( &self, parent: &Header, attributes: &OpNextBlockEnvAttributes, ) -> Result, Self::Error> { self.inner.next_evm_env(parent, attributes) } fn context_for_block( &self, block: &SealedBlock>, ) -> OpBlockExecutionCtx { self.inner.context_for_block(block) } fn context_for_next_block( &self, parent: &SealedHeader, attributes: Self::NextBlockEnvCtx, ) -> OpBlockExecutionCtx { self.inner.context_for_next_block(parent, attributes) } }