reth_chain_state/
in_memory.rs

1//! Types for tracking the canonical chain state in memory.
2
3use crate::{
4    CanonStateNotification, CanonStateNotificationSender, CanonStateNotifications,
5    ChainInfoTracker, ComputedTrieData, DeferredTrieData, MemoryOverlayStateProvider,
6};
7use alloy_consensus::{transaction::TransactionMeta, BlockHeader};
8use alloy_eips::{BlockHashOrNumber, BlockNumHash};
9use alloy_primitives::{map::HashMap, BlockNumber, TxHash, B256};
10use parking_lot::RwLock;
11use reth_chainspec::ChainInfo;
12use reth_ethereum_primitives::EthPrimitives;
13use reth_execution_types::{Chain, ExecutionOutcome};
14use reth_metrics::{metrics::Gauge, Metrics};
15use reth_primitives_traits::{
16    BlockBody as _, IndexedTx, NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader,
17    SignedTransaction,
18};
19use reth_storage_api::StateProviderBox;
20use reth_trie::{updates::TrieUpdatesSorted, HashedPostStateSorted, TrieInputSorted};
21use std::{collections::BTreeMap, ops::Deref, sync::Arc, time::Instant};
22use tokio::sync::{broadcast, watch};
23
24/// Size of the broadcast channel used to notify canonical state events.
25const CANON_STATE_NOTIFICATION_CHANNEL_SIZE: usize = 256;
26
27/// Metrics for the in-memory state.
28#[derive(Metrics)]
29#[metrics(scope = "blockchain_tree.in_mem_state")]
30pub(crate) struct InMemoryStateMetrics {
31    /// The block number of the earliest block in the in-memory state.
32    pub(crate) earliest_block: Gauge,
33    /// The block number of the latest block in the in-memory state.
34    pub(crate) latest_block: Gauge,
35    /// The number of blocks in the in-memory state.
36    pub(crate) num_blocks: Gauge,
37}
38
39/// Container type for in memory state data of the canonical chain.
40///
41/// This tracks blocks and their state that haven't been persisted to disk yet but are part of the
42/// canonical chain that can be traced back to a canonical block on disk.
43///
44/// # Locking behavior on state updates
45///
46/// All update calls must acquire all locks at once before modifying state to ensure the internal
47/// state remains consistent. This prevents readers from observing partially updated state where
48/// the numbers and blocks maps are out of sync.
49/// Update functions ensure that the numbers write lock is always acquired first, because lookup by
50/// numbers first read the numbers map and then the blocks map.
51/// By acquiring the numbers lock first, we ensure that read-only lookups don't deadlock updates.
52/// This holds, because only lookup by number functions need to acquire the numbers lock first to
53/// get the block hash.
54#[derive(Debug, Default)]
55pub(crate) struct InMemoryState<N: NodePrimitives = EthPrimitives> {
56    /// All canonical blocks that are not on disk yet.
57    blocks: RwLock<HashMap<B256, Arc<BlockState<N>>>>,
58    /// Mapping of block numbers to block hashes.
59    numbers: RwLock<BTreeMap<u64, B256>>,
60    /// The pending block that has not yet been made canonical.
61    pending: watch::Sender<Option<BlockState<N>>>,
62    /// Metrics for the in-memory state.
63    metrics: InMemoryStateMetrics,
64}
65
66impl<N: NodePrimitives> InMemoryState<N> {
67    pub(crate) fn new(
68        blocks: HashMap<B256, Arc<BlockState<N>>>,
69        numbers: BTreeMap<u64, B256>,
70        pending: Option<BlockState<N>>,
71    ) -> Self {
72        let (pending, _) = watch::channel(pending);
73        let this = Self {
74            blocks: RwLock::new(blocks),
75            numbers: RwLock::new(numbers),
76            pending,
77            metrics: Default::default(),
78        };
79        this.update_metrics();
80        this
81    }
82
83    /// Update the metrics for the in-memory state.
84    ///
85    /// # Locking behavior
86    ///
87    /// This tries to acquire a read lock. Drop any write locks before calling this.
88    pub(crate) fn update_metrics(&self) {
89        let numbers = self.numbers.read();
90        if let Some((earliest_block_number, _)) = numbers.first_key_value() {
91            self.metrics.earliest_block.set(*earliest_block_number as f64);
92        }
93        if let Some((latest_block_number, _)) = numbers.last_key_value() {
94            self.metrics.latest_block.set(*latest_block_number as f64);
95        }
96        self.metrics.num_blocks.set(numbers.len() as f64);
97    }
98
99    /// Returns the state for a given block hash.
100    pub(crate) fn state_by_hash(&self, hash: B256) -> Option<Arc<BlockState<N>>> {
101        self.blocks.read().get(&hash).cloned()
102    }
103
104    /// Returns the state for a given block number.
105    pub(crate) fn state_by_number(&self, number: u64) -> Option<Arc<BlockState<N>>> {
106        let hash = self.hash_by_number(number)?;
107        self.state_by_hash(hash)
108    }
109
110    /// Returns the hash for a specific block number
111    pub(crate) fn hash_by_number(&self, number: u64) -> Option<B256> {
112        self.numbers.read().get(&number).copied()
113    }
114
115    /// Returns the current chain head state.
116    pub(crate) fn head_state(&self) -> Option<Arc<BlockState<N>>> {
117        let hash = *self.numbers.read().last_key_value()?.1;
118        self.state_by_hash(hash)
119    }
120
121    /// Returns the pending state corresponding to the current head plus one,
122    /// from the payload received in newPayload that does not have a FCU yet.
123    pub(crate) fn pending_state(&self) -> Option<BlockState<N>> {
124        self.pending.borrow().clone()
125    }
126
127    #[cfg(test)]
128    fn block_count(&self) -> usize {
129        self.blocks.read().len()
130    }
131}
132
133/// Inner type to provide in memory state. It includes a chain tracker to be
134/// advanced internally by the tree.
135#[derive(Debug)]
136pub(crate) struct CanonicalInMemoryStateInner<N: NodePrimitives> {
137    /// Tracks certain chain information, such as the canonical head, safe head, and finalized
138    /// head.
139    pub(crate) chain_info_tracker: ChainInfoTracker<N>,
140    /// Tracks blocks at the tip of the chain that have not been persisted to disk yet.
141    pub(crate) in_memory_state: InMemoryState<N>,
142    /// A broadcast stream that emits events when the canonical chain is updated.
143    pub(crate) canon_state_notification_sender: CanonStateNotificationSender<N>,
144}
145
146impl<N: NodePrimitives> CanonicalInMemoryStateInner<N> {
147    /// Clears all entries in the in memory state.
148    fn clear(&self) {
149        {
150            // acquire locks, starting with the numbers lock
151            let mut numbers = self.in_memory_state.numbers.write();
152            let mut blocks = self.in_memory_state.blocks.write();
153            numbers.clear();
154            blocks.clear();
155            self.in_memory_state.pending.send_modify(|p| {
156                p.take();
157            });
158        }
159        self.in_memory_state.update_metrics();
160    }
161}
162
163type PendingBlockAndReceipts<N> =
164    (RecoveredBlock<<N as NodePrimitives>::Block>, Vec<reth_primitives_traits::ReceiptTy<N>>);
165
166/// This type is responsible for providing the blocks, receipts, and state for
167/// all canonical blocks not on disk yet and keeps track of the block range that
168/// is in memory.
169#[derive(Debug, Clone)]
170pub struct CanonicalInMemoryState<N: NodePrimitives = EthPrimitives> {
171    pub(crate) inner: Arc<CanonicalInMemoryStateInner<N>>,
172}
173
174impl<N: NodePrimitives> CanonicalInMemoryState<N> {
175    /// Create a new in-memory state with the given blocks, numbers, pending state, and optional
176    /// finalized header.
177    pub fn new(
178        blocks: HashMap<B256, Arc<BlockState<N>>>,
179        numbers: BTreeMap<u64, B256>,
180        pending: Option<BlockState<N>>,
181        finalized: Option<SealedHeader<N::BlockHeader>>,
182        safe: Option<SealedHeader<N::BlockHeader>>,
183    ) -> Self {
184        let in_memory_state = InMemoryState::new(blocks, numbers, pending);
185        let header = in_memory_state.head_state().map_or_else(SealedHeader::default, |state| {
186            state.block_ref().recovered_block().clone_sealed_header()
187        });
188        let chain_info_tracker = ChainInfoTracker::new(header, finalized, safe);
189        let (canon_state_notification_sender, _) =
190            broadcast::channel(CANON_STATE_NOTIFICATION_CHANNEL_SIZE);
191
192        Self {
193            inner: Arc::new(CanonicalInMemoryStateInner {
194                chain_info_tracker,
195                in_memory_state,
196                canon_state_notification_sender,
197            }),
198        }
199    }
200
201    /// Create an empty state.
202    pub fn empty() -> Self {
203        Self::new(HashMap::default(), BTreeMap::new(), None, None, None)
204    }
205
206    /// Create a new in memory state with the given local head and finalized header
207    /// if it exists.
208    pub fn with_head(
209        head: SealedHeader<N::BlockHeader>,
210        finalized: Option<SealedHeader<N::BlockHeader>>,
211        safe: Option<SealedHeader<N::BlockHeader>>,
212    ) -> Self {
213        let chain_info_tracker = ChainInfoTracker::new(head, finalized, safe);
214        let in_memory_state = InMemoryState::default();
215        let (canon_state_notification_sender, _) =
216            broadcast::channel(CANON_STATE_NOTIFICATION_CHANNEL_SIZE);
217        let inner = CanonicalInMemoryStateInner {
218            chain_info_tracker,
219            in_memory_state,
220            canon_state_notification_sender,
221        };
222
223        Self { inner: Arc::new(inner) }
224    }
225
226    /// Returns the block hash corresponding to the given number.
227    pub fn hash_by_number(&self, number: u64) -> Option<B256> {
228        self.inner.in_memory_state.hash_by_number(number)
229    }
230
231    /// Returns the header corresponding to the given hash.
232    pub fn header_by_hash(&self, hash: B256) -> Option<SealedHeader<N::BlockHeader>> {
233        self.state_by_hash(hash)
234            .map(|block| block.block_ref().recovered_block().clone_sealed_header())
235    }
236
237    /// Clears all entries in the in memory state.
238    pub fn clear_state(&self) {
239        self.inner.clear()
240    }
241
242    /// Updates the pending block with the given block.
243    ///
244    /// Note: This assumes that the parent block of the pending block is canonical.
245    pub fn set_pending_block(&self, pending: ExecutedBlock<N>) {
246        // fetch the state of the pending block's parent block
247        let parent = self.state_by_hash(pending.recovered_block().parent_hash());
248        let pending = BlockState::with_parent(pending, parent);
249        self.inner.in_memory_state.pending.send_modify(|p| {
250            p.replace(pending);
251        });
252        self.inner.in_memory_state.update_metrics();
253    }
254
255    /// Append new blocks to the in memory state.
256    ///
257    /// This removes all reorged blocks and appends the new blocks to the tracked chain and connects
258    /// them to their parent blocks.
259    fn update_blocks<I, R>(&self, new_blocks: I, reorged: R)
260    where
261        I: IntoIterator<Item = ExecutedBlock<N>>,
262        R: IntoIterator<Item = ExecutedBlock<N>>,
263    {
264        {
265            // acquire locks, starting with the numbers lock
266            let mut numbers = self.inner.in_memory_state.numbers.write();
267            let mut blocks = self.inner.in_memory_state.blocks.write();
268
269            // we first remove the blocks from the reorged chain
270            for block in reorged {
271                let hash = block.recovered_block().hash();
272                let number = block.recovered_block().number();
273                blocks.remove(&hash);
274                numbers.remove(&number);
275            }
276
277            // insert the new blocks
278            for block in new_blocks {
279                let parent = blocks.get(&block.recovered_block().parent_hash()).cloned();
280                let block_state = BlockState::with_parent(block, parent);
281                let hash = block_state.hash();
282                let number = block_state.number();
283
284                // append new blocks
285                blocks.insert(hash, Arc::new(block_state));
286                numbers.insert(number, hash);
287            }
288
289            // remove the pending state
290            self.inner.in_memory_state.pending.send_modify(|p| {
291                p.take();
292            });
293        }
294        self.inner.in_memory_state.update_metrics();
295    }
296
297    /// Update the in memory state with the given chain update.
298    pub fn update_chain(&self, new_chain: NewCanonicalChain<N>) {
299        match new_chain {
300            NewCanonicalChain::Commit { new } => {
301                self.update_blocks(new, vec![]);
302            }
303            NewCanonicalChain::Reorg { new, old } => {
304                self.update_blocks(new, old);
305            }
306        }
307    }
308
309    /// Removes blocks from the in memory state that are persisted to the given height.
310    ///
311    /// This will update the links between blocks and remove all blocks that are [..
312    /// `persisted_height`].
313    pub fn remove_persisted_blocks(&self, persisted_num_hash: BlockNumHash) {
314        // if the persisted hash is not in the canonical in memory state, do nothing, because it
315        // means canonical blocks were not actually persisted.
316        //
317        // This can happen if the persistence task takes a long time, while a reorg is happening.
318        {
319            if self.inner.in_memory_state.blocks.read().get(&persisted_num_hash.hash).is_none() {
320                // do nothing
321                return
322            }
323        }
324
325        {
326            // acquire locks, starting with the numbers lock
327            let mut numbers = self.inner.in_memory_state.numbers.write();
328            let mut blocks = self.inner.in_memory_state.blocks.write();
329
330            let BlockNumHash { number: persisted_height, hash: _ } = persisted_num_hash;
331
332            // clear all numbers
333            numbers.clear();
334
335            // drain all blocks and only keep the ones that are not persisted (below the persisted
336            // height)
337            let mut old_blocks = blocks
338                .drain()
339                .filter(|(_, b)| b.block_ref().recovered_block().number() > persisted_height)
340                .map(|(_, b)| b.block.clone())
341                .collect::<Vec<_>>();
342
343            // sort the blocks by number so we can insert them back in natural order (low -> high)
344            old_blocks.sort_unstable_by_key(|block| block.recovered_block().number());
345
346            // re-insert the blocks in natural order and connect them to their parent blocks
347            for block in old_blocks {
348                let parent = blocks.get(&block.recovered_block().parent_hash()).cloned();
349                let block_state = BlockState::with_parent(block, parent);
350                let hash = block_state.hash();
351                let number = block_state.number();
352
353                // append new blocks
354                blocks.insert(hash, Arc::new(block_state));
355                numbers.insert(number, hash);
356            }
357
358            // also shift the pending state if it exists
359            self.inner.in_memory_state.pending.send_modify(|p| {
360                if let Some(p) = p.as_mut() {
361                    p.parent = blocks.get(&p.block_ref().recovered_block().parent_hash()).cloned();
362                }
363            });
364        }
365        self.inner.in_memory_state.update_metrics();
366    }
367
368    /// Returns in memory state corresponding the given hash.
369    pub fn state_by_hash(&self, hash: B256) -> Option<Arc<BlockState<N>>> {
370        self.inner.in_memory_state.state_by_hash(hash)
371    }
372
373    /// Returns in memory state corresponding the block number.
374    pub fn state_by_number(&self, number: u64) -> Option<Arc<BlockState<N>>> {
375        self.inner.in_memory_state.state_by_number(number)
376    }
377
378    /// Returns the in memory head state.
379    pub fn head_state(&self) -> Option<Arc<BlockState<N>>> {
380        self.inner.in_memory_state.head_state()
381    }
382
383    /// Returns the in memory pending state.
384    pub fn pending_state(&self) -> Option<BlockState<N>> {
385        self.inner.in_memory_state.pending_state()
386    }
387
388    /// Returns the in memory pending `BlockNumHash`.
389    pub fn pending_block_num_hash(&self) -> Option<BlockNumHash> {
390        self.inner
391            .in_memory_state
392            .pending_state()
393            .map(|state| BlockNumHash { number: state.number(), hash: state.hash() })
394    }
395
396    /// Returns the current `ChainInfo`.
397    pub fn chain_info(&self) -> ChainInfo {
398        self.inner.chain_info_tracker.chain_info()
399    }
400
401    /// Returns the latest canonical block number.
402    pub fn get_canonical_block_number(&self) -> u64 {
403        self.inner.chain_info_tracker.get_canonical_block_number()
404    }
405
406    /// Returns the `BlockNumHash` of the safe head.
407    pub fn get_safe_num_hash(&self) -> Option<BlockNumHash> {
408        self.inner.chain_info_tracker.get_safe_num_hash()
409    }
410
411    /// Returns the `BlockNumHash` of the finalized head.
412    pub fn get_finalized_num_hash(&self) -> Option<BlockNumHash> {
413        self.inner.chain_info_tracker.get_finalized_num_hash()
414    }
415
416    /// Hook for new fork choice update.
417    pub fn on_forkchoice_update_received(&self) {
418        self.inner.chain_info_tracker.on_forkchoice_update_received();
419    }
420
421    /// Returns the timestamp of the last received update.
422    pub fn last_received_update_timestamp(&self) -> Option<Instant> {
423        self.inner.chain_info_tracker.last_forkchoice_update_received_at()
424    }
425
426    /// Canonical head setter.
427    pub fn set_canonical_head(&self, header: SealedHeader<N::BlockHeader>) {
428        self.inner.chain_info_tracker.set_canonical_head(header);
429    }
430
431    /// Safe head setter.
432    pub fn set_safe(&self, header: SealedHeader<N::BlockHeader>) {
433        self.inner.chain_info_tracker.set_safe(header);
434    }
435
436    /// Finalized head setter.
437    pub fn set_finalized(&self, header: SealedHeader<N::BlockHeader>) {
438        self.inner.chain_info_tracker.set_finalized(header);
439    }
440
441    /// Canonical head getter.
442    pub fn get_canonical_head(&self) -> SealedHeader<N::BlockHeader> {
443        self.inner.chain_info_tracker.get_canonical_head()
444    }
445
446    /// Finalized header getter.
447    pub fn get_finalized_header(&self) -> Option<SealedHeader<N::BlockHeader>> {
448        self.inner.chain_info_tracker.get_finalized_header()
449    }
450
451    /// Safe header getter.
452    pub fn get_safe_header(&self) -> Option<SealedHeader<N::BlockHeader>> {
453        self.inner.chain_info_tracker.get_safe_header()
454    }
455
456    /// Returns the `SealedHeader` corresponding to the pending state.
457    pub fn pending_sealed_header(&self) -> Option<SealedHeader<N::BlockHeader>> {
458        self.pending_state().map(|h| h.block_ref().recovered_block().clone_sealed_header())
459    }
460
461    /// Returns the `Header` corresponding to the pending state.
462    pub fn pending_header(&self) -> Option<N::BlockHeader> {
463        self.pending_sealed_header().map(|sealed_header| sealed_header.unseal())
464    }
465
466    /// Returns the `SealedBlock` corresponding to the pending state.
467    pub fn pending_block(&self) -> Option<SealedBlock<N::Block>> {
468        self.pending_state()
469            .map(|block_state| block_state.block_ref().recovered_block().sealed_block().clone())
470    }
471
472    /// Returns the `RecoveredBlock` corresponding to the pending state.
473    pub fn pending_recovered_block(&self) -> Option<RecoveredBlock<N::Block>>
474    where
475        N::SignedTx: SignedTransaction,
476    {
477        self.pending_state().map(|block_state| block_state.block_ref().recovered_block().clone())
478    }
479
480    /// Returns a tuple with the `SealedBlock` corresponding to the pending
481    /// state and a vector of its `Receipt`s.
482    pub fn pending_block_and_receipts(&self) -> Option<PendingBlockAndReceipts<N>> {
483        self.pending_state().map(|block_state| {
484            (
485                block_state.block_ref().recovered_block().clone(),
486                block_state.executed_block_receipts(),
487            )
488        })
489    }
490
491    /// Subscribe to new blocks events.
492    pub fn subscribe_canon_state(&self) -> CanonStateNotifications<N> {
493        self.inner.canon_state_notification_sender.subscribe()
494    }
495
496    /// Subscribe to new safe block events.
497    pub fn subscribe_safe_block(&self) -> watch::Receiver<Option<SealedHeader<N::BlockHeader>>> {
498        self.inner.chain_info_tracker.subscribe_safe_block()
499    }
500
501    /// Subscribe to new finalized block events.
502    pub fn subscribe_finalized_block(
503        &self,
504    ) -> watch::Receiver<Option<SealedHeader<N::BlockHeader>>> {
505        self.inner.chain_info_tracker.subscribe_finalized_block()
506    }
507
508    /// Attempts to send a new [`CanonStateNotification`] to all active Receiver handles.
509    pub fn notify_canon_state(&self, event: CanonStateNotification<N>) {
510        self.inner.canon_state_notification_sender.send(event).ok();
511    }
512
513    /// Return state provider with reference to in-memory blocks that overlay database state.
514    ///
515    /// This merges the state of all blocks that are part of the chain that the requested block is
516    /// the head of. This includes all blocks that connect back to the canonical block on disk.
517    pub fn state_provider(
518        &self,
519        hash: B256,
520        historical: StateProviderBox,
521    ) -> MemoryOverlayStateProvider<N> {
522        let in_memory = if let Some(state) = self.state_by_hash(hash) {
523            state.chain().map(|block_state| block_state.block()).collect()
524        } else {
525            Vec::new()
526        };
527
528        MemoryOverlayStateProvider::new(historical, in_memory)
529    }
530
531    /// Returns an iterator over all __canonical blocks__ in the in-memory state, from newest to
532    /// oldest (highest to lowest).
533    ///
534    /// This iterator contains a snapshot of the in-memory state at the time of the call.
535    pub fn canonical_chain(&self) -> impl Iterator<Item = Arc<BlockState<N>>> {
536        self.inner.in_memory_state.head_state().into_iter().flat_map(|head| head.iter())
537    }
538
539    /// Returns [`SignedTransaction`] type for the given `TxHash` if found.
540    pub fn transaction_by_hash(&self, hash: TxHash) -> Option<N::SignedTx> {
541        for block_state in self.canonical_chain() {
542            if let Some(tx) =
543                block_state.block_ref().recovered_block().body().transaction_by_hash(&hash)
544            {
545                return Some(tx.clone())
546            }
547        }
548        None
549    }
550
551    /// Returns a tuple with [`SignedTransaction`] type and [`TransactionMeta`] for the
552    /// given [`TxHash`] if found.
553    pub fn transaction_by_hash_with_meta(
554        &self,
555        tx_hash: TxHash,
556    ) -> Option<(N::SignedTx, TransactionMeta)> {
557        for block_state in self.canonical_chain() {
558            if let Some(indexed) = block_state.find_indexed(tx_hash) {
559                return Some((indexed.tx().clone(), indexed.meta()));
560            }
561        }
562        None
563    }
564}
565
566/// State after applying the given block, this block is part of the canonical chain that partially
567/// stored in memory and can be traced back to a canonical block on disk.
568#[derive(Debug, Clone)]
569pub struct BlockState<N: NodePrimitives = EthPrimitives> {
570    /// The executed block that determines the state after this block has been executed.
571    block: ExecutedBlock<N>,
572    /// The block's parent block if it exists.
573    parent: Option<Arc<Self>>,
574}
575
576impl<N: NodePrimitives> PartialEq for BlockState<N> {
577    fn eq(&self, other: &Self) -> bool {
578        self.block == other.block && self.parent == other.parent
579    }
580}
581
582impl<N: NodePrimitives> BlockState<N> {
583    /// [`BlockState`] constructor.
584    pub const fn new(block: ExecutedBlock<N>) -> Self {
585        Self { block, parent: None }
586    }
587
588    /// [`BlockState`] constructor with parent.
589    pub const fn with_parent(block: ExecutedBlock<N>, parent: Option<Arc<Self>>) -> Self {
590        Self { block, parent }
591    }
592
593    /// Returns the hash and block of the on disk block this state can be traced back to.
594    pub fn anchor(&self) -> BlockNumHash {
595        let mut current = self;
596        while let Some(parent) = &current.parent {
597            current = parent;
598        }
599        current.block.recovered_block().parent_num_hash()
600    }
601
602    /// Returns the executed block that determines the state.
603    pub fn block(&self) -> ExecutedBlock<N> {
604        self.block.clone()
605    }
606
607    /// Returns a reference to the executed block that determines the state.
608    pub const fn block_ref(&self) -> &ExecutedBlock<N> {
609        &self.block
610    }
611
612    /// Returns the hash of executed block that determines the state.
613    pub fn hash(&self) -> B256 {
614        self.block.recovered_block().hash()
615    }
616
617    /// Returns the block number of executed block that determines the state.
618    pub fn number(&self) -> u64 {
619        self.block.recovered_block().number()
620    }
621
622    /// Returns the state root after applying the executed block that determines
623    /// the state.
624    pub fn state_root(&self) -> B256 {
625        self.block.recovered_block().state_root()
626    }
627
628    /// Returns the `Receipts` of executed block that determines the state.
629    pub fn receipts(&self) -> &Vec<Vec<N::Receipt>> {
630        &self.block.execution_outcome().receipts
631    }
632
633    /// Returns a vector of `Receipt` of executed block that determines the state.
634    /// We assume that the `Receipts` in the executed block `ExecutionOutcome`
635    /// has only one element corresponding to the executed block associated to
636    /// the state.
637    ///
638    /// This clones the vector of receipts. To avoid it, use [`Self::executed_block_receipts_ref`].
639    pub fn executed_block_receipts(&self) -> Vec<N::Receipt> {
640        let receipts = self.receipts();
641
642        debug_assert!(
643            receipts.len() <= 1,
644            "Expected at most one block's worth of receipts, found {}",
645            receipts.len()
646        );
647
648        receipts.first().cloned().unwrap_or_default()
649    }
650
651    /// Returns a slice of `Receipt` of executed block that determines the state.
652    /// We assume that the `Receipts` in the executed block `ExecutionOutcome`
653    /// has only one element corresponding to the executed block associated to
654    /// the state.
655    pub fn executed_block_receipts_ref(&self) -> &[N::Receipt] {
656        let receipts = self.receipts();
657
658        debug_assert!(
659            receipts.len() <= 1,
660            "Expected at most one block's worth of receipts, found {}",
661            receipts.len()
662        );
663
664        receipts.first().map(|receipts| receipts.deref()).unwrap_or_default()
665    }
666
667    /// Returns a vector of __parent__ `BlockStates`.
668    ///
669    /// The block state order in the output vector is newest to oldest (highest to lowest):
670    /// `[5,4,3,2,1]`
671    ///
672    /// Note: This does not include self.
673    pub fn parent_state_chain(&self) -> Vec<&Self> {
674        let mut parents = Vec::new();
675        let mut current = self.parent.as_deref();
676
677        while let Some(parent) = current {
678            parents.push(parent);
679            current = parent.parent.as_deref();
680        }
681
682        parents
683    }
684
685    /// Returns a vector of `BlockStates` representing the entire in memory chain.
686    /// The block state order in the output vector is newest to oldest (highest to lowest),
687    /// including self as the first element.
688    pub fn chain(&self) -> impl Iterator<Item = &Self> {
689        std::iter::successors(Some(self), |state| state.parent.as_deref())
690    }
691
692    /// Appends the parent chain of this [`BlockState`] to the given vector.
693    pub fn append_parent_chain<'a>(&'a self, chain: &mut Vec<&'a Self>) {
694        chain.extend(self.parent_state_chain());
695    }
696
697    /// Returns an iterator over the atomically captured chain of in memory blocks.
698    ///
699    /// This yields the blocks from newest to oldest (highest to lowest).
700    pub fn iter(self: Arc<Self>) -> impl Iterator<Item = Arc<Self>> {
701        std::iter::successors(Some(self), |state| state.parent.clone())
702    }
703
704    /// Return state provider with reference to in-memory blocks that overlay database state.
705    ///
706    /// This merges the state of all blocks that are part of the chain that the this block is
707    /// the head of. This includes all blocks that connect back to the canonical block on disk.
708    pub fn state_provider(&self, historical: StateProviderBox) -> MemoryOverlayStateProvider<N> {
709        let in_memory = self.chain().map(|block_state| block_state.block()).collect();
710
711        MemoryOverlayStateProvider::new(historical, in_memory)
712    }
713
714    /// Tries to find a block by [`BlockHashOrNumber`] in the chain ending at this block.
715    pub fn block_on_chain(&self, hash_or_num: BlockHashOrNumber) -> Option<&Self> {
716        self.chain().find(|block| match hash_or_num {
717            BlockHashOrNumber::Hash(hash) => block.hash() == hash,
718            BlockHashOrNumber::Number(number) => block.number() == number,
719        })
720    }
721
722    /// Tries to find a transaction by [`TxHash`] in the chain ending at this block.
723    pub fn transaction_on_chain(&self, hash: TxHash) -> Option<N::SignedTx> {
724        self.chain().find_map(|block_state| {
725            block_state.block_ref().recovered_block().body().transaction_by_hash(&hash).cloned()
726        })
727    }
728
729    /// Tries to find a transaction with meta by [`TxHash`] in the chain ending at this block.
730    pub fn transaction_meta_on_chain(
731        &self,
732        tx_hash: TxHash,
733    ) -> Option<(N::SignedTx, TransactionMeta)> {
734        self.chain().find_map(|block_state| {
735            block_state.find_indexed(tx_hash).map(|indexed| (indexed.tx().clone(), indexed.meta()))
736        })
737    }
738
739    /// Finds a transaction by hash and returns it with its index and block context.
740    pub fn find_indexed(&self, tx_hash: TxHash) -> Option<IndexedTx<'_, N::Block>> {
741        self.block_ref().recovered_block().find_indexed(tx_hash)
742    }
743}
744
745/// Represents an executed block stored in-memory.
746#[derive(Clone, Debug)]
747pub struct ExecutedBlock<N: NodePrimitives = EthPrimitives> {
748    /// Recovered Block
749    pub recovered_block: Arc<RecoveredBlock<N::Block>>,
750    /// Block's execution outcome.
751    pub execution_output: Arc<ExecutionOutcome<N::Receipt>>,
752    /// Deferred trie data produced by execution.
753    ///
754    /// This allows deferring the computation of the trie data which can be expensive.
755    /// The data can be populated asynchronously after the block was validated.
756    pub trie_data: DeferredTrieData,
757}
758
759impl<N: NodePrimitives> Default for ExecutedBlock<N> {
760    fn default() -> Self {
761        Self {
762            recovered_block: Default::default(),
763            execution_output: Default::default(),
764            trie_data: DeferredTrieData::ready(ComputedTrieData::default()),
765        }
766    }
767}
768
769impl<N: NodePrimitives> PartialEq for ExecutedBlock<N> {
770    fn eq(&self, other: &Self) -> bool {
771        // Trie data is computed asynchronously and doesn't define block identity.
772        self.recovered_block == other.recovered_block &&
773            self.execution_output == other.execution_output
774    }
775}
776
777impl<N: NodePrimitives> ExecutedBlock<N> {
778    /// Create a new [`ExecutedBlock`] with already-computed trie data.
779    ///
780    /// Use this constructor when trie data is available immediately (e.g., sequencers,
781    /// payload builders). This is the safe default path.
782    pub fn new(
783        recovered_block: Arc<RecoveredBlock<N::Block>>,
784        execution_output: Arc<ExecutionOutcome<N::Receipt>>,
785        trie_data: ComputedTrieData,
786    ) -> Self {
787        Self { recovered_block, execution_output, trie_data: DeferredTrieData::ready(trie_data) }
788    }
789
790    /// Create a new [`ExecutedBlock`] with deferred trie data.
791    ///
792    /// This is useful if the trie data is populated somewhere else, e.g. asynchronously
793    /// after the block was validated.
794    ///
795    /// The [`DeferredTrieData`] handle allows expensive trie operations (sorting hashed state,
796    /// sorting trie updates, and building the accumulated trie input overlay) to be performed
797    /// outside the critical validation path. This can improve latency for time-sensitive
798    /// operations like block validation.
799    ///
800    /// If the data hasn't been populated when [`Self::trie_data()`] is called, computation
801    /// occurs synchronously from stored inputs, so there is no blocking or deadlock risk.
802    ///
803    /// Use [`Self::new()`] instead when trie data is already computed and available immediately.
804    pub const fn with_deferred_trie_data(
805        recovered_block: Arc<RecoveredBlock<N::Block>>,
806        execution_output: Arc<ExecutionOutcome<N::Receipt>>,
807        trie_data: DeferredTrieData,
808    ) -> Self {
809        Self { recovered_block, execution_output, trie_data }
810    }
811
812    /// Returns a reference to an inner [`SealedBlock`]
813    #[inline]
814    pub fn sealed_block(&self) -> &SealedBlock<N::Block> {
815        self.recovered_block.sealed_block()
816    }
817
818    /// Returns a reference to [`RecoveredBlock`]
819    #[inline]
820    pub fn recovered_block(&self) -> &RecoveredBlock<N::Block> {
821        &self.recovered_block
822    }
823
824    /// Returns a reference to the block's execution outcome
825    #[inline]
826    pub fn execution_outcome(&self) -> &ExecutionOutcome<N::Receipt> {
827        &self.execution_output
828    }
829
830    /// Returns the trie data, computing it synchronously if not already cached.
831    ///
832    /// Uses `OnceLock::get_or_init` internally:
833    /// - If already computed: returns cached result immediately
834    /// - If not computed: first caller computes, others wait for that result
835    #[inline]
836    #[tracing::instrument(level = "debug", target = "engine::tree", name = "trie_data", skip_all)]
837    pub fn trie_data(&self) -> ComputedTrieData {
838        self.trie_data.wait_cloned()
839    }
840
841    /// Returns a clone of the deferred trie data handle.
842    ///
843    /// A handle is a lightweight reference that can be passed to descendants without
844    /// forcing trie data to be computed immediately. The actual work runs when
845    /// `wait_cloned()` is called by a consumer (e.g. when merging overlays).
846    #[inline]
847    pub fn trie_data_handle(&self) -> DeferredTrieData {
848        self.trie_data.clone()
849    }
850
851    /// Returns the hashed state result of the execution outcome.
852    ///
853    /// May compute trie data synchronously if the deferred task hasn't completed.
854    #[inline]
855    pub fn hashed_state(&self) -> Arc<HashedPostStateSorted> {
856        self.trie_data().hashed_state
857    }
858
859    /// Returns the trie updates resulting from the execution outcome.
860    ///
861    /// May compute trie data synchronously if the deferred task hasn't completed.
862    #[inline]
863    pub fn trie_updates(&self) -> Arc<TrieUpdatesSorted> {
864        self.trie_data().trie_updates
865    }
866
867    /// Returns the trie input anchored to the persisted ancestor.
868    ///
869    /// May compute trie data synchronously if the deferred task hasn't completed.
870    #[inline]
871    pub fn trie_input(&self) -> Option<Arc<TrieInputSorted>> {
872        self.trie_data().trie_input().cloned()
873    }
874
875    /// Returns the anchor hash of the trie input, if present.
876    #[inline]
877    pub fn anchor_hash(&self) -> Option<B256> {
878        self.trie_data().anchor_hash()
879    }
880
881    /// Returns a [`BlockNumber`] of the block.
882    #[inline]
883    pub fn block_number(&self) -> BlockNumber {
884        self.recovered_block.header().number()
885    }
886}
887
888/// Non-empty chain of blocks.
889#[derive(Debug)]
890pub enum NewCanonicalChain<N: NodePrimitives = EthPrimitives> {
891    /// A simple append to the current canonical head
892    Commit {
893        /// all blocks that lead back to the canonical head
894        new: Vec<ExecutedBlock<N>>,
895    },
896    /// A reorged chain consists of two chains that trace back to a shared ancestor block at which
897    /// point they diverge.
898    Reorg {
899        /// All blocks of the _new_ chain
900        new: Vec<ExecutedBlock<N>>,
901        /// All blocks of the _old_ chain
902        old: Vec<ExecutedBlock<N>>,
903    },
904}
905
906impl<N: NodePrimitives<SignedTx: SignedTransaction>> NewCanonicalChain<N> {
907    /// Returns the length of the new chain.
908    pub const fn new_block_count(&self) -> usize {
909        match self {
910            Self::Commit { new } | Self::Reorg { new, .. } => new.len(),
911        }
912    }
913
914    /// Returns the length of the reorged chain.
915    pub const fn reorged_block_count(&self) -> usize {
916        match self {
917            Self::Commit { .. } => 0,
918            Self::Reorg { old, .. } => old.len(),
919        }
920    }
921
922    /// Converts the new chain into a notification that will be emitted to listeners
923    pub fn to_chain_notification(&self) -> CanonStateNotification<N> {
924        match self {
925            Self::Commit { new } => {
926                let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| {
927                    chain.append_block(
928                        exec.recovered_block().clone(),
929                        exec.execution_outcome().clone(),
930                    );
931                    chain
932                }));
933                CanonStateNotification::Commit { new }
934            }
935            Self::Reorg { new, old } => {
936                let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| {
937                    chain.append_block(
938                        exec.recovered_block().clone(),
939                        exec.execution_outcome().clone(),
940                    );
941                    chain
942                }));
943                let old = Arc::new(old.iter().fold(Chain::default(), |mut chain, exec| {
944                    chain.append_block(
945                        exec.recovered_block().clone(),
946                        exec.execution_outcome().clone(),
947                    );
948                    chain
949                }));
950                CanonStateNotification::Reorg { new, old }
951            }
952        }
953    }
954
955    /// Returns the new tip of the chain.
956    ///
957    /// Returns the new tip for [`Self::Reorg`] and [`Self::Commit`] variants which commit at least
958    /// 1 new block.
959    pub fn tip(&self) -> &SealedBlock<N::Block> {
960        match self {
961            Self::Commit { new } | Self::Reorg { new, .. } => {
962                new.last().expect("non empty blocks").recovered_block()
963            }
964        }
965    }
966}
967
968#[cfg(test)]
969mod tests {
970    use super::*;
971    use crate::test_utils::TestBlockBuilder;
972    use alloy_eips::eip7685::Requests;
973    use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, StorageValue};
974    use rand::Rng;
975    use reth_errors::ProviderResult;
976    use reth_ethereum_primitives::{EthPrimitives, Receipt};
977    use reth_primitives_traits::{Account, Bytecode};
978    use reth_storage_api::{
979        AccountReader, BlockHashReader, BytecodeReader, HashedPostStateProvider,
980        StateProofProvider, StateProvider, StateRootProvider, StorageRootProvider,
981    };
982    use reth_trie::{
983        updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof,
984        MultiProofTargets, StorageMultiProof, StorageProof, TrieInput,
985    };
986
987    fn create_mock_state(
988        test_block_builder: &mut TestBlockBuilder<EthPrimitives>,
989        block_number: u64,
990        parent_hash: B256,
991    ) -> BlockState {
992        BlockState::new(
993            test_block_builder.get_executed_block_with_number(block_number, parent_hash),
994        )
995    }
996
997    fn create_mock_state_chain(
998        test_block_builder: &mut TestBlockBuilder<EthPrimitives>,
999        num_blocks: u64,
1000    ) -> Vec<BlockState> {
1001        let mut chain = Vec::with_capacity(num_blocks as usize);
1002        let mut parent_hash = B256::random();
1003        let mut parent_state: Option<BlockState> = None;
1004
1005        for i in 1..=num_blocks {
1006            let mut state = create_mock_state(test_block_builder, i, parent_hash);
1007            if let Some(parent) = parent_state {
1008                state.parent = Some(Arc::new(parent));
1009            }
1010            parent_hash = state.hash();
1011            parent_state = Some(state.clone());
1012            chain.push(state);
1013        }
1014
1015        chain
1016    }
1017
1018    struct MockStateProvider;
1019
1020    impl StateProvider for MockStateProvider {
1021        fn storage(
1022            &self,
1023            _address: Address,
1024            _storage_key: StorageKey,
1025        ) -> ProviderResult<Option<StorageValue>> {
1026            Ok(None)
1027        }
1028    }
1029
1030    impl BytecodeReader for MockStateProvider {
1031        fn bytecode_by_hash(&self, _code_hash: &B256) -> ProviderResult<Option<Bytecode>> {
1032            Ok(None)
1033        }
1034    }
1035
1036    impl BlockHashReader for MockStateProvider {
1037        fn block_hash(&self, _number: BlockNumber) -> ProviderResult<Option<B256>> {
1038            Ok(None)
1039        }
1040
1041        fn canonical_hashes_range(
1042            &self,
1043            _start: BlockNumber,
1044            _end: BlockNumber,
1045        ) -> ProviderResult<Vec<B256>> {
1046            Ok(vec![])
1047        }
1048    }
1049
1050    impl AccountReader for MockStateProvider {
1051        fn basic_account(&self, _address: &Address) -> ProviderResult<Option<Account>> {
1052            Ok(None)
1053        }
1054    }
1055
1056    impl StateRootProvider for MockStateProvider {
1057        fn state_root(&self, _hashed_state: HashedPostState) -> ProviderResult<B256> {
1058            Ok(B256::random())
1059        }
1060
1061        fn state_root_from_nodes(&self, _input: TrieInput) -> ProviderResult<B256> {
1062            Ok(B256::random())
1063        }
1064
1065        fn state_root_with_updates(
1066            &self,
1067            _hashed_state: HashedPostState,
1068        ) -> ProviderResult<(B256, TrieUpdates)> {
1069            Ok((B256::random(), TrieUpdates::default()))
1070        }
1071
1072        fn state_root_from_nodes_with_updates(
1073            &self,
1074            _input: TrieInput,
1075        ) -> ProviderResult<(B256, TrieUpdates)> {
1076            Ok((B256::random(), TrieUpdates::default()))
1077        }
1078    }
1079
1080    impl HashedPostStateProvider for MockStateProvider {
1081        fn hashed_post_state(&self, _bundle_state: &revm_database::BundleState) -> HashedPostState {
1082            HashedPostState::default()
1083        }
1084    }
1085
1086    impl StorageRootProvider for MockStateProvider {
1087        fn storage_root(
1088            &self,
1089            _address: Address,
1090            _hashed_storage: HashedStorage,
1091        ) -> ProviderResult<B256> {
1092            Ok(B256::random())
1093        }
1094
1095        fn storage_proof(
1096            &self,
1097            _address: Address,
1098            slot: B256,
1099            _hashed_storage: HashedStorage,
1100        ) -> ProviderResult<StorageProof> {
1101            Ok(StorageProof::new(slot))
1102        }
1103
1104        fn storage_multiproof(
1105            &self,
1106            _address: Address,
1107            _slots: &[B256],
1108            _hashed_storage: HashedStorage,
1109        ) -> ProviderResult<StorageMultiProof> {
1110            Ok(StorageMultiProof::empty())
1111        }
1112    }
1113
1114    impl StateProofProvider for MockStateProvider {
1115        fn proof(
1116            &self,
1117            _input: TrieInput,
1118            _address: Address,
1119            _slots: &[B256],
1120        ) -> ProviderResult<AccountProof> {
1121            Ok(AccountProof::new(Address::random()))
1122        }
1123
1124        fn multiproof(
1125            &self,
1126            _input: TrieInput,
1127            _targets: MultiProofTargets,
1128        ) -> ProviderResult<MultiProof> {
1129            Ok(MultiProof::default())
1130        }
1131
1132        fn witness(
1133            &self,
1134            _input: TrieInput,
1135            _target: HashedPostState,
1136        ) -> ProviderResult<Vec<Bytes>> {
1137            Ok(Vec::default())
1138        }
1139    }
1140
1141    #[test]
1142    fn test_in_memory_state_impl_state_by_hash() {
1143        let mut state_by_hash = HashMap::default();
1144        let number = rand::rng().random::<u64>();
1145        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1146        let state = Arc::new(create_mock_state(&mut test_block_builder, number, B256::random()));
1147        state_by_hash.insert(state.hash(), state.clone());
1148
1149        let in_memory_state = InMemoryState::new(state_by_hash, BTreeMap::new(), None);
1150
1151        assert_eq!(in_memory_state.state_by_hash(state.hash()), Some(state));
1152        assert_eq!(in_memory_state.state_by_hash(B256::random()), None);
1153    }
1154
1155    #[test]
1156    fn test_in_memory_state_impl_state_by_number() {
1157        let mut state_by_hash = HashMap::default();
1158        let mut hash_by_number = BTreeMap::new();
1159
1160        let number = rand::rng().random::<u64>();
1161        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1162        let state = Arc::new(create_mock_state(&mut test_block_builder, number, B256::random()));
1163        let hash = state.hash();
1164
1165        state_by_hash.insert(hash, state.clone());
1166        hash_by_number.insert(number, hash);
1167
1168        let in_memory_state = InMemoryState::new(state_by_hash, hash_by_number, None);
1169
1170        assert_eq!(in_memory_state.state_by_number(number), Some(state));
1171        assert_eq!(in_memory_state.state_by_number(number + 1), None);
1172    }
1173
1174    #[test]
1175    fn test_in_memory_state_impl_head_state() {
1176        let mut state_by_hash = HashMap::default();
1177        let mut hash_by_number = BTreeMap::new();
1178        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1179        let state1 = Arc::new(create_mock_state(&mut test_block_builder, 1, B256::random()));
1180        let hash1 = state1.hash();
1181        let state2 = Arc::new(create_mock_state(&mut test_block_builder, 2, hash1));
1182        let hash2 = state2.hash();
1183        hash_by_number.insert(1, hash1);
1184        hash_by_number.insert(2, hash2);
1185        state_by_hash.insert(hash1, state1);
1186        state_by_hash.insert(hash2, state2);
1187
1188        let in_memory_state = InMemoryState::new(state_by_hash, hash_by_number, None);
1189        let head_state = in_memory_state.head_state().unwrap();
1190
1191        assert_eq!(head_state.hash(), hash2);
1192        assert_eq!(head_state.number(), 2);
1193    }
1194
1195    #[test]
1196    fn test_in_memory_state_impl_pending_state() {
1197        let pending_number = rand::rng().random::<u64>();
1198        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1199        let pending_state =
1200            create_mock_state(&mut test_block_builder, pending_number, B256::random());
1201        let pending_hash = pending_state.hash();
1202
1203        let in_memory_state =
1204            InMemoryState::new(HashMap::default(), BTreeMap::new(), Some(pending_state));
1205
1206        let result = in_memory_state.pending_state();
1207        assert!(result.is_some());
1208        let actual_pending_state = result.unwrap();
1209        assert_eq!(actual_pending_state.block.recovered_block().hash(), pending_hash);
1210        assert_eq!(actual_pending_state.block.recovered_block().number, pending_number);
1211    }
1212
1213    #[test]
1214    fn test_in_memory_state_impl_no_pending_state() {
1215        let in_memory_state: InMemoryState =
1216            InMemoryState::new(HashMap::default(), BTreeMap::new(), None);
1217
1218        assert_eq!(in_memory_state.pending_state(), None);
1219    }
1220
1221    #[test]
1222    fn test_state() {
1223        let number = rand::rng().random::<u64>();
1224        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1225        let block = test_block_builder.get_executed_block_with_number(number, B256::random());
1226
1227        let state = BlockState::new(block.clone());
1228
1229        assert_eq!(state.block(), block);
1230        assert_eq!(state.hash(), block.recovered_block().hash());
1231        assert_eq!(state.number(), number);
1232        assert_eq!(state.state_root(), block.recovered_block().state_root);
1233    }
1234
1235    #[test]
1236    fn test_state_receipts() {
1237        let receipts = vec![vec![Receipt::default()]];
1238        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1239        let block =
1240            test_block_builder.get_executed_block_with_receipts(receipts.clone(), B256::random());
1241
1242        let state = BlockState::new(block);
1243
1244        assert_eq!(state.receipts(), &receipts);
1245    }
1246
1247    #[test]
1248    fn test_in_memory_state_chain_update() {
1249        let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1250        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1251        let block1 = test_block_builder.get_executed_block_with_number(0, B256::random());
1252        let block2 = test_block_builder.get_executed_block_with_number(0, B256::random());
1253        let chain = NewCanonicalChain::Commit { new: vec![block1.clone()] };
1254        state.update_chain(chain);
1255        assert_eq!(
1256            state.head_state().unwrap().block_ref().recovered_block().hash(),
1257            block1.recovered_block().hash()
1258        );
1259        assert_eq!(
1260            state.state_by_number(0).unwrap().block_ref().recovered_block().hash(),
1261            block1.recovered_block().hash()
1262        );
1263
1264        let chain = NewCanonicalChain::Reorg { new: vec![block2.clone()], old: vec![block1] };
1265        state.update_chain(chain);
1266        assert_eq!(
1267            state.head_state().unwrap().block_ref().recovered_block().hash(),
1268            block2.recovered_block().hash()
1269        );
1270        assert_eq!(
1271            state.state_by_number(0).unwrap().block_ref().recovered_block().hash(),
1272            block2.recovered_block().hash()
1273        );
1274
1275        assert_eq!(state.inner.in_memory_state.block_count(), 1);
1276    }
1277
1278    #[test]
1279    fn test_in_memory_state_set_pending_block() {
1280        let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1281        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1282
1283        // First random block
1284        let block1 = test_block_builder.get_executed_block_with_number(0, B256::random());
1285
1286        // Second block with parent hash of the first block
1287        let block2 =
1288            test_block_builder.get_executed_block_with_number(1, block1.recovered_block().hash());
1289
1290        // Commit the two blocks
1291        let chain = NewCanonicalChain::Commit { new: vec![block1.clone(), block2.clone()] };
1292        state.update_chain(chain);
1293
1294        // Assert that the pending state is None before setting it
1295        assert!(state.pending_state().is_none());
1296
1297        // Set the pending block
1298        state.set_pending_block(block2.clone());
1299
1300        // Check the pending state
1301        assert_eq!(
1302            state.pending_state().unwrap(),
1303            BlockState::with_parent(block2.clone(), Some(Arc::new(BlockState::new(block1))))
1304        );
1305
1306        // Check the pending block
1307        assert_eq!(state.pending_block().unwrap(), block2.recovered_block().sealed_block().clone());
1308
1309        // Check the pending block number and hash
1310        assert_eq!(
1311            state.pending_block_num_hash().unwrap(),
1312            BlockNumHash { number: 1, hash: block2.recovered_block().hash() }
1313        );
1314
1315        // Check the pending header
1316        assert_eq!(state.pending_header().unwrap(), block2.recovered_block().header().clone());
1317
1318        // Check the pending sealed header
1319        assert_eq!(
1320            state.pending_sealed_header().unwrap(),
1321            block2.recovered_block().clone_sealed_header()
1322        );
1323
1324        // Check the pending block with senders
1325        assert_eq!(state.pending_recovered_block().unwrap(), block2.recovered_block().clone());
1326
1327        // Check the pending block and receipts
1328        assert_eq!(
1329            state.pending_block_and_receipts().unwrap(),
1330            (block2.recovered_block().clone(), vec![])
1331        );
1332    }
1333
1334    #[test]
1335    fn test_canonical_in_memory_state_state_provider() {
1336        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1337        let block1 = test_block_builder.get_executed_block_with_number(1, B256::random());
1338        let block2 =
1339            test_block_builder.get_executed_block_with_number(2, block1.recovered_block().hash());
1340        let block3 =
1341            test_block_builder.get_executed_block_with_number(3, block2.recovered_block().hash());
1342
1343        let state1 = Arc::new(BlockState::new(block1.clone()));
1344        let state2 = Arc::new(BlockState::with_parent(block2.clone(), Some(state1.clone())));
1345        let state3 = Arc::new(BlockState::with_parent(block3.clone(), Some(state2.clone())));
1346
1347        let mut blocks = HashMap::default();
1348        blocks.insert(block1.recovered_block().hash(), state1);
1349        blocks.insert(block2.recovered_block().hash(), state2);
1350        blocks.insert(block3.recovered_block().hash(), state3);
1351
1352        let mut numbers = BTreeMap::new();
1353        numbers.insert(1, block1.recovered_block().hash());
1354        numbers.insert(2, block2.recovered_block().hash());
1355        numbers.insert(3, block3.recovered_block().hash());
1356
1357        let canonical_state = CanonicalInMemoryState::new(blocks, numbers, None, None, None);
1358
1359        let historical: StateProviderBox = Box::new(MockStateProvider);
1360
1361        let overlay_provider =
1362            canonical_state.state_provider(block3.recovered_block().hash(), historical);
1363
1364        assert_eq!(overlay_provider.in_memory.len(), 3);
1365        assert_eq!(overlay_provider.in_memory[0].recovered_block().number, 3);
1366        assert_eq!(overlay_provider.in_memory[1].recovered_block().number, 2);
1367        assert_eq!(overlay_provider.in_memory[2].recovered_block().number, 1);
1368
1369        assert_eq!(
1370            overlay_provider.in_memory[0].recovered_block().parent_hash,
1371            overlay_provider.in_memory[1].recovered_block().hash()
1372        );
1373        assert_eq!(
1374            overlay_provider.in_memory[1].recovered_block().parent_hash,
1375            overlay_provider.in_memory[2].recovered_block().hash()
1376        );
1377
1378        let unknown_hash = B256::random();
1379        let empty_overlay_provider =
1380            canonical_state.state_provider(unknown_hash, Box::new(MockStateProvider));
1381        assert_eq!(empty_overlay_provider.in_memory.len(), 0);
1382    }
1383
1384    #[test]
1385    fn test_canonical_in_memory_state_canonical_chain_empty() {
1386        let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1387        assert!(state.canonical_chain().next().is_none());
1388    }
1389
1390    #[test]
1391    fn test_canonical_in_memory_state_canonical_chain_single_block() {
1392        let block = TestBlockBuilder::eth().get_executed_block_with_number(1, B256::random());
1393        let hash = block.recovered_block().hash();
1394        let mut blocks = HashMap::default();
1395        blocks.insert(hash, Arc::new(BlockState::new(block)));
1396        let mut numbers = BTreeMap::new();
1397        numbers.insert(1, hash);
1398
1399        let state = CanonicalInMemoryState::new(blocks, numbers, None, None, None);
1400        let chain: Vec<_> = state.canonical_chain().collect();
1401
1402        assert_eq!(chain.len(), 1);
1403        assert_eq!(chain[0].number(), 1);
1404        assert_eq!(chain[0].hash(), hash);
1405    }
1406
1407    #[test]
1408    fn test_canonical_in_memory_state_canonical_chain_multiple_blocks() {
1409        let mut parent_hash = B256::random();
1410        let mut block_builder = TestBlockBuilder::eth();
1411        let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1412
1413        for i in 1..=3 {
1414            let block = block_builder.get_executed_block_with_number(i, parent_hash);
1415            let hash = block.recovered_block().hash();
1416            state.update_blocks(Some(block), None);
1417            parent_hash = hash;
1418        }
1419
1420        let chain: Vec<_> = state.canonical_chain().collect();
1421
1422        assert_eq!(chain.len(), 3);
1423        assert_eq!(chain[0].number(), 3);
1424        assert_eq!(chain[1].number(), 2);
1425        assert_eq!(chain[2].number(), 1);
1426    }
1427
1428    // ensures the pending block is not part of the canonical chain
1429    #[test]
1430    fn test_canonical_in_memory_state_canonical_chain_with_pending_block() {
1431        let mut parent_hash = B256::random();
1432        let mut block_builder = TestBlockBuilder::<EthPrimitives>::eth();
1433        let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1434
1435        for i in 1..=2 {
1436            let block = block_builder.get_executed_block_with_number(i, parent_hash);
1437            let hash = block.recovered_block().hash();
1438            state.update_blocks(Some(block), None);
1439            parent_hash = hash;
1440        }
1441
1442        let pending_block = block_builder.get_executed_block_with_number(3, parent_hash);
1443        state.set_pending_block(pending_block);
1444        let chain: Vec<_> = state.canonical_chain().collect();
1445
1446        assert_eq!(chain.len(), 2);
1447        assert_eq!(chain[0].number(), 2);
1448        assert_eq!(chain[1].number(), 1);
1449    }
1450
1451    #[test]
1452    fn test_block_state_parent_blocks() {
1453        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1454        let chain = create_mock_state_chain(&mut test_block_builder, 4);
1455
1456        let parents = chain[3].parent_state_chain();
1457        assert_eq!(parents.len(), 3);
1458        assert_eq!(parents[0].block().recovered_block().number, 3);
1459        assert_eq!(parents[1].block().recovered_block().number, 2);
1460        assert_eq!(parents[2].block().recovered_block().number, 1);
1461
1462        let parents = chain[2].parent_state_chain();
1463        assert_eq!(parents.len(), 2);
1464        assert_eq!(parents[0].block().recovered_block().number, 2);
1465        assert_eq!(parents[1].block().recovered_block().number, 1);
1466
1467        let parents = chain[0].parent_state_chain();
1468        assert_eq!(parents.len(), 0);
1469    }
1470
1471    #[test]
1472    fn test_block_state_single_block_state_chain() {
1473        let single_block_number = 1;
1474        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1475        let single_block =
1476            create_mock_state(&mut test_block_builder, single_block_number, B256::random());
1477        let single_block_hash = single_block.block().recovered_block().hash();
1478
1479        let parents = single_block.parent_state_chain();
1480        assert_eq!(parents.len(), 0);
1481
1482        let block_state_chain = single_block.chain().collect::<Vec<_>>();
1483        assert_eq!(block_state_chain.len(), 1);
1484        assert_eq!(block_state_chain[0].block().recovered_block().number, single_block_number);
1485        assert_eq!(block_state_chain[0].block().recovered_block().hash(), single_block_hash);
1486    }
1487
1488    #[test]
1489    fn test_block_state_chain() {
1490        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1491        let chain = create_mock_state_chain(&mut test_block_builder, 3);
1492
1493        let block_state_chain = chain[2].chain().collect::<Vec<_>>();
1494        assert_eq!(block_state_chain.len(), 3);
1495        assert_eq!(block_state_chain[0].block().recovered_block().number, 3);
1496        assert_eq!(block_state_chain[1].block().recovered_block().number, 2);
1497        assert_eq!(block_state_chain[2].block().recovered_block().number, 1);
1498
1499        let block_state_chain = chain[1].chain().collect::<Vec<_>>();
1500        assert_eq!(block_state_chain.len(), 2);
1501        assert_eq!(block_state_chain[0].block().recovered_block().number, 2);
1502        assert_eq!(block_state_chain[1].block().recovered_block().number, 1);
1503
1504        let block_state_chain = chain[0].chain().collect::<Vec<_>>();
1505        assert_eq!(block_state_chain.len(), 1);
1506        assert_eq!(block_state_chain[0].block().recovered_block().number, 1);
1507    }
1508
1509    #[test]
1510    fn test_to_chain_notification() {
1511        // Generate 4 blocks
1512        let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1513        let block0 = test_block_builder.get_executed_block_with_number(0, B256::random());
1514        let block1 =
1515            test_block_builder.get_executed_block_with_number(1, block0.recovered_block.hash());
1516        let block1a =
1517            test_block_builder.get_executed_block_with_number(1, block0.recovered_block.hash());
1518        let block2 =
1519            test_block_builder.get_executed_block_with_number(2, block1.recovered_block.hash());
1520        let block2a =
1521            test_block_builder.get_executed_block_with_number(2, block1.recovered_block.hash());
1522
1523        let sample_execution_outcome = ExecutionOutcome {
1524            receipts: vec![vec![], vec![]],
1525            requests: vec![Requests::default(), Requests::default()],
1526            ..Default::default()
1527        };
1528
1529        // Test commit notification
1530        let chain_commit = NewCanonicalChain::Commit { new: vec![block0.clone(), block1.clone()] };
1531
1532        assert_eq!(
1533            chain_commit.to_chain_notification(),
1534            CanonStateNotification::Commit {
1535                new: Arc::new(Chain::new(
1536                    vec![block0.recovered_block().clone(), block1.recovered_block().clone()],
1537                    sample_execution_outcome.clone(),
1538                    None
1539                ))
1540            }
1541        );
1542
1543        // Test reorg notification
1544        let chain_reorg = NewCanonicalChain::Reorg {
1545            new: vec![block1a.clone(), block2a.clone()],
1546            old: vec![block1.clone(), block2.clone()],
1547        };
1548
1549        assert_eq!(
1550            chain_reorg.to_chain_notification(),
1551            CanonStateNotification::Reorg {
1552                old: Arc::new(Chain::new(
1553                    vec![block1.recovered_block().clone(), block2.recovered_block().clone()],
1554                    sample_execution_outcome.clone(),
1555                    None
1556                )),
1557                new: Arc::new(Chain::new(
1558                    vec![block1a.recovered_block().clone(), block2a.recovered_block().clone()],
1559                    sample_execution_outcome,
1560                    None
1561                ))
1562            }
1563        );
1564    }
1565}