Skip to main content

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