diff --git a/bin/reth/src/commands/debug_cmd/build_block.rs b/bin/reth/src/commands/debug_cmd/build_block.rs index ef6dbaf11c..b674324aa8 100644 --- a/bin/reth/src/commands/debug_cmd/build_block.rs +++ b/bin/reth/src/commands/debug_cmd/build_block.rs @@ -279,8 +279,8 @@ impl Command { #[cfg(not(feature = "bsc"))] let executor = block_executor!(provider_factory.chain_spec()).executor(db); - let BlockExecutionOutput { state, receipts, requests, .. } = - executor.execute((&block_with_senders.clone().unseal(), U256::MAX).into())?; + let BlockExecutionOutput { state, receipts, requests, .. } = executor + .execute((&block_with_senders.clone().unseal(), U256::MAX, None).into())?; let execution_outcome = ExecutionOutcome::new( state, receipts.into(), diff --git a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs index ed59246510..aa202004cf 100644 --- a/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs +++ b/bin/reth/src/commands/debug_cmd/in_memory_merkle.rs @@ -145,6 +145,7 @@ impl Command { .with_recovered_senders() .ok_or(BlockValidationError::SenderRecoveryError)?, merkle_block_td + block.difficulty, + None, ) .into(), )?; diff --git a/bin/reth/src/commands/debug_cmd/merkle.rs b/bin/reth/src/commands/debug_cmd/merkle.rs index 3534b6c2cc..2c41a2c593 100644 --- a/bin/reth/src/commands/debug_cmd/merkle.rs +++ b/bin/reth/src/commands/debug_cmd/merkle.rs @@ -153,7 +153,7 @@ impl Command { provider_rw.static_file_provider().clone(), ), )); - executor.execute_and_verify_one((&sealed_block.clone().unseal(), td).into())?; + executor.execute_and_verify_one((&sealed_block.clone().unseal(), td, None).into())?; executor.finalize().write_to_storage(&provider_rw, None, OriginalValuesKnown::Yes)?; let checkpoint = Some(StageCheckpoint::new( diff --git a/crates/blockchain-tree/src/chain.rs b/crates/blockchain-tree/src/chain.rs index dbc0c1d04b..90b20b9555 100644 --- a/crates/blockchain-tree/src/chain.rs +++ b/crates/blockchain-tree/src/chain.rs @@ -209,7 +209,7 @@ impl AppendableChain { let block_hash = block.hash(); let block = block.unseal(); - let state = executor.execute((&block, U256::MAX).into())?; + let state = executor.execute((&block, U256::MAX, Some(parent_block.header())).into())?; let BlockExecutionOutput { state, receipts, requests, .. } = state; externals .consensus diff --git a/crates/bsc/evm/src/execute.rs b/crates/bsc/evm/src/execute.rs index 145ac7615d..bf8f027540 100644 --- a/crates/bsc/evm/src/execute.rs +++ b/crates/bsc/evm/src/execute.rs @@ -323,9 +323,14 @@ where &mut self, block: &BlockWithSenders, total_difficulty: U256, + parent_header: Option<&Header>, ) -> Result { // 1. get parent header and snapshot - let parent = &(self.get_header_by_hash(block.parent_hash)?); + let parent = match parent_header { + // during live sync, the parent may not have been committed to the underlying database + Some(p) => p, + None => &(self.get_header_by_hash(block.parent_hash)?), + }; let snapshot_reader = SnapshotReader::new(self.provider.clone(), self.parlia.clone()); let snap = &(snapshot_reader.snapshot(parent, None)?); @@ -670,7 +675,7 @@ where DB: Database + std::fmt::Display>, P: ParliaProvider, { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -682,9 +687,9 @@ where /// /// State changes are committed to the database. fn execute(mut self, input: Self::Input<'_>) -> Result { - let BlockExecutionInput { block, total_difficulty } = input; + let BlockExecutionInput { block, total_difficulty, parent_header } = input; let BscExecuteOutput { receipts, gas_used, snapshot } = - self.execute_and_verify(block, total_difficulty)?; + self.execute_and_verify(block, total_difficulty, parent_header)?; // NOTE: we need to merge keep the reverts for the bundle retention self.state.merge_transitions(BundleRetention::Reverts); @@ -726,15 +731,15 @@ where DB: Database + std::fmt::Display>, P: ParliaProvider, { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = ExecutionOutcome; type Error = BlockExecutionError; fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> { - let BlockExecutionInput { block, total_difficulty } = input; + let BlockExecutionInput { block, total_difficulty, .. } = input; let execute_start = Instant::now(); let BscExecuteOutput { receipts, gas_used: _, snapshot } = - self.executor.execute_and_verify(block, total_difficulty)?; + self.executor.execute_and_verify(block, total_difficulty, None)?; self.stats.execution_duration += execute_start.elapsed(); validate_block_post_execution(block, self.executor.chain_spec(), &receipts)?; diff --git a/crates/consensus/auto-seal/src/lib.rs b/crates/consensus/auto-seal/src/lib.rs index 7a9001dcae..3274abb258 100644 --- a/crates/consensus/auto-seal/src/lib.rs +++ b/crates/consensus/auto-seal/src/lib.rs @@ -388,7 +388,7 @@ impl StorageInner { requests: block_execution_requests, gas_used, .. - } = executor.executor(&mut db).execute((&block, U256::ZERO).into())?; + } = executor.executor(&mut db).execute((&block, U256::ZERO, None).into())?; let execution_outcome = ExecutionOutcome::new( state, receipts.into(), diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 83afa7395c..4de11fc9c1 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -658,7 +658,7 @@ where let block_number = block.number; let block_hash = block.hash(); let block = block.unseal(); - let output = executor.execute((&block, U256::MAX).into()).unwrap(); + let output = executor.execute((&block, U256::MAX, None).into()).unwrap(); self.consensus.validate_block_post_execution( &block, PostExecutionInput::new(&output.receipts, &output.requests), diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 45ed8c8740..243f46c4b4 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -365,7 +365,7 @@ where EvmConfig: ConfigureEvm, DB: Database + std::fmt::Display>, { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -375,7 +375,7 @@ where /// /// Returns an error if the block could not be executed or failed verification. fn execute(mut self, input: Self::Input<'_>) -> Result { - let BlockExecutionInput { block, total_difficulty } = input; + let BlockExecutionInput { block, total_difficulty, .. } = input; let EthExecuteOutput { receipts, requests, gas_used } = self.execute_without_verification(block, total_difficulty)?; @@ -419,12 +419,12 @@ where EvmConfig: ConfigureEvm, DB: Database + Display>, { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = ExecutionOutcome; type Error = BlockExecutionError; fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> { - let BlockExecutionInput { block, total_difficulty } = input; + let BlockExecutionInput { block, total_difficulty, .. } = input; let EthExecuteOutput { receipts, requests, gas_used: _ } = self.executor.execute_without_verification(block, total_difficulty)?; diff --git a/crates/evm/src/either.rs b/crates/evm/src/either.rs index f6af36d2eb..def3dcc652 100644 --- a/crates/evm/src/either.rs +++ b/crates/evm/src/either.rs @@ -7,7 +7,7 @@ use crate::execute::{ }; use reth_execution_errors::BlockExecutionError; use reth_execution_types::ExecutionOutcome; -use reth_primitives::{BlockNumber, BlockWithSenders, Receipt}; +use reth_primitives::{BlockNumber, BlockWithSenders, Header, Receipt}; use reth_prune_types::PruneModes; use reth_storage_errors::provider::ProviderError; use revm_primitives::db::Database; @@ -51,19 +51,19 @@ impl Executor for Either where A: for<'a> Executor< DB, - Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, + Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>, Output = BlockExecutionOutput, Error = BlockExecutionError, >, B: for<'a> Executor< DB, - Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, + Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>, Output = BlockExecutionOutput, Error = BlockExecutionError, >, DB: Database + Display>, { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -79,19 +79,19 @@ impl BatchExecutor for Either where A: for<'a> BatchExecutor< DB, - Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, + Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>, Output = ExecutionOutcome, Error = BlockExecutionError, >, B: for<'a> BatchExecutor< DB, - Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, + Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>, Output = ExecutionOutcome, Error = BlockExecutionError, >, DB: Database + Display>, { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = ExecutionOutcome; type Error = BlockExecutionError; diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index c3ca2ba9ac..308ee3f792 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -1,7 +1,9 @@ //! Traits for execution. use reth_execution_types::ExecutionOutcome; -use reth_primitives::{parlia::Snapshot, BlockNumber, BlockWithSenders, Receipt, Request, U256}; +use reth_primitives::{ + parlia::Snapshot, BlockNumber, BlockWithSenders, Header, Receipt, Request, U256, +}; use reth_prune_types::PruneModes; use revm::db::BundleState; use revm_primitives::db::Database; @@ -119,23 +121,33 @@ pub struct BlockExecutionOutput { /// A helper type for ethereum block inputs that consists of a block and the total difficulty. #[derive(Debug)] -pub struct BlockExecutionInput<'a, Block> { +pub struct BlockExecutionInput<'a, Block, Header> { /// The block to execute. pub block: &'a Block, /// The total difficulty of the block. pub total_difficulty: U256, + /// The header of the block's parent + pub parent_header: Option<&'a Header>, } -impl<'a, Block> BlockExecutionInput<'a, Block> { +impl<'a, Block, Header> BlockExecutionInput<'a, Block, Header> { /// Creates a new input. - pub const fn new(block: &'a Block, total_difficulty: U256) -> Self { - Self { block, total_difficulty } + pub const fn new( + block: &'a Block, + total_difficulty: U256, + parent_header: Option<&'a Header>, + ) -> Self { + Self { block, total_difficulty, parent_header } } } -impl<'a, Block> From<(&'a Block, U256)> for BlockExecutionInput<'a, Block> { - fn from((block, total_difficulty): (&'a Block, U256)) -> Self { - Self::new(block, total_difficulty) +impl<'a, Block, Header> From<(&'a Block, U256, Option<&'a Header>)> + for BlockExecutionInput<'a, Block, Header> +{ + fn from( + (block, total_difficulty, parent_header): (&'a Block, U256, Option<&'a Header>), + ) -> Self { + Self::new(block, total_difficulty, parent_header) } } @@ -154,7 +166,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// the returned state. type Executor + Display>>: for<'a> Executor< DB, - Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, + Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>, Output = BlockExecutionOutput, Error = BlockExecutionError, >; @@ -162,7 +174,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { /// An executor that can execute a batch of blocks given a database. type BatchExecutor + Display>>: for<'a> BatchExecutor< DB, - Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, + Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>, Output = ExecutionOutcome, Error = BlockExecutionError, >; diff --git a/crates/evm/src/noop.rs b/crates/evm/src/noop.rs index 80a2b76de8..72c0ed9d91 100644 --- a/crates/evm/src/noop.rs +++ b/crates/evm/src/noop.rs @@ -4,7 +4,7 @@ use std::fmt::Display; use reth_execution_errors::BlockExecutionError; use reth_execution_types::ExecutionOutcome; -use reth_primitives::{BlockNumber, BlockWithSenders, Receipt}; +use reth_primitives::{BlockNumber, BlockWithSenders, Header, Receipt}; use reth_prune_types::PruneModes; use reth_storage_errors::provider::ProviderError; use revm_primitives::db::Database; @@ -41,7 +41,7 @@ impl BlockExecutorProvider for NoopBlockExecutorProvider { } impl Executor for NoopBlockExecutorProvider { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -51,7 +51,7 @@ impl Executor for NoopBlockExecutorProvider { } impl BatchExecutor for NoopBlockExecutorProvider { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = ExecutionOutcome; type Error = BlockExecutionError; diff --git a/crates/exex/exex/src/backfill/job.rs b/crates/exex/exex/src/backfill/job.rs index fa8695740b..892f63efac 100644 --- a/crates/exex/exex/src/backfill/job.rs +++ b/crates/exex/exex/src/backfill/job.rs @@ -61,7 +61,7 @@ where trace!(target: "exex::backfill", number = block_number, txs = block_with_senders.block.body.len(), "Executing block"); - let block_execution_output = executor.execute((&block_with_senders, td).into())?; + let block_execution_output = executor.execute((&block_with_senders, td, None).into())?; Ok((block_with_senders, block_execution_output)) } diff --git a/crates/exex/exex/src/backfill/mod.rs b/crates/exex/exex/src/backfill/mod.rs index 40cc48c6bb..11f85c64a8 100644 --- a/crates/exex/exex/src/backfill/mod.rs +++ b/crates/exex/exex/src/backfill/mod.rs @@ -161,7 +161,7 @@ where } .with_senders_unchecked(senders); - executor.execute_and_verify_one((&block, td).into())?; + executor.execute_and_verify_one((&block, td, None).into())?; execution_duration += execute_start.elapsed(); // TODO(alexey): report gas metrics using `block.header.gas_used` diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 3ff38e4dea..183ad4422d 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -391,7 +391,7 @@ where EvmConfig: ConfigureEvm, DB: Database + std::fmt::Display>, { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = BlockExecutionOutput; type Error = BlockExecutionError; @@ -403,7 +403,7 @@ where /// /// State changes are committed to the database. fn execute(mut self, input: Self::Input<'_>) -> Result { - let BlockExecutionInput { block, total_difficulty } = input; + let BlockExecutionInput { block, total_difficulty, .. } = input; let (receipts, gas_used) = self.execute_without_verification(block, total_difficulty)?; // NOTE: we need to merge keep the reverts for the bundle retention @@ -449,12 +449,12 @@ where EvmConfig: ConfigureEvm, DB: Database + std::fmt::Display>, { - type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; + type Input<'a> = BlockExecutionInput<'a, BlockWithSenders, Header>; type Output = ExecutionOutcome; type Error = BlockExecutionError; fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> { - let BlockExecutionInput { block, total_difficulty } = input; + let BlockExecutionInput { block, total_difficulty, .. } = input; let (receipts, _gas_used) = self.executor.execute_without_verification(block, total_difficulty)?; diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 08a5d07d24..7b605006be 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -275,7 +275,7 @@ where // Execute the block let execute_start = Instant::now(); - executor.execute_and_verify_one((&block, td).into()).map_err(|error| { + executor.execute_and_verify_one((&block, td, None).into()).map_err(|error| { StageError::Block { block: Box::new(block.header.clone().seal_slow()), error: BlockErrorKind::Execution(error),