diff --git a/crates/chain-state/src/in_memory.rs b/crates/chain-state/src/in_memory.rs index cf1ddf413bf..f8cddcda160 100644 --- a/crates/chain-state/src/in_memory.rs +++ b/crates/chain-state/src/in_memory.rs @@ -822,6 +822,8 @@ impl> NewCanonicalChain { chain.append_block( exec.recovered_block().clone(), exec.execution_outcome().clone(), + Arc::new((*exec.trie_updates).clone().into()), + Arc::new((*exec.hashed_state).clone().into()), ); chain })); @@ -832,6 +834,8 @@ impl> NewCanonicalChain { chain.append_block( exec.recovered_block().clone(), exec.execution_outcome().clone(), + Arc::new((*exec.trie_updates).clone().into()), + Arc::new((*exec.hashed_state).clone().into()), ); chain })); @@ -839,6 +843,8 @@ impl> NewCanonicalChain { chain.append_block( exec.recovered_block().clone(), exec.execution_outcome().clone(), + Arc::new((*exec.trie_updates).clone().into()), + Arc::new((*exec.hashed_state).clone().into()), ); chain })); @@ -1424,13 +1430,29 @@ mod tests { // Test commit notification let chain_commit = NewCanonicalChain::Commit { new: vec![block0.clone(), block1.clone()] }; + // Build expected trie updates map + let mut expected_trie_updates: BTreeMap> = BTreeMap::new(); + expected_trie_updates + .insert(0, Arc::new(TrieUpdates::from((*block0.trie_updates).clone()))); + expected_trie_updates + .insert(1, Arc::new(TrieUpdates::from((*block1.trie_updates).clone()))); + + // Build expected hashed state map + let mut expected_hashed_state: BTreeMap> = + BTreeMap::new(); + expected_hashed_state + .insert(0, Arc::new(HashedPostState::from((*block0.hashed_state).clone()))); + expected_hashed_state + .insert(1, Arc::new(HashedPostState::from((*block1.hashed_state).clone()))); + assert_eq!( chain_commit.to_chain_notification(), CanonStateNotification::Commit { new: Arc::new(Chain::new( vec![block0.recovered_block().clone(), block1.recovered_block().clone()], sample_execution_outcome.clone(), - None + expected_trie_updates, + expected_hashed_state )) } ); @@ -1441,18 +1463,39 @@ mod tests { old: vec![block1.clone(), block2.clone()], }; + // Build expected trie updates for old chain + let mut old_trie_updates: BTreeMap> = BTreeMap::new(); + old_trie_updates.insert(1, Arc::new(TrieUpdates::from((*block1.trie_updates).clone()))); + old_trie_updates.insert(2, Arc::new(TrieUpdates::from((*block2.trie_updates).clone()))); + + // Build expected trie updates for new chain + let mut new_trie_updates: BTreeMap> = BTreeMap::new(); + new_trie_updates.insert(1, Arc::new(TrieUpdates::from((*block1a.trie_updates).clone()))); + new_trie_updates.insert(2, Arc::new(TrieUpdates::from((*block2a.trie_updates).clone()))); + // Build expected hashed state for old chain + let mut old_hashed_state: BTreeMap> = BTreeMap::new(); + old_hashed_state.insert(1, Arc::new(HashedPostState::from((*block1.hashed_state).clone()))); + old_hashed_state.insert(2, Arc::new(HashedPostState::from((*block2.hashed_state).clone()))); + // Build expected hashed state for new chain + let mut new_hashed_state: BTreeMap> = BTreeMap::new(); + new_hashed_state + .insert(1, Arc::new(HashedPostState::from((*block1a.hashed_state).clone()))); + new_hashed_state + .insert(2, Arc::new(HashedPostState::from((*block2a.hashed_state).clone()))); assert_eq!( chain_reorg.to_chain_notification(), CanonStateNotification::Reorg { old: Arc::new(Chain::new( vec![block1.recovered_block().clone(), block2.recovered_block().clone()], sample_execution_outcome.clone(), - None + old_trie_updates, + old_hashed_state )), new: Arc::new(Chain::new( vec![block1a.recovered_block().clone(), block2a.recovered_block().clone()], sample_execution_outcome, - None + new_trie_updates, + new_hashed_state )) } ); diff --git a/crates/chain-state/src/notifications.rs b/crates/chain-state/src/notifications.rs index 1d2f4df10fa..f5d7f9fd0b0 100644 --- a/crates/chain-state/src/notifications.rs +++ b/crates/chain-state/src/notifications.rs @@ -242,6 +242,7 @@ mod tests { use reth_ethereum_primitives::{Receipt, TransactionSigned, TxType}; use reth_execution_types::ExecutionOutcome; use reth_primitives_traits::SealedBlock; + use std::collections::BTreeMap; #[test] fn test_commit_notification() { @@ -260,7 +261,8 @@ mod tests { let chain: Arc = Arc::new(Chain::new( vec![block1.clone(), block2.clone()], ExecutionOutcome::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )); // Create a commit notification @@ -295,12 +297,17 @@ mod tests { block3.set_block_number(3); block3.set_hash(block3_hash); - let old_chain: Arc = - Arc::new(Chain::new(vec![block1.clone()], ExecutionOutcome::default(), None)); + let old_chain: Arc = Arc::new(Chain::new( + vec![block1.clone()], + ExecutionOutcome::default(), + BTreeMap::new(), + BTreeMap::new(), + )); let new_chain = Arc::new(Chain::new( vec![block2.clone(), block3.clone()], ExecutionOutcome::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )); // Create a reorg notification @@ -362,8 +369,12 @@ mod tests { let execution_outcome = ExecutionOutcome { receipts, ..Default::default() }; // Create a new chain segment with `block1` and `block2` and the execution outcome. - let new_chain: Arc = - Arc::new(Chain::new(vec![block1.clone(), block2.clone()], execution_outcome, None)); + let new_chain: Arc = Arc::new(Chain::new( + vec![block1.clone(), block2.clone()], + execution_outcome, + BTreeMap::new(), + BTreeMap::new(), + )); // Create a commit notification containing the new chain segment. let notification = CanonStateNotification::Commit { new: new_chain }; @@ -420,8 +431,12 @@ mod tests { ExecutionOutcome { receipts: old_receipts, ..Default::default() }; // Create an old chain segment to be reverted, containing `old_block1`. - let old_chain: Arc = - Arc::new(Chain::new(vec![old_block1.clone()], old_execution_outcome, None)); + let old_chain: Arc = Arc::new(Chain::new( + vec![old_block1.clone()], + old_execution_outcome, + BTreeMap::new(), + BTreeMap::new(), + )); // Define block2 for the new chain segment, which will be committed. let mut body = BlockBody::::default(); @@ -449,7 +464,12 @@ mod tests { ExecutionOutcome { receipts: new_receipts, ..Default::default() }; // Create a new chain segment to be committed, containing `new_block1`. - let new_chain = Arc::new(Chain::new(vec![new_block1.clone()], new_execution_outcome, None)); + let new_chain = Arc::new(Chain::new( + vec![new_block1.clone()], + new_execution_outcome, + BTreeMap::new(), + BTreeMap::new(), + )); // Create a reorg notification with both reverted (old) and committed (new) chain segments. let notification = CanonStateNotification::Reorg { old: old_chain, new: new_chain }; diff --git a/crates/evm/execution-types/src/chain.rs b/crates/evm/execution-types/src/chain.rs index dc7218631f9..ae6719246c1 100644 --- a/crates/evm/execution-types/src/chain.rs +++ b/crates/evm/execution-types/src/chain.rs @@ -1,7 +1,7 @@ //! Contains [Chain], a chain of blocks and their final state. use crate::ExecutionOutcome; -use alloc::{borrow::Cow, collections::BTreeMap, vec::Vec}; +use alloc::{borrow::Cow, collections::BTreeMap, sync::Arc, vec::Vec}; use alloy_consensus::{transaction::Recovered, BlockHeader}; use alloy_eips::{eip1898::ForkBlock, eip2718::Encodable2718, BlockNumHash}; use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash}; @@ -10,8 +10,7 @@ use reth_primitives_traits::{ transaction::signed::SignedTransaction, Block, BlockBody, NodePrimitives, RecoveredBlock, SealedHeader, }; -use reth_trie_common::updates::TrieUpdates; -use revm::database::BundleState; +use reth_trie_common::{updates::TrieUpdates, HashedPostState}; /// A chain of blocks and their final state. /// @@ -35,10 +34,10 @@ pub struct Chain { /// /// Additionally, it includes the individual state changes that led to the current state. execution_outcome: ExecutionOutcome, - /// State trie updates after block is added to the chain. - /// NOTE: Currently, trie updates are present only for - /// single-block chains that extend the canonical chain. - trie_updates: Option, + /// State trie updates for each block in the chain, keyed by block number. + trie_updates: BTreeMap>, + /// Hashed post state for each block in the chain, keyed by block number. + hashed_state: BTreeMap>, } impl Default for Chain { @@ -47,6 +46,7 @@ impl Default for Chain { blocks: Default::default(), execution_outcome: Default::default(), trie_updates: Default::default(), + hashed_state: Default::default(), } } } @@ -60,22 +60,27 @@ impl Chain { pub fn new( blocks: impl IntoIterator>, execution_outcome: ExecutionOutcome, - trie_updates: Option, + trie_updates: BTreeMap>, + hashed_state: BTreeMap>, ) -> Self { let blocks = blocks.into_iter().map(|b| (b.header().number(), b)).collect::>(); debug_assert!(!blocks.is_empty(), "Chain should have at least one block"); - Self { blocks, execution_outcome, trie_updates } + Self { blocks, execution_outcome, trie_updates, hashed_state } } /// Create new Chain from a single block and its state. pub fn from_block( block: RecoveredBlock, execution_outcome: ExecutionOutcome, - trie_updates: Option, + trie_updates: Arc, + hashed_state: Arc, ) -> Self { - Self::new([block], execution_outcome, trie_updates) + let block_number = block.header().number(); + let trie_updates_map = BTreeMap::from([(block_number, trie_updates)]); + let hashed_state_map = BTreeMap::from([(block_number, hashed_state)]); + Self::new([block], execution_outcome, trie_updates_map, hashed_state_map) } /// Get the blocks in this chain. @@ -93,14 +98,34 @@ impl Chain { self.blocks.values().map(|block| block.clone_sealed_header()) } - /// Get cached trie updates for this chain. - pub const fn trie_updates(&self) -> Option<&TrieUpdates> { - self.trie_updates.as_ref() + /// Get all trie updates for this chain. + pub const fn trie_updates(&self) -> &BTreeMap> { + &self.trie_updates } - /// Remove cached trie updates for this chain. + /// Get trie updates for a specific block number. + pub fn trie_updates_at(&self, block_number: BlockNumber) -> Option<&Arc> { + self.trie_updates.get(&block_number) + } + + /// Remove all trie updates for this chain. pub fn clear_trie_updates(&mut self) { - self.trie_updates.take(); + self.trie_updates.clear(); + } + + /// Get all hashed states for this chain. + pub const fn hashed_state(&self) -> &BTreeMap> { + &self.hashed_state + } + + /// Get hashed state for a specific block number. + pub fn hashed_state_at(&self, block_number: BlockNumber) -> Option<&Arc> { + self.hashed_state.get(&block_number) + } + + /// Remove all hashed states for this chain. + pub fn clear_hashed_state(&mut self) { + self.hashed_state.clear(); } /// Get execution outcome of this chain @@ -113,12 +138,6 @@ impl Chain { &mut self.execution_outcome } - /// Prepends the given state to the current state. - pub fn prepend_state(&mut self, state: BundleState) { - self.execution_outcome.prepend_state(state); - self.trie_updates.take(); // invalidate cached trie updates - } - /// Return true if chain is empty and has no blocks. pub fn is_empty(&self) -> bool { self.blocks.is_empty() @@ -154,11 +173,23 @@ impl Chain { /// Destructure the chain into its inner components: /// 1. The blocks contained in the chain. /// 2. The execution outcome representing the final state. - /// 3. The optional trie updates. + /// 3. The trie updates map. + /// 4. The hashed state map. + #[expect(clippy::type_complexity)] pub fn into_inner( self, - ) -> (ChainBlocks<'static, N::Block>, ExecutionOutcome, Option) { - (ChainBlocks { blocks: Cow::Owned(self.blocks) }, self.execution_outcome, self.trie_updates) + ) -> ( + ChainBlocks<'static, N::Block>, + ExecutionOutcome, + BTreeMap>, + BTreeMap>, + ) { + ( + ChainBlocks { blocks: Cow::Owned(self.blocks) }, + self.execution_outcome, + self.trie_updates, + self.hashed_state, + ) } /// Destructure the chain into its inner components: @@ -270,10 +301,14 @@ impl Chain { &mut self, block: RecoveredBlock, execution_outcome: ExecutionOutcome, + trie_updates: Arc, + hashed_state: Arc, ) { - self.blocks.insert(block.header().number(), block); + let block_number = block.header().number(); + self.blocks.insert(block_number, block); self.execution_outcome.extend(execution_outcome); - self.trie_updates.take(); // reset + self.trie_updates.insert(block_number, trie_updates); + self.hashed_state.insert(block_number, hashed_state); } /// Merge two chains by appending the given chain into the current one. @@ -292,7 +327,8 @@ impl Chain { // Insert blocks from other chain self.blocks.extend(other.blocks); self.execution_outcome.extend(other.execution_outcome); - self.trie_updates.take(); // reset + self.trie_updates.extend(other.trie_updates); + self.hashed_state.extend(other.hashed_state); Ok(()) } @@ -417,7 +453,7 @@ pub struct BlockReceipts { #[cfg(feature = "serde-bincode-compat")] pub(super) mod serde_bincode_compat { use crate::{serde_bincode_compat, ExecutionOutcome}; - use alloc::{borrow::Cow, collections::BTreeMap}; + use alloc::{borrow::Cow, collections::BTreeMap, sync::Arc}; use alloy_primitives::BlockNumber; use reth_ethereum_primitives::EthPrimitives; use reth_primitives_traits::{ @@ -452,7 +488,12 @@ pub(super) mod serde_bincode_compat { { blocks: RecoveredBlocks<'a, N::Block>, execution_outcome: serde_bincode_compat::ExecutionOutcome<'a, N::Receipt>, - trie_updates: Option>, + #[serde(default, rename = "trie_updates_legacy")] + _trie_updates_legacy: Option>, + #[serde(default)] + trie_updates: BTreeMap>, + #[serde(default)] + hashed_state: BTreeMap>, } #[derive(Debug)] @@ -505,7 +546,9 @@ pub(super) mod serde_bincode_compat { Self { blocks: RecoveredBlocks(Cow::Borrowed(&value.blocks)), execution_outcome: value.execution_outcome.as_repr(), - trie_updates: value.trie_updates.as_ref().map(Into::into), + _trie_updates_legacy: None, + trie_updates: value.trie_updates.clone(), + hashed_state: value.hashed_state.clone(), } } } @@ -520,7 +563,8 @@ pub(super) mod serde_bincode_compat { Self { blocks: value.blocks.0.into_owned(), execution_outcome: ExecutionOutcome::from_repr(value.execution_outcome), - trie_updates: value.trie_updates.map(Into::into), + trie_updates: value.trie_updates, + hashed_state: value.hashed_state, } } } @@ -564,6 +608,8 @@ pub(super) mod serde_bincode_compat { #[test] fn test_chain_bincode_roundtrip() { + use alloc::collections::BTreeMap; + #[serde_as] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] struct Data { @@ -578,7 +624,8 @@ pub(super) mod serde_bincode_compat { vec![RecoveredBlock::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) .unwrap()], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), ), }; @@ -595,7 +642,7 @@ mod tests { use alloy_consensus::TxType; use alloy_primitives::{Address, B256}; use reth_ethereum_primitives::Receipt; - use revm::{primitives::HashMap, state::AccountInfo}; + use revm::{database::BundleState, primitives::HashMap, state::AccountInfo}; #[test] fn chain_append() { @@ -678,8 +725,12 @@ mod tests { let mut block_state_extended = execution_outcome1; block_state_extended.extend(execution_outcome2); - let chain: Chain = - Chain::new(vec![block1.clone(), block2.clone()], block_state_extended, None); + let chain: Chain = Chain::new( + vec![block1.clone(), block2.clone()], + block_state_extended, + BTreeMap::new(), + BTreeMap::new(), + ); // return tip state assert_eq!( diff --git a/crates/exex/exex/src/backfill/job.rs b/crates/exex/exex/src/backfill/job.rs index 1a294e50659..7c911239c3b 100644 --- a/crates/exex/exex/src/backfill/job.rs +++ b/crates/exex/exex/src/backfill/job.rs @@ -1,6 +1,7 @@ use crate::StreamBackfillJob; use reth_evm::ConfigureEvm; use std::{ + collections::BTreeMap, ops::RangeInclusive, time::{Duration, Instant}, }; @@ -150,7 +151,7 @@ where executor.into_state().take_bundle(), results, ); - let chain = Chain::new(blocks, outcome, None); + let chain = Chain::new(blocks, outcome, BTreeMap::new(), BTreeMap::new()); Ok(chain) } } diff --git a/crates/exex/exex/src/manager.rs b/crates/exex/exex/src/manager.rs index 99694f0a51b..11539563da1 100644 --- a/crates/exex/exex/src/manager.rs +++ b/crates/exex/exex/src/manager.rs @@ -670,6 +670,7 @@ mod tests { BlockWriter, Chain, DBProvider, DatabaseProviderFactory, TransactionVariant, }; use reth_testing_utils::generators::{self, random_block, BlockParams}; + use std::collections::BTreeMap; fn empty_finalized_header_stream() -> ForkChoiceStream { let (tx, rx) = watch::channel(None); @@ -771,7 +772,12 @@ mod tests { block1.set_block_number(10); let notification1 = ExExNotification::ChainCommitted { - new: Arc::new(Chain::new(vec![block1.clone()], Default::default(), Default::default())), + new: Arc::new(Chain::new( + vec![block1.clone()], + Default::default(), + Default::default(), + Default::default(), + )), }; // Push the first notification @@ -789,7 +795,12 @@ mod tests { block2.set_block_number(20); let notification2 = ExExNotification::ChainCommitted { - new: Arc::new(Chain::new(vec![block2.clone()], Default::default(), Default::default())), + new: Arc::new(Chain::new( + vec![block2.clone()], + Default::default(), + Default::default(), + Default::default(), + )), }; exex_manager.push_notification(notification2.clone()); @@ -832,7 +843,12 @@ mod tests { block1.set_block_number(10); let notification1 = ExExNotification::ChainCommitted { - new: Arc::new(Chain::new(vec![block1.clone()], Default::default(), Default::default())), + new: Arc::new(Chain::new( + vec![block1.clone()], + Default::default(), + Default::default(), + Default::default(), + )), }; exex_manager.push_notification(notification1.clone()); @@ -1060,6 +1076,7 @@ mod tests { vec![Default::default()], Default::default(), Default::default(), + Default::default(), )), }; @@ -1130,6 +1147,7 @@ mod tests { vec![block1.clone(), block2.clone()], Default::default(), Default::default(), + Default::default(), )), }; @@ -1174,7 +1192,12 @@ mod tests { block1.set_block_number(10); let notification = ExExNotification::ChainCommitted { - new: Arc::new(Chain::new(vec![block1.clone()], Default::default(), Default::default())), + new: Arc::new(Chain::new( + vec![block1.clone()], + Default::default(), + Default::default(), + Default::default(), + )), }; let mut cx = Context::from_waker(futures::task::noop_waker_ref()); @@ -1320,10 +1343,20 @@ mod tests { ); let genesis_notification = ExExNotification::ChainCommitted { - new: Arc::new(Chain::new(vec![genesis_block.clone()], Default::default(), None)), + new: Arc::new(Chain::new( + vec![genesis_block.clone()], + Default::default(), + BTreeMap::new(), + BTreeMap::new(), + )), }; let notification = ExExNotification::ChainCommitted { - new: Arc::new(Chain::new(vec![block.clone()], Default::default(), None)), + new: Arc::new(Chain::new( + vec![block.clone()], + Default::default(), + BTreeMap::new(), + BTreeMap::new(), + )), }; let (finalized_headers_tx, rx) = watch::channel(None); diff --git a/crates/exex/exex/src/notifications.rs b/crates/exex/exex/src/notifications.rs index c6a54e647cf..2f241392e32 100644 --- a/crates/exex/exex/src/notifications.rs +++ b/crates/exex/exex/src/notifications.rs @@ -460,6 +460,7 @@ mod tests { Chain, DBProvider, DatabaseProviderFactory, }; use reth_testing_utils::generators::{self, random_block, BlockParams}; + use std::collections::BTreeMap; use tokio::sync::mpsc; #[tokio::test] @@ -499,7 +500,8 @@ mod tests { ) .try_recover()?], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; @@ -567,7 +569,8 @@ mod tests { .seal_slow() .try_recover()?], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; @@ -634,7 +637,8 @@ mod tests { new: Arc::new(Chain::new( vec![exex_head_block.clone().try_recover()?], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; wal.commit(&exex_head_notification)?; @@ -648,7 +652,8 @@ mod tests { ) .try_recover()?], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; @@ -705,7 +710,8 @@ mod tests { new: Arc::new(Chain::new( vec![exex_head_block.clone().try_recover()?], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; wal.commit(&exex_head_notification)?; @@ -724,7 +730,8 @@ mod tests { ) .try_recover()?], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; diff --git a/crates/exex/exex/src/wal/mod.rs b/crates/exex/exex/src/wal/mod.rs index b5537aa88fc..7ab49b6e0de 100644 --- a/crates/exex/exex/src/wal/mod.rs +++ b/crates/exex/exex/src/wal/mod.rs @@ -243,7 +243,7 @@ mod tests { use reth_testing_utils::generators::{ self, random_block, random_block_range, BlockParams, BlockRangeParams, }; - use std::sync::Arc; + use std::{collections::BTreeMap, sync::Arc}; fn read_notifications(wal: &Wal) -> WalResult> { wal.inner.storage.files_range()?.map_or(Ok(Vec::new()), |range| { @@ -303,25 +303,38 @@ mod tests { new: Arc::new(Chain::new( vec![blocks[0].clone(), blocks[1].clone()], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; let reverted_notification = ExExNotification::ChainReverted { - old: Arc::new(Chain::new(vec![blocks[1].clone()], Default::default(), None)), + old: Arc::new(Chain::new( + vec![blocks[1].clone()], + Default::default(), + BTreeMap::new(), + BTreeMap::new(), + )), }; let committed_notification_2 = ExExNotification::ChainCommitted { new: Arc::new(Chain::new( vec![block_1_reorged.clone(), blocks[2].clone()], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; let reorged_notification = ExExNotification::ChainReorged { - old: Arc::new(Chain::new(vec![blocks[2].clone()], Default::default(), None)), + old: Arc::new(Chain::new( + vec![blocks[2].clone()], + Default::default(), + BTreeMap::new(), + BTreeMap::new(), + )), new: Arc::new(Chain::new( vec![block_2_reorged.clone(), blocks[3].clone()], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }; diff --git a/crates/exex/exex/src/wal/storage.rs b/crates/exex/exex/src/wal/storage.rs index 122edc632e7..4b28501a33d 100644 --- a/crates/exex/exex/src/wal/storage.rs +++ b/crates/exex/exex/src/wal/storage.rs @@ -181,7 +181,7 @@ mod tests { use reth_exex_types::ExExNotification; use reth_provider::Chain; use reth_testing_utils::generators::{self, random_block}; - use std::{fs::File, sync::Arc}; + use std::{collections::BTreeMap, fs::File, sync::Arc}; // wal with 1 block and tx // @@ -213,8 +213,18 @@ mod tests { let new_block = random_block(&mut rng, 0, Default::default()).try_recover()?; let notification = ExExNotification::ChainReorged { - new: Arc::new(Chain::new(vec![new_block], Default::default(), None)), - old: Arc::new(Chain::new(vec![old_block], Default::default(), None)), + new: Arc::new(Chain::new( + vec![new_block], + Default::default(), + BTreeMap::new(), + BTreeMap::new(), + )), + old: Arc::new(Chain::new( + vec![old_block], + Default::default(), + BTreeMap::new(), + BTreeMap::new(), + )), }; // Do a round trip serialization and deserialization diff --git a/crates/exex/types/src/notification.rs b/crates/exex/types/src/notification.rs index cf0d7580556..2af322263b7 100644 --- a/crates/exex/types/src/notification.rs +++ b/crates/exex/types/src/notification.rs @@ -185,7 +185,7 @@ pub(super) mod serde_bincode_compat { use reth_primitives_traits::RecoveredBlock; use serde::{Deserialize, Serialize}; use serde_with::serde_as; - use std::sync::Arc; + use std::{collections::BTreeMap, sync::Arc}; #[test] fn test_exex_notification_bincode_roundtrip() { @@ -206,13 +206,15 @@ pub(super) mod serde_bincode_compat { vec![RecoveredBlock::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) .unwrap()], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), new: Arc::new(Chain::new( vec![RecoveredBlock::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) .unwrap()], Default::default(), - None, + BTreeMap::new(), + BTreeMap::new(), )), }, }; diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index e5df16ee2e7..a6cd20d8ef1 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -277,6 +277,7 @@ where #[cfg(test)] mod tests { use super::*; + use alloc::collections::BTreeMap; use alloy_consensus::{Header, Receipt}; use alloy_eips::eip7685::Requests; use alloy_genesis::Genesis; @@ -510,8 +511,12 @@ mod tests { // Create a Chain object with a BTreeMap of blocks mapped to their block numbers, // including block1_hash and block2_hash, and the execution_outcome - let chain: Chain = - Chain::new([block1, block2], execution_outcome.clone(), None); + let chain: Chain = Chain::new( + [block1, block2], + execution_outcome.clone(), + BTreeMap::new(), + BTreeMap::new(), + ); // Assert that the proper receipt vector is returned for block1_hash assert_eq!(chain.receipts_by_block_hash(block1_hash), Some(vec![&receipt1])); diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index c8428f93f3a..44a96f8ef22 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -24,6 +24,7 @@ use reth_stages_api::{ use reth_static_file_types::StaticFileSegment; use std::{ cmp::Ordering, + collections::BTreeMap, ops::RangeInclusive, sync::Arc, task::{ready, Context, Poll}, @@ -418,8 +419,12 @@ where // Note: Since we only write to `blocks` if there are any ExExes, we don't need to perform // the `has_exexs` check here as well if !blocks.is_empty() { - let previous_input = - self.post_execute_commit_input.replace(Chain::new(blocks, state.clone(), None)); + let previous_input = self.post_execute_commit_input.replace(Chain::new( + blocks, + state.clone(), + BTreeMap::new(), + BTreeMap::new(), + )); if previous_input.is_some() { // Not processing the previous post execute commit input is a critical error, as it @@ -519,7 +524,8 @@ where let previous_input = self.post_unwind_commit_input.replace(Chain::new( blocks, bundle_state_with_receipts, - None, + BTreeMap::new(), + BTreeMap::new(), )); debug_assert!( diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 81e6c7ee7f2..b820e479978 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -787,6 +787,7 @@ mod tests { }; use revm_database::{BundleState, OriginalValuesKnown}; use std::{ + collections::BTreeMap, ops::{Bound, Range, RangeBounds}, sync::Arc, }; @@ -1320,7 +1321,12 @@ mod tests { // Send and receive commit notifications. let block_2 = test_block_builder.generate_random_block(1, block_hash_1); - let chain = Chain::new(vec![block_2], ExecutionOutcome::default(), None); + let chain = Chain::new( + vec![block_2], + ExecutionOutcome::default(), + BTreeMap::new(), + BTreeMap::new(), + ); let commit = CanonStateNotification::Commit { new: Arc::new(chain.clone()) }; in_memory_state.notify_canon_state(commit.clone()); let (notification_1, notification_2) = tokio::join!(rx_1.recv(), rx_2.recv()); @@ -1330,7 +1336,12 @@ mod tests { // Send and receive re-org notifications. let block_3 = test_block_builder.generate_random_block(1, block_hash_1); let block_4 = test_block_builder.generate_random_block(2, block_3.hash()); - let new_chain = Chain::new(vec![block_3, block_4], ExecutionOutcome::default(), None); + let new_chain = Chain::new( + vec![block_3, block_4], + ExecutionOutcome::default(), + BTreeMap::new(), + BTreeMap::new(), + ); let re_org = CanonStateNotification::Reorg { old: Arc::new(chain), new: Arc::new(new_chain) }; in_memory_state.notify_canon_state(re_org.clone()); diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 8bf813d1f24..10fb31749d9 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -2785,7 +2785,7 @@ impl BlockExecu // Update pipeline progress self.update_pipeline_stages(block, true)?; - Ok(Chain::new(blocks, execution_state, None)) + Ok(Chain::new(blocks, execution_state, BTreeMap::new(), BTreeMap::new())) } fn remove_block_and_execution_above(&self, block: BlockNumber) -> ProviderResult<()> { diff --git a/crates/transaction-pool/src/blobstore/tracker.rs b/crates/transaction-pool/src/blobstore/tracker.rs index 6789086abed..44bd772cf1d 100644 --- a/crates/transaction-pool/src/blobstore/tracker.rs +++ b/crates/transaction-pool/src/blobstore/tracker.rs @@ -175,7 +175,8 @@ mod tests { ); // Extract blocks from the chain - let chain: Chain = Chain::new(vec![block1, block2], Default::default(), None); + let chain: Chain = + Chain::new(vec![block1, block2], Default::default(), BTreeMap::new(), BTreeMap::new()); let blocks = chain.into_inner().0; // Add new chain blocks to the tracker