refactor: replace BatchBlockExecutionOutput by BundleStateWithReceipts (#8709)

This commit is contained in:
Thomas Coratger
2024-06-10 18:46:39 +02:00
committed by GitHub
parent 3a8baa0106
commit ad0be4ca06
27 changed files with 138 additions and 120 deletions

3
Cargo.lock generated
View File

@ -6938,6 +6938,7 @@ dependencies = [
"futures-util", "futures-util",
"parking_lot 0.12.3", "parking_lot 0.12.3",
"reth-execution-errors", "reth-execution-errors",
"reth-execution-types",
"reth-primitives", "reth-primitives",
"reth-prune-types", "reth-prune-types",
"reth-storage-errors", "reth-storage-errors",
@ -6953,6 +6954,7 @@ dependencies = [
"alloy-sol-types", "alloy-sol-types",
"reth-ethereum-consensus", "reth-ethereum-consensus",
"reth-evm", "reth-evm",
"reth-execution-types",
"reth-primitives", "reth-primitives",
"reth-prune-types", "reth-prune-types",
"reth-revm", "reth-revm",
@ -6995,7 +6997,6 @@ dependencies = [
name = "reth-execution-types" name = "reth-execution-types"
version = "0.2.0-beta.9" version = "0.2.0-beta.9"
dependencies = [ dependencies = [
"reth-evm",
"reth-execution-errors", "reth-execution-errors",
"reth-primitives", "reth-primitives",
"reth-trie", "reth-trie",

View File

@ -271,9 +271,15 @@ impl Command {
let db = StateProviderDatabase::new(blockchain_db.latest()?); let db = StateProviderDatabase::new(blockchain_db.latest()?);
let executor = block_executor!(provider_factory.chain_spec()).executor(db); let executor = block_executor!(provider_factory.chain_spec()).executor(db);
let BlockExecutionOutput { state, receipts, .. } = let BlockExecutionOutput { state, receipts, requests, .. } =
executor.execute((&block_with_senders.clone().unseal(), U256::MAX).into())?; executor.execute((&block_with_senders.clone().unseal(), U256::MAX).into())?;
let state = BundleStateWithReceipts::new(state, receipts.into(), block.number); let state = BundleStateWithReceipts::new(
state,
receipts.into(),
block.number,
vec![requests.into()],
);
debug!(target: "reth::cli", ?state, "Executed block"); debug!(target: "reth::cli", ?state, "Executed block");
let hashed_state = state.hash_state_slow(); let hashed_state = state.hash_state_slow();

View File

@ -135,7 +135,7 @@ impl Command {
let merkle_block_td = let merkle_block_td =
provider.header_td_by_number(merkle_block_number)?.unwrap_or_default(); provider.header_td_by_number(merkle_block_number)?.unwrap_or_default();
let BlockExecutionOutput { state, receipts, .. } = executor.execute( let BlockExecutionOutput { state, receipts, requests, .. } = executor.execute(
( (
&block &block
.clone() .clone()
@ -146,7 +146,12 @@ impl Command {
) )
.into(), .into(),
)?; )?;
let block_state = BundleStateWithReceipts::new(state, receipts.into(), block.number); let block_state = BundleStateWithReceipts::new(
state,
receipts.into(),
block.number,
vec![requests.into()],
);
// Unpacked `BundleState::state_root_slow` function // Unpacked `BundleState::state_root_slow` function
let (in_memory_state_root, in_memory_updates) = let (in_memory_state_root, in_memory_updates) =

View File

@ -14,14 +14,14 @@ use reth_config::Config;
use reth_consensus::Consensus; use reth_consensus::Consensus;
use reth_db::{tables, DatabaseEnv}; use reth_db::{tables, DatabaseEnv};
use reth_db_api::{cursor::DbCursorRO, transaction::DbTx}; use reth_db_api::{cursor::DbCursorRO, transaction::DbTx};
use reth_evm::execute::{BatchBlockExecutionOutput, BatchExecutor, BlockExecutorProvider}; use reth_evm::execute::{BatchExecutor, BlockExecutorProvider};
use reth_network::NetworkHandle; use reth_network::NetworkHandle;
use reth_network_api::NetworkInfo; use reth_network_api::NetworkInfo;
use reth_network_p2p::full_block::FullBlockClient; use reth_network_p2p::full_block::FullBlockClient;
use reth_primitives::{stage::StageCheckpoint, BlockHashOrNumber}; use reth_primitives::{stage::StageCheckpoint, BlockHashOrNumber};
use reth_provider::{ use reth_provider::{
BlockNumReader, BlockWriter, BundleStateWithReceipts, ChainSpecProvider, HeaderProvider, BlockNumReader, BlockWriter, ChainSpecProvider, HeaderProvider, LatestStateProviderRef,
LatestStateProviderRef, OriginalValuesKnown, ProviderError, ProviderFactory, StateWriter, OriginalValuesKnown, ProviderError, ProviderFactory, StateWriter,
}; };
use reth_prune_types::PruneModes; use reth_prune_types::PruneModes;
use reth_revm::database::StateProviderDatabase; use reth_revm::database::StateProviderDatabase;
@ -161,9 +161,7 @@ impl Command {
PruneModes::none(), PruneModes::none(),
); );
executor.execute_and_verify_one((&sealed_block.clone().unseal(), td).into())?; executor.execute_and_verify_one((&sealed_block.clone().unseal(), td).into())?;
let BatchBlockExecutionOutput { bundle, receipts, requests: _, first_block } = executor.finalize().write_to_storage(
executor.finalize();
BundleStateWithReceipts::new(bundle, receipts, first_block).write_to_storage(
provider_rw.tx_ref(), provider_rw.tx_ref(),
None, None,
OriginalValuesKnown::Yes, OriginalValuesKnown::Yes,

View File

@ -132,7 +132,12 @@ where
// We're reusing receipt writing code internal to // We're reusing receipt writing code internal to
// `BundleStateWithReceipts::write_to_storage`, so we just use a default empty // `BundleStateWithReceipts::write_to_storage`, so we just use a default empty
// `BundleState`. // `BundleState`.
let bundled_state = BundleStateWithReceipts::new(Default::default(), receipts, first_block); let bundled_state = BundleStateWithReceipts::new(
Default::default(),
receipts,
first_block,
Default::default(),
);
let static_file_producer = let static_file_producer =
static_file_provider.get_writer(first_block, StaticFileSegment::Receipts)?; static_file_provider.get_writer(first_block, StaticFileSegment::Receipts)?;

View File

@ -214,7 +214,12 @@ impl AppendableChain {
.consensus .consensus
.validate_block_post_execution(&block, PostExecutionInput::new(&receipts, &requests))?; .validate_block_post_execution(&block, PostExecutionInput::new(&receipts, &requests))?;
let bundle_state = BundleStateWithReceipts::new(state, receipts.into(), block.number); let bundle_state = BundleStateWithReceipts::new(
state,
receipts.into(),
block.number,
vec![requests.into()],
);
// check state root if the block extends the canonical chain __and__ if state root // check state root if the block extends the canonical chain __and__ if state root
// validation was requested. // validation was requested.

View File

@ -389,9 +389,14 @@ impl StorageInner {
); );
// execute the block // execute the block
let BlockExecutionOutput { state, receipts, .. } = let BlockExecutionOutput { state, receipts, requests: block_execution_requests, .. } =
executor.executor(&mut db).execute((&block, U256::ZERO).into())?; executor.executor(&mut db).execute((&block, U256::ZERO).into())?;
let bundle_state = BundleStateWithReceipts::new(state, receipts.into(), block.number); let bundle_state = BundleStateWithReceipts::new(
state,
receipts.into(),
block.number,
vec![block_execution_requests.into()],
);
// todo(onbjerg): we should not pass requests around as this is building a block, which // todo(onbjerg): we should not pass requests around as this is building a block, which
// means we need to extract the requests from the execution output and compute the requests // means we need to extract the requests from the execution output and compute the requests

View File

@ -17,6 +17,7 @@ reth-primitives.workspace = true
reth-revm.workspace = true reth-revm.workspace = true
reth-ethereum-consensus.workspace = true reth-ethereum-consensus.workspace = true
reth-prune-types.workspace = true reth-prune-types.workspace = true
reth-execution-types.workspace = true
# Ethereum # Ethereum
revm-primitives.workspace = true revm-primitives.workspace = true

View File

@ -7,11 +7,12 @@ use crate::{
use reth_ethereum_consensus::validate_block_post_execution; use reth_ethereum_consensus::validate_block_post_execution;
use reth_evm::{ use reth_evm::{
execute::{ execute::{
BatchBlockExecutionOutput, BatchExecutor, BlockExecutionError, BlockExecutionInput, BatchExecutor, BlockExecutionError, BlockExecutionInput, BlockExecutionOutput,
BlockExecutionOutput, BlockExecutorProvider, BlockValidationError, Executor, ProviderError, BlockExecutorProvider, BlockValidationError, Executor, ProviderError,
}, },
ConfigureEvm, ConfigureEvm,
}; };
use reth_execution_types::BundleStateWithReceipts;
use reth_primitives::{ use reth_primitives::{
BlockNumber, BlockWithSenders, ChainSpec, Hardfork, Header, Receipt, Request, Withdrawals, BlockNumber, BlockWithSenders, ChainSpec, Hardfork, Header, Receipt, Request, Withdrawals,
MAINNET, U256, MAINNET, U256,
@ -405,7 +406,7 @@ where
DB: Database<Error = ProviderError>, DB: Database<Error = ProviderError>,
{ {
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
type Output = BatchBlockExecutionOutput; type Output = BundleStateWithReceipts;
type Error = BlockExecutionError; type Error = BlockExecutionError;
fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> { fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> {
@ -435,11 +436,11 @@ where
fn finalize(mut self) -> Self::Output { fn finalize(mut self) -> Self::Output {
self.stats.log_debug(); self.stats.log_debug();
BatchBlockExecutionOutput::new( BundleStateWithReceipts::new(
self.executor.state.take_bundle(), self.executor.state.take_bundle(),
self.batch_record.take_receipts(), self.batch_record.take_receipts(),
self.batch_record.take_requests(),
self.batch_record.first_block().unwrap_or_default(), self.batch_record.first_block().unwrap_or_default(),
self.batch_record.take_requests(),
) )
} }

View File

@ -444,8 +444,12 @@ where
// and 4788 contract call // and 4788 contract call
db.merge_transitions(BundleRetention::PlainState); db.merge_transitions(BundleRetention::PlainState);
let bundle = let bundle = BundleStateWithReceipts::new(
BundleStateWithReceipts::new(db.take_bundle(), vec![receipts].into(), block_number); db.take_bundle(),
vec![receipts].into(),
block_number,
vec![requests.clone().unwrap_or_default()],
);
let receipts_root = bundle.receipts_root_slow(block_number).expect("Number is in range"); let receipts_root = bundle.receipts_root_slow(block_number).expect("Number is in range");
let logs_bloom = bundle.block_logs_bloom(block_number).expect("Number is in range"); let logs_bloom = bundle.block_logs_bloom(block_number).expect("Number is in range");

View File

@ -17,6 +17,7 @@ reth-primitives.workspace = true
revm-primitives.workspace = true revm-primitives.workspace = true
reth-prune-types.workspace = true reth-prune-types.workspace = true
reth-storage-errors.workspace = true reth-storage-errors.workspace = true
reth-execution-types.workspace = true
revm.workspace = true revm.workspace = true

View File

@ -14,7 +14,6 @@ workspace = true
reth-primitives.workspace = true reth-primitives.workspace = true
reth-execution-errors.workspace = true reth-execution-errors.workspace = true
reth-trie.workspace = true reth-trie.workspace = true
reth-evm.workspace = true
revm.workspace = true revm.workspace = true

View File

@ -1,9 +1,8 @@
use reth_evm::execute::BatchBlockExecutionOutput;
use reth_primitives::{ use reth_primitives::{
logs_bloom, logs_bloom,
revm::compat::{into_reth_acc, into_revm_acc}, revm::compat::{into_reth_acc, into_revm_acc},
Account, Address, BlockNumber, Bloom, Bytecode, Log, Receipt, Receipts, StorageEntry, B256, Account, Address, BlockNumber, Bloom, Bytecode, Log, Receipt, Receipts, Requests, StorageEntry,
U256, B256, U256,
}; };
use reth_trie::HashedPostState; use reth_trie::HashedPostState;
use revm::{ use revm::{
@ -27,23 +26,13 @@ pub struct BundleStateWithReceipts {
pub receipts: Receipts, pub receipts: Receipts,
/// First block of bundle state. /// First block of bundle state.
pub first_block: BlockNumber, pub first_block: BlockNumber,
} /// The collection of EIP-7685 requests.
/// Outer vector stores requests for each block sequentially.
// TODO(mattsse): unify the types, currently there's a cyclic dependency between /// The inner vector stores requests ordered by transaction number.
impl From<BatchBlockExecutionOutput> for BundleStateWithReceipts { ///
fn from(value: BatchBlockExecutionOutput) -> Self { /// A transaction may have zero or more requests, so the length of the inner vector is not
let BatchBlockExecutionOutput { bundle, receipts, requests: _, first_block } = value; /// guaranteed to be the same as the number of transactions.
Self { bundle, receipts, first_block } pub requests: Vec<Requests>,
}
}
// TODO(mattsse): unify the types, currently there's a cyclic dependency between
impl From<BundleStateWithReceipts> for BatchBlockExecutionOutput {
fn from(value: BundleStateWithReceipts) -> Self {
let BundleStateWithReceipts { bundle, receipts, first_block } = value;
// TODO(alexey): add requests
Self { bundle, receipts, requests: Vec::default(), first_block }
}
} }
/// Type used to initialize revms bundle state. /// Type used to initialize revms bundle state.
@ -58,8 +47,13 @@ pub type RevertsInit = HashMap<BlockNumber, HashMap<Address, AccountRevertInit>>
impl BundleStateWithReceipts { impl BundleStateWithReceipts {
/// Create Bundle State. /// Create Bundle State.
pub const fn new(bundle: BundleState, receipts: Receipts, first_block: BlockNumber) -> Self { pub const fn new(
Self { bundle, receipts, first_block } bundle: BundleState,
receipts: Receipts,
first_block: BlockNumber,
requests: Vec<Requests>,
) -> Self {
Self { bundle, receipts, first_block, requests }
} }
/// Create new bundle state with receipts. /// Create new bundle state with receipts.
@ -69,6 +63,7 @@ impl BundleStateWithReceipts {
contracts_init: Vec<(B256, Bytecode)>, contracts_init: Vec<(B256, Bytecode)>,
receipts: Receipts, receipts: Receipts,
first_block: BlockNumber, first_block: BlockNumber,
requests: Vec<Requests>,
) -> Self { ) -> Self {
// sort reverts by block number // sort reverts by block number
let mut reverts = revert_init.into_iter().collect::<Vec<_>>(); let mut reverts = revert_init.into_iter().collect::<Vec<_>>();
@ -97,7 +92,7 @@ impl BundleStateWithReceipts {
contracts_init.into_iter().map(|(code_hash, bytecode)| (code_hash, bytecode.0)), contracts_init.into_iter().map(|(code_hash, bytecode)| (code_hash, bytecode.0)),
); );
Self { bundle, receipts, first_block } Self { bundle, receipts, first_block, requests }
} }
/// Return revm bundle state. /// Return revm bundle state.

View File

@ -526,6 +526,7 @@ mod tests {
), ),
vec![vec![]].into(), vec![vec![]].into(),
1, 1,
vec![],
); );
let block_state2 = BundleStateWithReceipts::new( let block_state2 = BundleStateWithReceipts::new(
@ -541,6 +542,7 @@ mod tests {
), ),
vec![vec![]].into(), vec![vec![]].into(),
2, 2,
vec![],
); );
let mut block1 = SealedBlockWithSenders::default(); let mut block1 = SealedBlockWithSenders::default();

View File

@ -1,10 +1,10 @@
//! Helper type that represents one of two possible executor types //! Helper type that represents one of two possible executor types
use crate::execute::{ use crate::execute::{
BatchBlockExecutionOutput, BatchExecutor, BlockExecutionInput, BlockExecutionOutput, BatchExecutor, BlockExecutionInput, BlockExecutionOutput, BlockExecutorProvider, Executor,
BlockExecutorProvider, Executor,
}; };
use reth_execution_errors::BlockExecutionError; use reth_execution_errors::BlockExecutionError;
use reth_execution_types::BundleStateWithReceipts;
use reth_primitives::{BlockNumber, BlockWithSenders, Receipt}; use reth_primitives::{BlockNumber, BlockWithSenders, Receipt};
use reth_prune_types::PruneModes; use reth_prune_types::PruneModes;
use reth_storage_errors::provider::ProviderError; use reth_storage_errors::provider::ProviderError;
@ -76,19 +76,19 @@ where
A: for<'a> BatchExecutor< A: for<'a> BatchExecutor<
DB, DB,
Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, Input<'a> = BlockExecutionInput<'a, BlockWithSenders>,
Output = BatchBlockExecutionOutput, Output = BundleStateWithReceipts,
Error = BlockExecutionError, Error = BlockExecutionError,
>, >,
B: for<'a> BatchExecutor< B: for<'a> BatchExecutor<
DB, DB,
Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, Input<'a> = BlockExecutionInput<'a, BlockWithSenders>,
Output = BatchBlockExecutionOutput, Output = BundleStateWithReceipts,
Error = BlockExecutionError, Error = BlockExecutionError,
>, >,
DB: Database<Error = ProviderError>, DB: Database<Error = ProviderError>,
{ {
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
type Output = BatchBlockExecutionOutput; type Output = BundleStateWithReceipts;
type Error = BlockExecutionError; type Error = BlockExecutionError;
fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> { fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> {

View File

@ -1,6 +1,7 @@
//! Traits for execution. //! Traits for execution.
use reth_primitives::{BlockNumber, BlockWithSenders, Receipt, Receipts, Request, Requests, U256}; use reth_execution_types::BundleStateWithReceipts;
use reth_primitives::{BlockNumber, BlockWithSenders, Receipt, Request, U256};
use reth_prune_types::PruneModes; use reth_prune_types::PruneModes;
use revm::db::BundleState; use revm::db::BundleState;
use revm_primitives::db::Database; use revm_primitives::db::Database;
@ -103,40 +104,6 @@ pub struct BlockExecutionOutput<T> {
pub gas_used: u64, pub gas_used: u64,
} }
/// The output of a batch of ethereum blocks.
#[derive(Debug)]
pub struct BatchBlockExecutionOutput {
/// Bundle state with reverts.
pub bundle: BundleState,
/// The collection of receipts.
/// Outer vector stores receipts for each block sequentially.
/// The inner vector stores receipts ordered by transaction number.
///
/// If receipt is None it means it is pruned.
pub receipts: Receipts,
/// The collection of EIP-7685 requests.
/// Outer vector stores requests for each block sequentially.
/// The inner vector stores requests ordered by transaction number.
///
/// A transaction may have zero or more requests, so the length of the inner vector is not
/// guaranteed to be the same as the number of transactions.
pub requests: Vec<Requests>,
/// First block of bundle state.
pub first_block: BlockNumber,
}
impl BatchBlockExecutionOutput {
/// Create Bundle State.
pub fn new(
bundle: BundleState,
receipts: Receipts,
requests: Vec<Requests>,
first_block: BlockNumber,
) -> Self {
Self { bundle, receipts, requests, first_block }
}
}
/// A helper type for ethereum block inputs that consists of a block and the total difficulty. /// A helper type for ethereum block inputs that consists of a block and the total difficulty.
#[derive(Debug)] #[derive(Debug)]
pub struct BlockExecutionInput<'a, Block> { pub struct BlockExecutionInput<'a, Block> {
@ -183,8 +150,7 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static {
type BatchExecutor<DB: Database<Error = ProviderError>>: for<'a> BatchExecutor< type BatchExecutor<DB: Database<Error = ProviderError>>: for<'a> BatchExecutor<
DB, DB,
Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, Input<'a> = BlockExecutionInput<'a, BlockWithSenders>,
// TODO: change to bundle state with receipts Output = BundleStateWithReceipts,
Output = BatchBlockExecutionOutput,
Error = BlockExecutionError, Error = BlockExecutionError,
>; >;
@ -250,7 +216,7 @@ mod tests {
impl<DB> BatchExecutor<DB> for TestExecutor<DB> { impl<DB> BatchExecutor<DB> for TestExecutor<DB> {
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
type Output = BatchBlockExecutionOutput; type Output = BundleStateWithReceipts;
type Error = BlockExecutionError; type Error = BlockExecutionError;
fn execute_and_verify_one(&mut self, _input: Self::Input<'_>) -> Result<(), Self::Error> { fn execute_and_verify_one(&mut self, _input: Self::Input<'_>) -> Result<(), Self::Error> {

View File

@ -1,14 +1,14 @@
//! A no operation block executor implementation. //! A no operation block executor implementation.
use reth_execution_errors::BlockExecutionError; use reth_execution_errors::BlockExecutionError;
use reth_execution_types::BundleStateWithReceipts;
use reth_primitives::{BlockNumber, BlockWithSenders, Receipt}; use reth_primitives::{BlockNumber, BlockWithSenders, Receipt};
use reth_prune_types::PruneModes; use reth_prune_types::PruneModes;
use reth_storage_errors::provider::ProviderError; use reth_storage_errors::provider::ProviderError;
use revm_primitives::db::Database; use revm_primitives::db::Database;
use crate::execute::{ use crate::execute::{
BatchBlockExecutionOutput, BatchExecutor, BlockExecutionInput, BlockExecutionOutput, BatchExecutor, BlockExecutionInput, BlockExecutionOutput, BlockExecutorProvider, Executor,
BlockExecutorProvider, Executor,
}; };
const UNAVAILABLE_FOR_NOOP: &str = "execution unavailable for noop"; const UNAVAILABLE_FOR_NOOP: &str = "execution unavailable for noop";
@ -50,7 +50,7 @@ impl<DB> Executor<DB> for NoopBlockExecutorProvider {
impl<DB> BatchExecutor<DB> for NoopBlockExecutorProvider { impl<DB> BatchExecutor<DB> for NoopBlockExecutorProvider {
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
type Output = BatchBlockExecutionOutput; type Output = BundleStateWithReceipts;
type Error = BlockExecutionError; type Error = BlockExecutionError;
fn execute_and_verify_one(&mut self, _: Self::Input<'_>) -> Result<(), Self::Error> { fn execute_and_verify_one(&mut self, _: Self::Input<'_>) -> Result<(), Self::Error> {

View File

@ -1,11 +1,11 @@
//! Helpers for testing. //! Helpers for testing.
use crate::execute::{ use crate::execute::{
BatchBlockExecutionOutput, BatchExecutor, BlockExecutionInput, BlockExecutionOutput, BatchExecutor, BlockExecutionInput, BlockExecutionOutput, BlockExecutorProvider, Executor,
BlockExecutorProvider, Executor,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;
use reth_execution_errors::BlockExecutionError; use reth_execution_errors::BlockExecutionError;
use reth_execution_types::BundleStateWithReceipts;
use reth_primitives::{BlockNumber, BlockWithSenders, Receipt}; use reth_primitives::{BlockNumber, BlockWithSenders, Receipt};
use reth_prune_types::PruneModes; use reth_prune_types::PruneModes;
use reth_storage_errors::provider::ProviderError; use reth_storage_errors::provider::ProviderError;
@ -15,12 +15,12 @@ use std::sync::Arc;
/// A [`BlockExecutorProvider`] that returns mocked execution results. /// A [`BlockExecutorProvider`] that returns mocked execution results.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct MockExecutorProvider { pub struct MockExecutorProvider {
exec_results: Arc<Mutex<Vec<BatchBlockExecutionOutput>>>, exec_results: Arc<Mutex<Vec<BundleStateWithReceipts>>>,
} }
impl MockExecutorProvider { impl MockExecutorProvider {
/// Extend the mocked execution results /// Extend the mocked execution results
pub fn extend(&self, results: impl IntoIterator<Item = impl Into<BatchBlockExecutionOutput>>) { pub fn extend(&self, results: impl IntoIterator<Item = impl Into<BundleStateWithReceipts>>) {
self.exec_results.lock().extend(results.into_iter().map(Into::into)); self.exec_results.lock().extend(results.into_iter().map(Into::into));
} }
} }
@ -51,7 +51,7 @@ impl<DB> Executor<DB> for MockExecutorProvider {
type Error = BlockExecutionError; type Error = BlockExecutionError;
fn execute(self, _: Self::Input<'_>) -> Result<Self::Output, Self::Error> { fn execute(self, _: Self::Input<'_>) -> Result<Self::Output, Self::Error> {
let BatchBlockExecutionOutput { bundle, receipts, requests, first_block: _ } = let BundleStateWithReceipts { bundle, receipts, requests, first_block: _ } =
self.exec_results.lock().pop().unwrap(); self.exec_results.lock().pop().unwrap();
Ok(BlockExecutionOutput { Ok(BlockExecutionOutput {
state: bundle, state: bundle,
@ -64,7 +64,7 @@ impl<DB> Executor<DB> for MockExecutorProvider {
impl<DB> BatchExecutor<DB> for MockExecutorProvider { impl<DB> BatchExecutor<DB> for MockExecutorProvider {
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
type Output = BatchBlockExecutionOutput; type Output = BundleStateWithReceipts;
type Error = BlockExecutionError; type Error = BlockExecutionError;
fn execute_and_verify_one(&mut self, _: Self::Input<'_>) -> Result<(), Self::Error> { fn execute_and_verify_one(&mut self, _: Self::Input<'_>) -> Result<(), Self::Error> {

View File

@ -3,8 +3,8 @@
use crate::{l1::ensure_create2_deployer, OptimismBlockExecutionError, OptimismEvmConfig}; use crate::{l1::ensure_create2_deployer, OptimismBlockExecutionError, OptimismEvmConfig};
use reth_evm::{ use reth_evm::{
execute::{ execute::{
BatchBlockExecutionOutput, BatchExecutor, BlockExecutionError, BlockExecutionInput, BatchExecutor, BlockExecutionError, BlockExecutionInput, BlockExecutionOutput,
BlockExecutionOutput, BlockExecutorProvider, BlockValidationError, Executor, ProviderError, BlockExecutorProvider, BlockValidationError, Executor, ProviderError,
}, },
ConfigureEvm, ConfigureEvm,
}; };
@ -13,6 +13,7 @@ use reth_primitives::{
BlockNumber, BlockWithSenders, ChainSpec, Hardfork, Header, Receipt, Receipts, TxType, BlockNumber, BlockWithSenders, ChainSpec, Hardfork, Header, Receipt, Receipts, TxType,
Withdrawals, U256, Withdrawals, U256,
}; };
use reth_provider::BundleStateWithReceipts;
use reth_prune_types::PruneModes; use reth_prune_types::PruneModes;
use reth_revm::{ use reth_revm::{
batch::{BlockBatchRecord, BlockExecutorStats}, batch::{BlockBatchRecord, BlockExecutorStats},
@ -396,7 +397,7 @@ where
DB: Database<Error = ProviderError>, DB: Database<Error = ProviderError>,
{ {
type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>; type Input<'a> = BlockExecutionInput<'a, BlockWithSenders>;
type Output = BatchBlockExecutionOutput; type Output = BundleStateWithReceipts;
type Error = BlockExecutionError; type Error = BlockExecutionError;
fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> { fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> {
@ -423,11 +424,11 @@ where
fn finalize(mut self) -> Self::Output { fn finalize(mut self) -> Self::Output {
self.stats.log_debug(); self.stats.log_debug();
BatchBlockExecutionOutput::new( BundleStateWithReceipts::new(
self.executor.state.take_bundle(), self.executor.state.take_bundle(),
self.batch_record.take_receipts(), self.batch_record.take_receipts(),
self.batch_record.take_requests(),
self.batch_record.first_block().unwrap_or_default(), self.batch_record.first_block().unwrap_or_default(),
self.batch_record.take_requests(),
) )
} }

View File

@ -506,8 +506,12 @@ where
// and 4788 contract call // and 4788 contract call
db.merge_transitions(BundleRetention::PlainState); db.merge_transitions(BundleRetention::PlainState);
let bundle = let bundle = BundleStateWithReceipts::new(
BundleStateWithReceipts::new(db.take_bundle(), vec![receipts].into(), block_number); db.take_bundle(),
vec![receipts].into(),
block_number,
Vec::new(),
);
let receipts_root = bundle let receipts_root = bundle
.optimism_receipts_root_slow( .optimism_receipts_root_slow(
block_number, block_number,

View File

@ -220,8 +220,12 @@ impl PendingBlockEnv {
// merge all transitions into bundle state. // merge all transitions into bundle state.
db.merge_transitions(BundleRetention::PlainState); db.merge_transitions(BundleRetention::PlainState);
let bundle = let bundle = BundleStateWithReceipts::new(
BundleStateWithReceipts::new(db.take_bundle(), vec![receipts].into(), block_number); db.take_bundle(),
vec![receipts].into(),
block_number,
Vec::new(),
);
#[cfg(feature = "optimism")] #[cfg(feature = "optimism")]
let receipts_root = bundle let receipts_root = bundle

View File

@ -3,7 +3,7 @@ use num_traits::Zero;
use reth_config::config::ExecutionConfig; use reth_config::config::ExecutionConfig;
use reth_db::{static_file::HeaderMask, tables}; use reth_db::{static_file::HeaderMask, tables};
use reth_db_api::{cursor::DbCursorRO, database::Database, transaction::DbTx}; use reth_db_api::{cursor::DbCursorRO, database::Database, transaction::DbTx};
use reth_evm::execute::{BatchBlockExecutionOutput, BatchExecutor, BlockExecutorProvider}; use reth_evm::execute::{BatchExecutor, BlockExecutorProvider};
use reth_exex::{ExExManagerHandle, ExExNotification}; use reth_exex::{ExExManagerHandle, ExExNotification};
use reth_primitives::{ use reth_primitives::{
stage::{ stage::{
@ -289,9 +289,9 @@ where
} }
} }
let time = Instant::now(); let time = Instant::now();
let BatchBlockExecutionOutput { bundle, receipts, requests: _, first_block } = let BundleStateWithReceipts { bundle, receipts, requests, first_block } =
executor.finalize(); executor.finalize();
let state = BundleStateWithReceipts::new(bundle, receipts, first_block); let state = BundleStateWithReceipts::new(bundle, receipts, first_block, requests);
let write_preparation_duration = time.elapsed(); let write_preparation_duration = time.elapsed();
// Check if we should send a [`ExExNotification`] to execution extensions. // Check if we should send a [`ExExNotification`] to execution extensions.

View File

@ -199,6 +199,7 @@ pub fn insert_state<'a, 'b, DB: Database>(
contracts.into_iter().collect(), contracts.into_iter().collect(),
Receipts::default(), Receipts::default(),
block, block,
Vec::new(),
); );
bundle.write_to_storage(tx, None, OriginalValuesKnown::Yes)?; bundle.write_to_storage(tx, None, OriginalValuesKnown::Yes)?;

View File

@ -288,7 +288,7 @@ mod tests {
state.merge_transitions(BundleRetention::Reverts); state.merge_transitions(BundleRetention::Reverts);
BundleStateWithReceipts::new(state.take_bundle(), Receipts::default(), 1) BundleStateWithReceipts::new(state.take_bundle(), Receipts::default(), 1, Vec::new())
.write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes) .write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes)
.expect("Could not write bundle state to DB"); .expect("Could not write bundle state to DB");
@ -386,7 +386,7 @@ mod tests {
)])); )]));
state.merge_transitions(BundleRetention::Reverts); state.merge_transitions(BundleRetention::Reverts);
BundleStateWithReceipts::new(state.take_bundle(), Receipts::default(), 2) BundleStateWithReceipts::new(state.take_bundle(), Receipts::default(), 2, Vec::new())
.write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes) .write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes)
.expect("Could not write bundle state to DB"); .expect("Could not write bundle state to DB");
@ -450,7 +450,7 @@ mod tests {
}, },
)])); )]));
init_state.merge_transitions(BundleRetention::Reverts); init_state.merge_transitions(BundleRetention::Reverts);
BundleStateWithReceipts::new(init_state.take_bundle(), Receipts::default(), 0) BundleStateWithReceipts::new(init_state.take_bundle(), Receipts::default(), 0, Vec::new())
.write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes) .write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes)
.expect("Could not write init bundle state to DB"); .expect("Could not write init bundle state to DB");
@ -592,7 +592,7 @@ mod tests {
let bundle = state.take_bundle(); let bundle = state.take_bundle();
BundleStateWithReceipts::new(bundle, Receipts::default(), 1) BundleStateWithReceipts::new(bundle, Receipts::default(), 1, Vec::new())
.write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes) .write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes)
.expect("Could not write bundle state to DB"); .expect("Could not write bundle state to DB");
@ -755,7 +755,7 @@ mod tests {
}, },
)])); )]));
init_state.merge_transitions(BundleRetention::Reverts); init_state.merge_transitions(BundleRetention::Reverts);
BundleStateWithReceipts::new(init_state.take_bundle(), Receipts::default(), 0) BundleStateWithReceipts::new(init_state.take_bundle(), Receipts::default(), 0, Vec::new())
.write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes) .write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes)
.expect("Could not write init bundle state to DB"); .expect("Could not write init bundle state to DB");
@ -800,7 +800,7 @@ mod tests {
// Commit block #1 changes to the database. // Commit block #1 changes to the database.
state.merge_transitions(BundleRetention::Reverts); state.merge_transitions(BundleRetention::Reverts);
BundleStateWithReceipts::new(state.take_bundle(), Receipts::default(), 1) BundleStateWithReceipts::new(state.take_bundle(), Receipts::default(), 1, Vec::new())
.write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes) .write_to_storage(provider.tx_ref(), None, OriginalValuesKnown::Yes)
.expect("Could not write bundle state to DB"); .expect("Could not write bundle state to DB");
@ -834,6 +834,7 @@ mod tests {
bundle: BundleState::default(), bundle: BundleState::default(),
receipts: vec![vec![Some(Receipt::default()); 2]; 7].into(), receipts: vec![vec![Some(Receipt::default()); 2]; 7].into(),
first_block: 10, first_block: 10,
requests: Vec::new(),
}; };
let mut this = base.clone(); let mut this = base.clone();
@ -895,10 +896,15 @@ mod tests {
let assert_state_root = |state: &State<EmptyDB>, expected: &PreState, msg| { let assert_state_root = |state: &State<EmptyDB>, expected: &PreState, msg| {
assert_eq!( assert_eq!(
BundleStateWithReceipts::new(state.bundle_state.clone(), Receipts::default(), 0) BundleStateWithReceipts::new(
.hash_state_slow() state.bundle_state.clone(),
.state_root(&tx) Receipts::default(),
.unwrap(), 0,
Vec::new()
)
.hash_state_slow()
.state_root(&tx)
.unwrap(),
state_root(expected.clone().into_iter().map(|(address, (account, storage))| ( state_root(expected.clone().into_iter().map(|(address, (account, storage))| (
address, address,
(account, storage.into_iter()) (account, storage.into_iter())
@ -1045,6 +1051,7 @@ mod tests {
bundle: present_state, bundle: present_state,
receipts: vec![vec![Some(Receipt::default()); 2]; 1].into(), receipts: vec![vec![Some(Receipt::default()); 2]; 1].into(),
first_block: 2, first_block: 2,
requests: Vec::new(),
}; };
test.prepend_state(previous_state); test.prepend_state(previous_state);

View File

@ -539,6 +539,7 @@ impl<TX: DbTxMut + DbTx> DatabaseProvider<TX> {
Vec::new(), Vec::new(),
receipts.into(), receipts.into(),
start_block_number, start_block_number,
Vec::new(),
)) ))
} }

View File

@ -166,6 +166,7 @@ fn block1(number: BlockNumber) -> (SealedBlockWithSenders, BundleStateWithReceip
})]] })]]
.into(), .into(),
number, number,
Vec::new(),
); );
let state_root = bundle_state_root(&bundle); let state_root = bundle_state_root(&bundle);
@ -225,6 +226,7 @@ fn block2(
})]] })]]
.into(), .into(),
number, number,
Vec::new(),
); );
let mut extended = prev_state.clone(); let mut extended = prev_state.clone();
@ -294,6 +296,7 @@ fn block3(
})]] })]]
.into(), .into(),
number, number,
Vec::new(),
); );
let mut extended = prev_state.clone(); let mut extended = prev_state.clone();
@ -384,6 +387,7 @@ fn block4(
})]] })]]
.into(), .into(),
number, number,
Vec::new(),
); );
let mut extended = prev_state.clone(); let mut extended = prev_state.clone();
@ -469,6 +473,7 @@ fn block5(
})]] })]]
.into(), .into(),
number, number,
Vec::new(),
); );
let mut extended = prev_state.clone(); let mut extended = prev_state.clone();

View File

@ -345,6 +345,7 @@ mod tests {
BundleState::default(), BundleState::default(),
vec![deposit_tx_receipt, withdrawal_tx_receipt].into(), vec![deposit_tx_receipt, withdrawal_tx_receipt].into(),
block.number, block.number,
vec![block.requests.clone().unwrap_or_default()],
), ),
None, None,
); );