1use 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
27const CANON_STATE_NOTIFICATION_CHANNEL_SIZE: usize = 256;
29
30#[derive(Metrics)]
32#[metrics(scope = "blockchain_tree.in_mem_state")]
33pub(crate) struct InMemoryStateMetrics {
34 pub(crate) earliest_block: Gauge,
36 pub(crate) latest_block: Gauge,
38 pub(crate) num_blocks: Gauge,
40}
41
42#[derive(Debug, Default)]
58pub(crate) struct InMemoryState<N: NodePrimitives = EthPrimitives> {
59 blocks: RwLock<B256Map<Arc<BlockState<N>>>>,
61 numbers: RwLock<BTreeMap<u64, B256>>,
63 pending: watch::Sender<Option<BlockState<N>>>,
65 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 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 pub(crate) fn state_by_hash(&self, hash: B256) -> Option<Arc<BlockState<N>>> {
110 self.blocks.read().get(&hash).cloned()
111 }
112
113 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 pub(crate) fn hash_by_number(&self, number: u64) -> Option<B256> {
121 self.numbers.read().get(&number).copied()
122 }
123
124 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 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#[derive(Debug)]
145pub(crate) struct CanonicalInMemoryStateInner<N: NodePrimitives> {
146 pub(crate) chain_info_tracker: ChainInfoTracker<N>,
149 pub(crate) in_memory_state: InMemoryState<N>,
151 pub(crate) canon_state_notification_sender: CanonStateNotificationSender<N>,
153}
154
155impl<N: NodePrimitives> CanonicalInMemoryStateInner<N> {
156 fn clear(&self) {
158 {
159 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#[derive(Debug, Clone)]
179pub struct CanonicalInMemoryState<N: NodePrimitives = EthPrimitives> {
180 pub(crate) inner: Arc<CanonicalInMemoryStateInner<N>>,
181}
182
183impl<N: NodePrimitives> CanonicalInMemoryState<N> {
184 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 pub fn empty() -> Self {
212 Self::new(B256Map::default(), BTreeMap::new(), None, None, None)
213 }
214
215 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 pub fn hash_by_number(&self, number: u64) -> Option<B256> {
237 self.inner.in_memory_state.hash_by_number(number)
238 }
239
240 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 pub fn clear_state(&self) {
248 self.inner.clear()
249 }
250
251 pub fn set_pending_block(&self, pending: ExecutedBlock<N>) {
255 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 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 let mut numbers = self.inner.in_memory_state.numbers.write();
276 let mut blocks = self.inner.in_memory_state.blocks.write();
277
278 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 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 blocks.insert(hash, Arc::new(block_state));
295 numbers.insert(number, hash);
296 }
297
298 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 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 pub fn remove_persisted_blocks(&self, persisted_num_hash: BlockNumHash) {
323 self.set_persisted(persisted_num_hash);
324 {
329 if self.inner.in_memory_state.blocks.read().get(&persisted_num_hash.hash).is_none() {
330 return
332 }
333 }
334
335 {
336 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 numbers.clear();
344
345 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 old_blocks.sort_unstable_by_key(|block| block.recovered_block().number());
355
356 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 blocks.insert(hash, Arc::new(block_state));
365 numbers.insert(number, hash);
366 }
367
368 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 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 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 pub fn head_state(&self) -> Option<Arc<BlockState<N>>> {
390 self.inner.in_memory_state.head_state()
391 }
392
393 pub fn pending_state(&self) -> Option<BlockState<N>> {
395 self.inner.in_memory_state.pending_state()
396 }
397
398 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 pub fn chain_info(&self) -> ChainInfo {
408 self.inner.chain_info_tracker.chain_info()
409 }
410
411 pub fn get_canonical_block_number(&self) -> u64 {
413 self.inner.chain_info_tracker.get_canonical_block_number()
414 }
415
416 pub fn get_safe_num_hash(&self) -> Option<BlockNumHash> {
418 self.inner.chain_info_tracker.get_safe_num_hash()
419 }
420
421 pub fn get_finalized_num_hash(&self) -> Option<BlockNumHash> {
423 self.inner.chain_info_tracker.get_finalized_num_hash()
424 }
425
426 pub fn on_forkchoice_update_received(&self) {
428 self.inner.chain_info_tracker.on_forkchoice_update_received();
429 }
430
431 pub fn last_received_update_timestamp(&self) -> Option<Instant> {
433 self.inner.chain_info_tracker.last_forkchoice_update_received_at()
434 }
435
436 pub fn set_canonical_head(&self, header: SealedHeader<N::BlockHeader>) {
438 self.inner.chain_info_tracker.set_canonical_head(header);
439 }
440
441 pub fn set_safe(&self, header: SealedHeader<N::BlockHeader>) {
443 self.inner.chain_info_tracker.set_safe(header);
444 }
445
446 pub fn set_finalized(&self, header: SealedHeader<N::BlockHeader>) {
448 self.inner.chain_info_tracker.set_finalized(header);
449 }
450
451 pub fn set_persisted(&self, num_hash: BlockNumHash) {
453 self.inner.chain_info_tracker.set_persisted(num_hash);
454 }
455
456 pub fn get_canonical_head(&self) -> SealedHeader<N::BlockHeader> {
458 self.inner.chain_info_tracker.get_canonical_head()
459 }
460
461 pub fn get_finalized_header(&self) -> Option<SealedHeader<N::BlockHeader>> {
463 self.inner.chain_info_tracker.get_finalized_header()
464 }
465
466 pub fn get_safe_header(&self) -> Option<SealedHeader<N::BlockHeader>> {
468 self.inner.chain_info_tracker.get_safe_header()
469 }
470
471 pub fn get_persisted_num_hash(&self) -> Option<BlockNumHash> {
473 self.inner.chain_info_tracker.get_persisted_num_hash()
474 }
475
476 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 pub fn pending_header(&self) -> Option<N::BlockHeader> {
483 self.pending_sealed_header().map(|sealed_header| sealed_header.unseal())
484 }
485
486 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 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 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 pub fn subscribe_canon_state(&self) -> CanonStateNotifications<N> {
513 self.inner.canon_state_notification_sender.subscribe()
514 }
515
516 pub fn subscribe_safe_block(&self) -> watch::Receiver<Option<SealedHeader<N::BlockHeader>>> {
518 self.inner.chain_info_tracker.subscribe_safe_block()
519 }
520
521 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 pub fn subscribe_persisted_block(&self) -> watch::Receiver<Option<BlockNumHash>> {
530 self.inner.chain_info_tracker.subscribe_persisted_block()
531 }
532
533 pub fn notify_canon_state(&self, event: CanonStateNotification<N>) {
535 self.inner.canon_state_notification_sender.send(event).ok();
536 }
537
538 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 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 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 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#[derive(Debug, Clone)]
594pub struct BlockState<N: NodePrimitives = EthPrimitives> {
595 block: ExecutedBlock<N>,
597 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 pub const fn new(block: ExecutedBlock<N>) -> Self {
610 Self { block, parent: None }
611 }
612
613 pub const fn with_parent(block: ExecutedBlock<N>, parent: Option<Arc<Self>>) -> Self {
615 Self { block, parent }
616 }
617
618 pub fn anchor(&self) -> BlockNumHash {
620 let mut current = self;
621 while let Some(parent) = ¤t.parent {
622 current = parent;
623 }
624 current.block.recovered_block().parent_num_hash()
625 }
626
627 pub fn block(&self) -> ExecutedBlock<N> {
629 self.block.clone()
630 }
631
632 pub const fn block_ref(&self) -> &ExecutedBlock<N> {
634 &self.block
635 }
636
637 pub fn hash(&self) -> B256 {
639 self.block.recovered_block().hash()
640 }
641
642 pub fn number(&self) -> u64 {
644 self.block.recovered_block().number()
645 }
646
647 pub fn state_root(&self) -> B256 {
650 self.block.recovered_block().state_root()
651 }
652
653 pub fn receipts(&self) -> &Vec<N::Receipt> {
655 &self.block.execution_outcome().receipts
656 }
657
658 pub fn executed_block_receipts(&self) -> Vec<N::Receipt> {
665 self.receipts().clone()
666 }
667
668 pub fn executed_block_receipts_ref(&self) -> &[N::Receipt] {
673 self.receipts()
674 }
675
676 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 pub fn chain(&self) -> impl Iterator<Item = &Self> {
690 std::iter::successors(Some(self), |state| state.parent.as_deref())
691 }
692
693 pub fn append_parent_chain<'a>(&'a self, chain: &mut Vec<&'a Self>) {
700 chain.extend(self.parent_state_chain());
701 }
702
703 pub fn iter(self: Arc<Self>) -> impl Iterator<Item = Arc<Self>> {
707 std::iter::successors(Some(self), |state| state.parent.clone())
708 }
709
710 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 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 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 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 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#[derive(Clone, Debug)]
753pub struct ExecutedBlock<N: NodePrimitives = EthPrimitives> {
754 pub recovered_block: Arc<RecoveredBlock<N::Block>>,
756 pub execution_output: Arc<BlockExecutionOutput<N::Receipt>>,
758 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 self.recovered_block == other.recovered_block &&
787 self.execution_output == other.execution_output
788 }
789}
790
791impl<N: NodePrimitives> ExecutedBlock<N> {
792 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 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 #[inline]
828 pub fn sealed_block(&self) -> &SealedBlock<N::Block> {
829 self.recovered_block.sealed_block()
830 }
831
832 #[inline]
834 pub fn recovered_block(&self) -> &RecoveredBlock<N::Block> {
835 &self.recovered_block
836 }
837
838 #[inline]
840 pub fn execution_outcome(&self) -> &BlockExecutionOutput<N::Receipt> {
841 &self.execution_output
842 }
843
844 #[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 #[inline]
861 pub fn trie_data_handle(&self) -> DeferredTrieData {
862 self.trie_data.clone()
863 }
864
865 #[inline]
869 pub fn hashed_state(&self) -> Arc<HashedPostStateSorted> {
870 self.trie_data().hashed_state
871 }
872
873 #[inline]
877 pub fn trie_updates(&self) -> Arc<TrieUpdatesSorted> {
878 self.trie_data().trie_updates
879 }
880
881 #[inline]
885 pub fn trie_input(&self) -> Option<Arc<TrieInputSorted>> {
886 self.trie_data().trie_input().cloned()
887 }
888
889 #[inline]
891 pub fn anchor_hash(&self) -> Option<B256> {
892 self.trie_data().anchor_hash()
893 }
894
895 #[inline]
897 pub fn block_number(&self) -> BlockNumber {
898 self.recovered_block.header().number()
899 }
900}
901
902#[derive(Debug)]
904pub enum NewCanonicalChain<N: NodePrimitives = EthPrimitives> {
905 Commit {
907 new: Vec<ExecutedBlock<N>>,
909 },
910 Reorg {
913 new: Vec<ExecutedBlock<N>>,
915 old: Vec<ExecutedBlock<N>>,
917 },
918}
919
920impl<N: NodePrimitives<SignedTx: SignedTransaction>> NewCanonicalChain<N> {
921 pub const fn new_block_count(&self) -> usize {
923 match self {
924 Self::Commit { new } | Self::Reorg { new, .. } => new.len(),
925 }
926 }
927
928 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 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 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 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 let block1 = test_block_builder.get_executed_block_with_number(0, B256::random());
1329
1330 let block2 =
1332 test_block_builder.get_executed_block_with_number(1, block1.recovered_block().hash());
1333
1334 let chain = NewCanonicalChain::Commit { new: vec![block1.clone(), block2.clone()] };
1336 state.update_chain(chain);
1337
1338 assert!(state.pending_state().is_none());
1340
1341 state.set_pending_block(block2.clone());
1343
1344 assert_eq!(
1346 state.pending_state().unwrap(),
1347 BlockState::with_parent(block2.clone(), Some(Arc::new(BlockState::new(block1))))
1348 );
1349
1350 assert_eq!(state.pending_block().unwrap(), block2.recovered_block().sealed_block().clone());
1352
1353 assert_eq!(
1355 state.pending_block_num_hash().unwrap(),
1356 BlockNumHash { number: 1, hash: block2.recovered_block().hash() }
1357 );
1358
1359 assert_eq!(state.pending_header().unwrap(), block2.recovered_block().header().clone());
1361
1362 assert_eq!(
1364 state.pending_sealed_header().unwrap(),
1365 block2.recovered_block().clone_sealed_header()
1366 );
1367
1368 assert_eq!(state.pending_recovered_block().unwrap(), block2.recovered_block().clone());
1370
1371 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 #[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 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 let chain_commit = NewCanonicalChain::Commit { new: vec![block0.clone(), block1.clone()] };
1567
1568 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 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 let chain_reorg = NewCanonicalChain::Reorg {
1596 new: vec![block1a.clone(), block2a.clone()],
1597 old: vec![block1.clone(), block2.clone()],
1598 };
1599
1600 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 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 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}