diff --git a/crates/blockchain-tree/src/state.rs b/crates/blockchain-tree/src/state.rs index ca8af6f9b581..fa8a65b72f7d 100644 --- a/crates/blockchain-tree/src/state.rs +++ b/crates/blockchain-tree/src/state.rs @@ -405,7 +405,14 @@ mod tests { // Create a chain with the block and its receipts let chain = AppendableChain::new(Chain::new( vec![block.clone()], - ExecutionOutcome { receipts: receipts.clone().into(), ..Default::default() }, + ExecutionOutcome { + receipts: receipts + .iter() + .map(|receipt| Some(receipt.clone())) + .collect::>() + .into(), + ..Default::default() + }, Default::default(), )); diff --git a/crates/chain-state/src/test_utils.rs b/crates/chain-state/src/test_utils.rs index 564df9fe341a..0a131e12f0df 100644 --- a/crates/chain-state/src/test_utils.rs +++ b/crates/chain-state/src/test_utils.rs @@ -287,7 +287,8 @@ impl TestBlockBuilder { Vec::new(), ); - execution_outcome.with_receipts(Receipts::from(receipts)) + execution_outcome + .with_receipts(receipts.into_iter().map(Option::Some).collect::>().into()) } } /// A test `ChainEventSubscriptions` diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index 026e6b37c42c..194dba40ac08 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -197,10 +197,22 @@ impl ExecutionOutcome { #[cfg(feature = "optimism")] panic!("This should not be called in optimism mode. Use `optimism_receipts_root_slow` instead."); #[cfg(not(feature = "optimism"))] - self.receipts.root_slow( - self.block_number_to_index(_block_number)?, - reth_primitives::proofs::calculate_receipt_root_no_memo, - ) + { + // TODO: This is a temporary solution until we eliminate the `Option` from `Receipts`. + // We can then apply directly: + // ```rust + // self.receipts + // .receipt_vec + // .get(self.block_number_to_index(_block_number)?) + // .map(|receipts| reth_primitives::proofs::calculate_receipt_root_no_memo(receipts)) + // ``` + let receipts = self.receipts().receipt_vec + [self.block_number_to_index(_block_number)?] + .iter() + .map(Option::as_ref) + .collect::>>()?; + Some(reth_primitives::proofs::calculate_receipt_root_no_memo(receipts.as_slice())) + } } /// Returns the receipt root for all recorded receipts. @@ -211,7 +223,19 @@ impl ExecutionOutcome { block_number: BlockNumber, f: impl FnOnce(&[&Receipt]) -> B256, ) -> Option { - self.receipts.root_slow(self.block_number_to_index(block_number)?, f) + // TODO: This is a temporary solution until we eliminate the `Option` from `Receipts`. + // We can then apply directly: + // ```rust + // self.receipts + // .receipt_vec + // .get(self.block_number_to_index(block_number)?) + // .map(|receipts| f(receipts)) + // ``` + let receipts = self.receipts.receipt_vec[self.block_number_to_index(block_number)?] + .iter() + .map(Option::as_ref) + .collect::>>()?; + Some(f(receipts.as_slice())) } /// Returns reference to receipts. @@ -356,7 +380,7 @@ impl From<(BlockExecutionOutput, BlockNumber)> for ExecutionOutcome { fn from(value: (BlockExecutionOutput, BlockNumber)) -> Self { Self { bundle: value.0.state, - receipts: Receipts::from(value.0.receipts), + receipts: value.0.receipts.into_iter().map(Some).collect::>().into(), first_block: value.1, requests: vec![value.0.requests], } diff --git a/crates/exex/exex/src/backfill/test_utils.rs b/crates/exex/exex/src/backfill/test_utils.rs index 0a8bde242457..491433f68dcd 100644 --- a/crates/exex/exex/src/backfill/test_utils.rs +++ b/crates/exex/exex/src/backfill/test_utils.rs @@ -26,7 +26,13 @@ pub(crate) fn to_execution_outcome( ) -> ExecutionOutcome { ExecutionOutcome { bundle: block_execution_output.state.clone(), - receipts: block_execution_output.receipts.clone().into(), + receipts: block_execution_output + .receipts + .clone() + .into_iter() + .map(Option::Some) + .collect::>() + .into(), first_block: block_number, requests: vec![block_execution_output.requests.clone()], } diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 21443f482c91..7642c3f710f7 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -6,11 +6,11 @@ use alloy_consensus::constants::{ EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID, }; use alloy_eips::eip2718::Encodable2718; -use alloy_primitives::{Bloom, Log, B256}; +use alloy_primitives::{Bloom, Log}; use alloy_rlp::{length_of_length, Decodable, Encodable, RlpDecodable, RlpEncodable}; use bytes::{Buf, BufMut}; use core::{cmp::Ordering, ops::Deref}; -use derive_more::{DerefMut, From, IntoIterator}; +use derive_more::{From, IntoIterator}; #[cfg(feature = "reth-codec")] use reth_codecs::Compact; use serde::{Deserialize, Serialize}; @@ -67,59 +67,7 @@ impl Receipt { } /// A collection of receipts organized as a two-dimensional vector. -#[derive( - Clone, - Debug, - PartialEq, - Eq, - Default, - Serialize, - Deserialize, - From, - derive_more::Deref, - DerefMut, - IntoIterator, -)] -pub struct Receipts { - /// A two-dimensional vector of optional `Receipt` instances. - pub receipt_vec: Vec>>, -} - -impl Receipts { - /// Returns the length of the `Receipts` vector. - pub fn len(&self) -> usize { - self.receipt_vec.len() - } - - /// Returns `true` if the `Receipts` vector is empty. - pub fn is_empty(&self) -> bool { - self.receipt_vec.is_empty() - } - - /// Push a new vector of receipts into the `Receipts` collection. - pub fn push(&mut self, receipts: Vec>) { - self.receipt_vec.push(receipts); - } - - /// Retrieves all recorded receipts from index and calculates the root using the given closure. - pub fn root_slow(&self, index: usize, f: impl FnOnce(&[&Receipt]) -> B256) -> Option { - let receipts = - self.receipt_vec[index].iter().map(Option::as_ref).collect::>>()?; - Some(f(receipts.as_slice())) - } -} - -impl From> for Receipts { - fn from(block_receipts: Vec) -> Self { - Self { receipt_vec: vec![block_receipts.into_iter().map(Option::Some).collect()] } - } -} - -impl FromIterator>> for Receipts { - fn from_iter>>>(iter: I) -> Self { - iter.into_iter().collect::>().into() - } -} +pub type Receipts = alloy_consensus::Receipts>; impl From for ReceiptWithBloom { fn from(receipt: Receipt) -> Self { diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 64a8a204a329..dd3fe54925b0 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -921,8 +921,14 @@ mod tests { .map(|block| { let senders = block.senders().expect("failed to recover senders"); let block_receipts = receipts.get(block.number as usize).unwrap().clone(); - let execution_outcome = - ExecutionOutcome { receipts: block_receipts.into(), ..Default::default() }; + let execution_outcome = ExecutionOutcome { + receipts: block_receipts + .into_iter() + .map(Option::Some) + .collect::>() + .into(), + ..Default::default() + }; ExecutedBlock::new( Arc::new(block.clone()),