diff --git a/src/evm/api/builder.rs b/src/evm/api/builder.rs index 14c01eee0..67152d616 100644 --- a/src/evm/api/builder.rs +++ b/src/evm/api/builder.rs @@ -1,17 +1,15 @@ use super::HlEvmInner; use crate::evm::{spec::HlSpecId, transaction::HlTxTr}; +use reth_revm::context::ContextTr; use revm::{ - context::{Cfg, JournalOutput}, - context_interface::{Block, JournalTr}, - handler::instructions::EthInstructions, - interpreter::interpreter::EthInterpreter, - Context, Database, + context::Cfg, context_interface::Block, handler::instructions::EthInstructions, + interpreter::interpreter::EthInterpreter, Context, Database, }; /// Trait that allows for hl HlEvm to be built. pub trait HlBuilder: Sized { /// Type of the context. - type Context; + type Context: ContextTr; /// Build the hl with an inspector. fn build_hl_with_inspector( @@ -20,13 +18,12 @@ pub trait HlBuilder: Sized { ) -> HlEvmInner>; } -impl HlBuilder for Context +impl HlBuilder for Context where BLOCK: Block, TX: HlTxTr, CFG: Cfg, DB: Database, - JOURNAL: JournalTr, { type Context = Self; diff --git a/src/evm/api/exec.rs b/src/evm/api/exec.rs index c3544b378..b4944e06f 100644 --- a/src/evm/api/exec.rs +++ b/src/evm/api/exec.rs @@ -1,29 +1,26 @@ use super::HlEvmInner; -use crate::evm::{handler::HlHandler, spec::HlSpecId, transaction::HlTxTr}; +use crate::evm::{spec::HlSpecId, transaction::HlTxTr}; use revm::{ - context::{ContextSetters, JournalOutput}, + context::{result::HaltReason, ContextSetters}, context_interface::{ result::{EVMError, ExecutionResult, ResultAndState}, Cfg, ContextTr, Database, JournalTr, }, - handler::{instructions::EthInstructions, EthFrame, EvmTr, Handler, PrecompileProvider}, - inspector::{InspectCommitEvm, InspectEvm, Inspector, InspectorHandler, JournalExt}, + handler::{instructions::EthInstructions, PrecompileProvider}, + inspector::{InspectCommitEvm, InspectEvm, Inspector, JournalExt}, interpreter::{interpreter::EthInterpreter, InterpreterResult}, + state::EvmState, DatabaseCommit, ExecuteCommitEvm, ExecuteEvm, }; // Type alias for HL context pub trait HlContextTr: - ContextTr, Tx: HlTxTr, Cfg: Cfg> + ContextTr, Tx: HlTxTr, Cfg: Cfg> { } impl HlContextTr for T where - T: ContextTr< - Journal: JournalTr, - Tx: HlTxTr, - Cfg: Cfg, - > + T: ContextTr, Tx: HlTxTr, Cfg: Cfg> { } @@ -36,23 +33,32 @@ where CTX: HlContextTr + ContextSetters, PRECOMPILE: PrecompileProvider, { - type Output = Result>; + type ExecutionResult = ExecutionResult; + type State = EvmState; + type Error = HlError; type Tx = ::Tx; type Block = ::Block; - fn set_tx(&mut self, tx: Self::Tx) { - self.0.ctx.set_tx(tx); + #[inline] + fn transact_one(&mut self, tx: Self::Tx) -> Result { + self.0.transact_one(tx) } + #[inline] + fn finalize(&mut self) -> Self::State { + self.0.finalize() + } + + #[inline] fn set_block(&mut self, block: Self::Block) { - self.0.ctx.set_block(block); + self.0.set_block(block); } - fn replay(&mut self) -> Self::Output { - let mut h = HlHandler::<_, _, EthFrame<_, _, _>>::new(); - h.run(self) + #[inline] + fn replay(&mut self) -> Result, Self::Error> { + self.0.replay() } } @@ -62,13 +68,8 @@ where CTX: HlContextTr + ContextSetters, PRECOMPILE: PrecompileProvider, { - type CommitOutput = Result>; - - fn replay_commit(&mut self) -> Self::CommitOutput { - self.replay().map(|r| { - self.ctx().db().commit(r.state); - r.result - }) + fn commit(&mut self, state: Self::State) { + self.0.commit(state); } } @@ -82,12 +83,11 @@ where type Inspector = INSP; fn set_inspector(&mut self, inspector: Self::Inspector) { - self.0.inspector = inspector; + self.0.set_inspector(inspector); } - fn inspect_replay(&mut self) -> Self::Output { - let mut h = HlHandler::<_, _, EthFrame<_, _, _>>::new(); - h.inspect_run(self) + fn inspect_one_tx(&mut self, tx: Self::Tx) -> Result { + self.0.inspect_one_tx(tx) } } diff --git a/src/evm/api/mod.rs b/src/evm/api/mod.rs index d25c4e911..bdbd50aaa 100644 --- a/src/evm/api/mod.rs +++ b/src/evm/api/mod.rs @@ -1,12 +1,13 @@ use revm::{ - context::{ContextSetters, Evm as EvmCtx}, + context::{ContextSetters, Evm, FrameStack}, context_interface::ContextTr, handler::{ + evm::{ContextDbError, FrameInitResult}, instructions::{EthInstructions, InstructionProvider}, - EthPrecompiles, EvmTr, PrecompileProvider, + EthFrame, EthPrecompiles, EvmTr, FrameInitOrResult, FrameTr, PrecompileProvider, }, inspector::{InspectorEvmTr, JournalExt}, - interpreter::{interpreter::EthInterpreter, Interpreter, InterpreterAction, InterpreterTypes}, + interpreter::{interpreter::EthInterpreter, InterpreterResult}, Inspector, }; @@ -14,19 +15,23 @@ pub mod builder; pub mod ctx; mod exec; -pub struct HlEvmInner, P = EthPrecompiles>( - pub EvmCtx, -); +pub struct HlEvmInner< + CTX: ContextTr, + INSP, + I = EthInstructions, + P = EthPrecompiles, +>(pub Evm>); impl HlEvmInner, EthPrecompiles> { pub fn new(ctx: CTX, inspector: INSP) -> Self { - Self(EvmCtx { + Self(Evm { ctx, inspector, instruction: EthInstructions::new_mainnet(), precompiles: EthPrecompiles::default(), + frame_stack: FrameStack::new(), }) } @@ -42,12 +47,9 @@ impl impl InspectorEvmTr for HlEvmInner where CTX: ContextTr + ContextSetters, - I: InstructionProvider< - Context = CTX, - InterpreterTypes: InterpreterTypes, - >, + I: InstructionProvider, INSP: Inspector, - P: PrecompileProvider, + P: PrecompileProvider, { type Inspector = INSP; @@ -59,41 +61,29 @@ where (&mut self.0.ctx, &mut self.0.inspector) } - fn run_inspect_interpreter( + fn ctx_inspector_frame( &mut self, - interpreter: &mut Interpreter< - ::InterpreterTypes, - >, - ) -> <::InterpreterTypes as InterpreterTypes>::Output - { - self.0.run_inspect_interpreter(interpreter) + ) -> (&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< - Context = CTX, - InterpreterTypes: InterpreterTypes, - >, - P: PrecompileProvider, + I: InstructionProvider, + P: PrecompileProvider, { type Context = CTX; type Instructions = I; type Precompiles = P; - - fn run_interpreter( - &mut self, - interpreter: &mut Interpreter< - ::InterpreterTypes, - >, - ) -> <::InterpreterTypes as InterpreterTypes>::Output - { - let context = &mut self.0.ctx; - let instructions = &mut self.0.instruction; - interpreter.run_plain(instructions.instruction_table(), context) - } + type Frame = EthFrame; fn ctx(&mut self) -> &mut Self::Context { &mut self.0.ctx @@ -110,6 +100,30 @@ where 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) + } } // #[cfg(test)] diff --git a/src/node/consensus/mod.rs b/src/node/consensus/mod.rs index bc4588283..e81b62cc3 100644 --- a/src/node/consensus/mod.rs +++ b/src/node/consensus/mod.rs @@ -135,7 +135,9 @@ impl Consensus for HlConsensus FullConsensus for HlConsensus { +impl + HlHardforks> + FullConsensus for HlConsensus +{ fn validate_block_post_execution( &self, block: &RecoveredBlock, diff --git a/src/node/evm/config.rs b/src/node/evm/config.rs index 631387291..13085fa03 100644 --- a/src/node/evm/config.rs +++ b/src/node/evm/config.rs @@ -14,7 +14,6 @@ use alloy_consensus::{BlockHeader, Header, Transaction as _, TxReceipt, EMPTY_OM use alloy_eips::merge::BEACON_NONCE; use alloy_primitives::{Log, U256}; use reth_chainspec::{EthChainSpec, EthereumHardforks, Hardforks}; -use reth_ethereum_forks::EthereumHardfork; use reth_evm::{ block::{BlockExecutionError, BlockExecutorFactory, BlockExecutorFor}, eth::{receipt_builder::ReceiptBuilder, EthBlockExecutionCtx}, @@ -67,7 +66,7 @@ where .. } = input; - let timestamp = evm_env.block_env.timestamp; + let timestamp = evm_env.block_env.timestamp.saturating_to(); // Filter out system tx receipts let transactions_for_root: Vec = @@ -122,7 +121,7 @@ where mix_hash: evm_env.block_env.prevrandao.unwrap_or_default(), nonce: BEACON_NONCE.into(), base_fee_per_gas: Some(evm_env.block_env.basefee), - number: evm_env.block_env.number, + number: evm_env.block_env.number.saturating_to(), gas_limit: evm_env.block_env.gas_limit, difficulty: evm_env.block_env.difficulty, gas_used: *gas_used, @@ -264,8 +263,6 @@ where } } -const EIP1559_INITIAL_BASE_FEE: u64 = 0; - impl ConfigureEvm for HlEvmConfig where Self: Send + Sync + Unpin + Clone + 'static, @@ -297,7 +294,7 @@ where CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec); if let Some(blob_params) = &blob_params { - cfg_env.set_blob_max_count(blob_params.max_blob_count); + cfg_env.set_max_blobs_per_tx(blob_params.max_blobs_per_tx); } // TODO: enable only for system transactions @@ -315,9 +312,9 @@ where let eth_spec = spec.into_eth_spec(); let block_env = BlockEnv { - number: header.number(), + number: U256::from(header.number()), beneficiary: header.beneficiary(), - timestamp: header.timestamp(), + timestamp: U256::from(header.timestamp()), difficulty: if eth_spec >= SpecId::MERGE { U256::ZERO } else { header.difficulty() }, prevrandao: if eth_spec >= SpecId::MERGE { header.mix_hash() } else { None }, gas_limit: header.gas_limit(), @@ -346,43 +343,19 @@ where // if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is // cancun now, we need to set the excess blob gas to the default value(0) - let blob_excess_gas_and_price = parent - .maybe_next_block_excess_blob_gas( - self.chain_spec().blob_params_at_timestamp(attributes.timestamp), - ) - .or_else(|| (spec_id.into_eth_spec().is_enabled_in(SpecId::CANCUN)).then_some(0)) - .map(|gas| BlobExcessGasAndPrice::new(gas, false)); + let blob_excess_gas_and_price = spec_id + .into_eth_spec() + .is_enabled_in(SpecId::CANCUN) + .then_some(BlobExcessGasAndPrice { excess_blob_gas: 0, blob_gasprice: 0 }); - let mut basefee = parent.next_block_base_fee( + let basefee = parent.next_block_base_fee( self.chain_spec().base_fee_params_at_timestamp(attributes.timestamp), ); - let mut gas_limit = U256::from(parent.gas_limit); - - // If we are on the London fork boundary, we need to multiply the parent's gas limit by the - // elasticity multiplier to get the new gas limit. - if self - .chain_spec() - .inner - .fork(EthereumHardfork::London) - .transitions_at_block(parent.number + 1) - { - let elasticity_multiplier = self - .chain_spec() - .base_fee_params_at_timestamp(attributes.timestamp) - .elasticity_multiplier; - - // multiply the gas limit by the elasticity multiplier - gas_limit *= U256::from(elasticity_multiplier); - - // set the base fee to the initial base fee from the EIP-1559 spec - basefee = Some(EIP1559_INITIAL_BASE_FEE) - } - let block_env = BlockEnv { - number: parent.number() + 1, + number: U256::from(parent.number() + 1), beneficiary: attributes.suggested_fee_recipient, - timestamp: attributes.timestamp, + timestamp: U256::from(attributes.timestamp), difficulty: U256::ZERO, prevrandao: Some(attributes.prev_randao), gas_limit: attributes.gas_limit, diff --git a/src/node/evm/executor.rs b/src/node/evm/executor.rs index 0a8cf7337..4f0d22742 100644 --- a/src/node/evm/executor.rs +++ b/src/node/evm/executor.rs @@ -16,8 +16,8 @@ use reth_evm::{ block::{BlockValidationError, CommitChanges}, eth::receipt_builder::ReceiptBuilder, execute::{BlockExecutionError, BlockExecutor}, - precompiles::{DynPrecompile, PrecompilesMap}, - Database, Evm, FromRecoveredTx, FromTxWithEncoded, IntoTxEnv, OnStateHook, RecoveredTx, + precompiles::{DynPrecompile, PrecompileInput, PrecompilesMap}, + Database, Evm, FromRecoveredTx, FromTxWithEncoded, IntoTxEnv, OnStateHook, }; use reth_provider::BlockExecutionResult; use reth_revm::State; @@ -227,8 +227,8 @@ where for (address, precompile) in ctx.read_precompile_calls.iter() { let precompile = precompile.clone(); precompiles_mut.apply_precompile(address, |_| { - Some(DynPrecompile::from(move |data: &[u8], gas: u64| { - run_precompile(&precompile, data, gas) + Some(DynPrecompile::from(move |input: PrecompileInput| -> PrecompileResult { + run_precompile(&precompile, input.data, input.gas) })) }); } diff --git a/src/node/evm/factory.rs b/src/node/evm/factory.rs index 8655fff9a..843ae2192 100644 --- a/src/node/evm/factory.rs +++ b/src/node/evm/factory.rs @@ -7,8 +7,8 @@ use crate::evm::{ spec::HlSpecId, transaction::HlTxEnv, }; -use reth_evm::{precompiles::PrecompilesMap, EvmEnv, EvmFactory}; -use reth_revm::{Context, Database}; +use reth_evm::{precompiles::PrecompilesMap, Database, EvmEnv, EvmFactory}; +use reth_revm::Context; use revm::{ context::{ result::{EVMError, HaltReason}, @@ -25,16 +25,15 @@ use revm::{ pub struct HlEvmFactory; impl EvmFactory for HlEvmFactory { - type Evm, I: Inspector>> = - HlEvm; - type Context> = HlContext; + type Evm>> = HlEvm; + type Context = HlContext; type Tx = HlTxEnv; type Error = EVMError; type HaltReason = HaltReason; type Spec = HlSpecId; type Precompiles = PrecompilesMap; - fn create_evm>( + fn create_evm( &self, db: DB, input: EvmEnv, diff --git a/src/node/evm/mod.rs b/src/node/evm/mod.rs index b1ce8ee08..1a4796002 100644 --- a/src/node/evm/mod.rs +++ b/src/node/evm/mod.rs @@ -97,8 +97,7 @@ where tx: Self::Tx, ) -> Result, Self::Error> { if self.inspect { - self.inner.set_tx(tx); - self.inner.inspect_replay() + self.inner.inspect_tx(tx) } else { self.inner.transact(tx) } diff --git a/src/node/rpc/block.rs b/src/node/rpc/block.rs index b4a892fff..98495ce66 100644 --- a/src/node/rpc/block.rs +++ b/src/node/rpc/block.rs @@ -3,7 +3,6 @@ use crate::{ node::{ primitives::TransactionSigned, rpc::{HlEthApi, HlNodeCore}, - HlBlock, HlPrimitives, }, }; use alloy_consensus::{BlockHeader, ReceiptEnvelope, TxType}; @@ -16,8 +15,7 @@ use reth::{ rpc::{ eth::EthApiTypes, server_types::eth::{ - error::FromEvmError, receipt::build_receipt, EthApiError, EthReceiptBuilder, - PendingBlock, + error::FromEvmError, receipt::build_receipt, EthApiError, PendingBlock, }, types::{BlockId, TransactionReceipt}, }, @@ -25,7 +23,8 @@ use reth::{ }; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::{ConfigureEvm, NextBlockEnvAttributes}; -use reth_primitives_traits::BlockBody as _; +use reth_primitives::NodePrimitives; +use reth_primitives_traits::{BlockBody as _, SignedTransaction as _}; use reth_provider::{ BlockReader, ChainSpecProvider, HeaderProvider, ProviderBlock, ProviderReceipt, ProviderTx, StateProviderFactory, @@ -33,7 +32,7 @@ use reth_provider::{ use reth_rpc_eth_api::{ helpers::{EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt, SpawnBlocking}, types::RpcTypes, - FromEthApiError, RpcNodeCore, RpcNodeCoreExt, RpcReceipt, + FromEthApiError, RpcConvert, RpcNodeCore, RpcNodeCoreExt, RpcReceipt, }; impl EthBlocks for HlEthApi @@ -68,7 +67,7 @@ where .enumerate() .map(|(idx, (tx, receipt))| { let meta = TransactionMeta { - tx_hash: *tx.0.tx_hash(), + tx_hash: *tx.tx_hash(), index: idx as u64, block_hash, block_number, @@ -76,8 +75,15 @@ where excess_blob_gas, timestamp, }; - EthReceiptBuilder::new(&tx.0, meta, receipt, &receipts, blob_params) - .map(|builder| builder.build()) + build_receipt(tx, meta, receipt, &receipts, blob_params, |receipt_with_bloom| { + match receipt.tx_type { + TxType::Legacy => ReceiptEnvelope::Legacy(receipt_with_bloom), + TxType::Eip2930 => ReceiptEnvelope::Eip2930(receipt_with_bloom), + TxType::Eip1559 => ReceiptEnvelope::Eip1559(receipt_with_bloom), + TxType::Eip4844 => ReceiptEnvelope::Eip4844(receipt_with_bloom), + TxType::Eip7702 => ReceiptEnvelope::Eip7702(receipt_with_bloom), + } + }) }) .collect::, Self::Error>>() .map(Some); @@ -108,17 +114,23 @@ where Header = alloy_rpc_types_eth::Header>, >, Error: FromEvmError, + RpcConvert: RpcConvert, >, N: RpcNodeCore< - Provider: BlockReaderIdExt< - Transaction = TransactionSigned, - Block = HlBlock, - Receipt = Receipt, - Header = alloy_consensus::Header, - > + ChainSpecProvider + Provider: BlockReaderIdExt + + ChainSpecProvider + StateProviderFactory, Pool: TransactionPool>>, - Evm: ConfigureEvm, + Evm: ConfigureEvm< + Primitives = ::Primitives, + NextBlockEnvCtx: From, + >, + Primitives: NodePrimitives< + BlockHeader = ProviderHeader, + SignedTx = ProviderTx, + Receipt = ProviderReceipt, + Block = ProviderBlock, + >, >, { #[inline] @@ -141,7 +153,8 @@ where gas_limit: parent.gas_limit(), parent_beacon_block_root: parent.parent_beacon_block_root(), withdrawals: None, - }) + } + .into()) } }