1use crate::{
4 CanonStateNotification, CanonStateNotificationSender, CanonStateNotifications,
5 ChainInfoTracker, MemoryOverlayStateProvider,
6};
7use alloy_consensus::{transaction::TransactionMeta, BlockHeader};
8use alloy_eips::{BlockHashOrNumber, BlockNumHash};
9use alloy_primitives::{map::HashMap, BlockNumber, TxHash, B256};
10use parking_lot::RwLock;
11use reth_chainspec::ChainInfo;
12use reth_ethereum_primitives::EthPrimitives;
13use reth_execution_types::{Chain, ExecutionOutcome};
14use reth_metrics::{metrics::Gauge, Metrics};
15use reth_primitives_traits::{
16 BlockBody as _, IndexedTx, NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader,
17 SignedTransaction,
18};
19use reth_storage_api::StateProviderBox;
20use reth_trie::{updates::TrieUpdates, HashedPostState};
21use std::{collections::BTreeMap, sync::Arc, time::Instant};
22use tokio::sync::{broadcast, watch};
23
24const CANON_STATE_NOTIFICATION_CHANNEL_SIZE: usize = 256;
26
27#[derive(Metrics)]
29#[metrics(scope = "blockchain_tree.in_mem_state")]
30pub(crate) struct InMemoryStateMetrics {
31 pub(crate) earliest_block: Gauge,
33 pub(crate) latest_block: Gauge,
35 pub(crate) num_blocks: Gauge,
37}
38
39#[derive(Debug, Default)]
55pub(crate) struct InMemoryState<N: NodePrimitives = EthPrimitives> {
56 blocks: RwLock<HashMap<B256, Arc<BlockState<N>>>>,
58 numbers: RwLock<BTreeMap<u64, B256>>,
60 pending: watch::Sender<Option<BlockState<N>>>,
62 metrics: InMemoryStateMetrics,
64}
65
66impl<N: NodePrimitives> InMemoryState<N> {
67 pub(crate) fn new(
68 blocks: HashMap<B256, Arc<BlockState<N>>>,
69 numbers: BTreeMap<u64, B256>,
70 pending: Option<BlockState<N>>,
71 ) -> Self {
72 let (pending, _) = watch::channel(pending);
73 let this = Self {
74 blocks: RwLock::new(blocks),
75 numbers: RwLock::new(numbers),
76 pending,
77 metrics: Default::default(),
78 };
79 this.update_metrics();
80 this
81 }
82
83 pub(crate) fn update_metrics(&self) {
89 let numbers = self.numbers.read();
90 if let Some((earliest_block_number, _)) = numbers.first_key_value() {
91 self.metrics.earliest_block.set(*earliest_block_number as f64);
92 }
93 if let Some((latest_block_number, _)) = numbers.last_key_value() {
94 self.metrics.latest_block.set(*latest_block_number as f64);
95 }
96 self.metrics.num_blocks.set(numbers.len() as f64);
97 }
98
99 pub(crate) fn state_by_hash(&self, hash: B256) -> Option<Arc<BlockState<N>>> {
101 self.blocks.read().get(&hash).cloned()
102 }
103
104 pub(crate) fn state_by_number(&self, number: u64) -> Option<Arc<BlockState<N>>> {
106 let hash = self.hash_by_number(number)?;
107 self.state_by_hash(hash)
108 }
109
110 pub(crate) fn hash_by_number(&self, number: u64) -> Option<B256> {
112 self.numbers.read().get(&number).copied()
113 }
114
115 pub(crate) fn head_state(&self) -> Option<Arc<BlockState<N>>> {
117 let hash = *self.numbers.read().last_key_value()?.1;
118 self.state_by_hash(hash)
119 }
120
121 pub(crate) fn pending_state(&self) -> Option<BlockState<N>> {
124 self.pending.borrow().clone()
125 }
126
127 #[cfg(test)]
128 fn block_count(&self) -> usize {
129 self.blocks.read().len()
130 }
131}
132
133#[derive(Debug)]
136pub(crate) struct CanonicalInMemoryStateInner<N: NodePrimitives> {
137 pub(crate) chain_info_tracker: ChainInfoTracker<N>,
140 pub(crate) in_memory_state: InMemoryState<N>,
142 pub(crate) canon_state_notification_sender: CanonStateNotificationSender<N>,
144}
145
146impl<N: NodePrimitives> CanonicalInMemoryStateInner<N> {
147 fn clear(&self) {
149 {
150 let mut numbers = self.in_memory_state.numbers.write();
152 let mut blocks = self.in_memory_state.blocks.write();
153 numbers.clear();
154 blocks.clear();
155 self.in_memory_state.pending.send_modify(|p| {
156 p.take();
157 });
158 }
159 self.in_memory_state.update_metrics();
160 }
161}
162
163type PendingBlockAndReceipts<N> =
164 (RecoveredBlock<<N as NodePrimitives>::Block>, Vec<reth_primitives_traits::ReceiptTy<N>>);
165
166#[derive(Debug, Clone)]
170pub struct CanonicalInMemoryState<N: NodePrimitives = EthPrimitives> {
171 pub(crate) inner: Arc<CanonicalInMemoryStateInner<N>>,
172}
173
174impl<N: NodePrimitives> CanonicalInMemoryState<N> {
175 pub fn new(
178 blocks: HashMap<B256, Arc<BlockState<N>>>,
179 numbers: BTreeMap<u64, B256>,
180 pending: Option<BlockState<N>>,
181 finalized: Option<SealedHeader<N::BlockHeader>>,
182 safe: Option<SealedHeader<N::BlockHeader>>,
183 ) -> Self {
184 let in_memory_state = InMemoryState::new(blocks, numbers, pending);
185 let header = in_memory_state.head_state().map_or_else(SealedHeader::default, |state| {
186 state.block_ref().recovered_block().clone_sealed_header()
187 });
188 let chain_info_tracker = ChainInfoTracker::new(header, finalized, safe);
189 let (canon_state_notification_sender, _) =
190 broadcast::channel(CANON_STATE_NOTIFICATION_CHANNEL_SIZE);
191
192 Self {
193 inner: Arc::new(CanonicalInMemoryStateInner {
194 chain_info_tracker,
195 in_memory_state,
196 canon_state_notification_sender,
197 }),
198 }
199 }
200
201 pub fn empty() -> Self {
203 Self::new(HashMap::default(), BTreeMap::new(), None, None, None)
204 }
205
206 pub fn with_head(
209 head: SealedHeader<N::BlockHeader>,
210 finalized: Option<SealedHeader<N::BlockHeader>>,
211 safe: Option<SealedHeader<N::BlockHeader>>,
212 ) -> Self {
213 let chain_info_tracker = ChainInfoTracker::new(head, finalized, safe);
214 let in_memory_state = InMemoryState::default();
215 let (canon_state_notification_sender, _) =
216 broadcast::channel(CANON_STATE_NOTIFICATION_CHANNEL_SIZE);
217 let inner = CanonicalInMemoryStateInner {
218 chain_info_tracker,
219 in_memory_state,
220 canon_state_notification_sender,
221 };
222
223 Self { inner: Arc::new(inner) }
224 }
225
226 pub fn hash_by_number(&self, number: u64) -> Option<B256> {
228 self.inner.in_memory_state.hash_by_number(number)
229 }
230
231 pub fn header_by_hash(&self, hash: B256) -> Option<SealedHeader<N::BlockHeader>> {
233 self.state_by_hash(hash)
234 .map(|block| block.block_ref().recovered_block().clone_sealed_header())
235 }
236
237 pub fn clear_state(&self) {
239 self.inner.clear()
240 }
241
242 pub fn set_pending_block(&self, pending: ExecutedBlock<N>) {
246 let parent = self.state_by_hash(pending.recovered_block().parent_hash());
248 let pending = BlockState::with_parent(pending, parent);
249 self.inner.in_memory_state.pending.send_modify(|p| {
250 p.replace(pending);
251 });
252 self.inner.in_memory_state.update_metrics();
253 }
254
255 fn update_blocks<I, R>(&self, new_blocks: I, reorged: R)
260 where
261 I: IntoIterator<Item = ExecutedBlock<N>>,
262 R: IntoIterator<Item = ExecutedBlock<N>>,
263 {
264 {
265 let mut numbers = self.inner.in_memory_state.numbers.write();
267 let mut blocks = self.inner.in_memory_state.blocks.write();
268
269 for block in reorged {
271 let hash = block.recovered_block().hash();
272 let number = block.recovered_block().number();
273 blocks.remove(&hash);
274 numbers.remove(&number);
275 }
276
277 for block in new_blocks {
279 let parent = blocks.get(&block.recovered_block().parent_hash()).cloned();
280 let block_state = BlockState::with_parent(block, parent);
281 let hash = block_state.hash();
282 let number = block_state.number();
283
284 blocks.insert(hash, Arc::new(block_state));
286 numbers.insert(number, hash);
287 }
288
289 self.inner.in_memory_state.pending.send_modify(|p| {
291 p.take();
292 });
293 }
294 self.inner.in_memory_state.update_metrics();
295 }
296
297 pub fn update_chain(&self, new_chain: NewCanonicalChain<N>) {
299 match new_chain {
300 NewCanonicalChain::Commit { new } => {
301 self.update_blocks(new, vec![]);
302 }
303 NewCanonicalChain::Reorg { new, old } => {
304 self.update_blocks(new, old);
305 }
306 }
307 }
308
309 pub fn remove_persisted_blocks(&self, persisted_num_hash: BlockNumHash) {
314 {
319 if self.inner.in_memory_state.blocks.read().get(&persisted_num_hash.hash).is_none() {
320 return
322 }
323 }
324
325 {
326 let mut numbers = self.inner.in_memory_state.numbers.write();
328 let mut blocks = self.inner.in_memory_state.blocks.write();
329
330 let BlockNumHash { number: persisted_height, hash: _ } = persisted_num_hash;
331
332 numbers.clear();
334
335 let mut old_blocks = blocks
338 .drain()
339 .filter(|(_, b)| b.block_ref().recovered_block().number() > persisted_height)
340 .map(|(_, b)| b.block.clone())
341 .collect::<Vec<_>>();
342
343 old_blocks.sort_unstable_by_key(|block| block.recovered_block().number());
345
346 for block in old_blocks {
348 let parent = blocks.get(&block.recovered_block().parent_hash()).cloned();
349 let block_state = BlockState::with_parent(block, parent);
350 let hash = block_state.hash();
351 let number = block_state.number();
352
353 blocks.insert(hash, Arc::new(block_state));
355 numbers.insert(number, hash);
356 }
357
358 self.inner.in_memory_state.pending.send_modify(|p| {
360 if let Some(p) = p.as_mut() {
361 p.parent = blocks.get(&p.block_ref().recovered_block().parent_hash()).cloned();
362 }
363 });
364 }
365 self.inner.in_memory_state.update_metrics();
366 }
367
368 pub fn state_by_hash(&self, hash: B256) -> Option<Arc<BlockState<N>>> {
370 self.inner.in_memory_state.state_by_hash(hash)
371 }
372
373 pub fn state_by_number(&self, number: u64) -> Option<Arc<BlockState<N>>> {
375 self.inner.in_memory_state.state_by_number(number)
376 }
377
378 pub fn head_state(&self) -> Option<Arc<BlockState<N>>> {
380 self.inner.in_memory_state.head_state()
381 }
382
383 pub fn pending_state(&self) -> Option<BlockState<N>> {
385 self.inner.in_memory_state.pending_state()
386 }
387
388 pub fn pending_block_num_hash(&self) -> Option<BlockNumHash> {
390 self.inner
391 .in_memory_state
392 .pending_state()
393 .map(|state| BlockNumHash { number: state.number(), hash: state.hash() })
394 }
395
396 pub fn chain_info(&self) -> ChainInfo {
398 self.inner.chain_info_tracker.chain_info()
399 }
400
401 pub fn get_canonical_block_number(&self) -> u64 {
403 self.inner.chain_info_tracker.get_canonical_block_number()
404 }
405
406 pub fn get_safe_num_hash(&self) -> Option<BlockNumHash> {
408 self.inner.chain_info_tracker.get_safe_num_hash()
409 }
410
411 pub fn get_finalized_num_hash(&self) -> Option<BlockNumHash> {
413 self.inner.chain_info_tracker.get_finalized_num_hash()
414 }
415
416 pub fn on_forkchoice_update_received(&self) {
418 self.inner.chain_info_tracker.on_forkchoice_update_received();
419 }
420
421 pub fn last_received_update_timestamp(&self) -> Option<Instant> {
423 self.inner.chain_info_tracker.last_forkchoice_update_received_at()
424 }
425
426 pub fn set_canonical_head(&self, header: SealedHeader<N::BlockHeader>) {
428 self.inner.chain_info_tracker.set_canonical_head(header);
429 }
430
431 pub fn set_safe(&self, header: SealedHeader<N::BlockHeader>) {
433 self.inner.chain_info_tracker.set_safe(header);
434 }
435
436 pub fn set_finalized(&self, header: SealedHeader<N::BlockHeader>) {
438 self.inner.chain_info_tracker.set_finalized(header);
439 }
440
441 pub fn get_canonical_head(&self) -> SealedHeader<N::BlockHeader> {
443 self.inner.chain_info_tracker.get_canonical_head()
444 }
445
446 pub fn get_finalized_header(&self) -> Option<SealedHeader<N::BlockHeader>> {
448 self.inner.chain_info_tracker.get_finalized_header()
449 }
450
451 pub fn get_safe_header(&self) -> Option<SealedHeader<N::BlockHeader>> {
453 self.inner.chain_info_tracker.get_safe_header()
454 }
455
456 pub fn pending_sealed_header(&self) -> Option<SealedHeader<N::BlockHeader>> {
458 self.pending_state().map(|h| h.block_ref().recovered_block().clone_sealed_header())
459 }
460
461 pub fn pending_header(&self) -> Option<N::BlockHeader> {
463 self.pending_sealed_header().map(|sealed_header| sealed_header.unseal())
464 }
465
466 pub fn pending_block(&self) -> Option<SealedBlock<N::Block>> {
468 self.pending_state()
469 .map(|block_state| block_state.block_ref().recovered_block().sealed_block().clone())
470 }
471
472 pub fn pending_recovered_block(&self) -> Option<RecoveredBlock<N::Block>>
474 where
475 N::SignedTx: SignedTransaction,
476 {
477 self.pending_state().map(|block_state| block_state.block_ref().recovered_block().clone())
478 }
479
480 pub fn pending_block_and_receipts(&self) -> Option<PendingBlockAndReceipts<N>> {
483 self.pending_state().map(|block_state| {
484 (
485 block_state.block_ref().recovered_block().clone(),
486 block_state.executed_block_receipts(),
487 )
488 })
489 }
490
491 pub fn subscribe_canon_state(&self) -> CanonStateNotifications<N> {
493 self.inner.canon_state_notification_sender.subscribe()
494 }
495
496 pub fn subscribe_safe_block(&self) -> watch::Receiver<Option<SealedHeader<N::BlockHeader>>> {
498 self.inner.chain_info_tracker.subscribe_safe_block()
499 }
500
501 pub fn subscribe_finalized_block(
503 &self,
504 ) -> watch::Receiver<Option<SealedHeader<N::BlockHeader>>> {
505 self.inner.chain_info_tracker.subscribe_finalized_block()
506 }
507
508 pub fn notify_canon_state(&self, event: CanonStateNotification<N>) {
510 self.inner.canon_state_notification_sender.send(event).ok();
511 }
512
513 pub fn state_provider(
518 &self,
519 hash: B256,
520 historical: StateProviderBox,
521 ) -> MemoryOverlayStateProvider<N> {
522 let in_memory = if let Some(state) = self.state_by_hash(hash) {
523 state.chain().map(|block_state| block_state.block()).collect()
524 } else {
525 Vec::new()
526 };
527
528 MemoryOverlayStateProvider::new(historical, in_memory)
529 }
530
531 pub fn canonical_chain(&self) -> impl Iterator<Item = Arc<BlockState<N>>> {
536 self.inner.in_memory_state.head_state().into_iter().flat_map(|head| head.iter())
537 }
538
539 pub fn transaction_by_hash(&self, hash: TxHash) -> Option<N::SignedTx> {
541 for block_state in self.canonical_chain() {
542 if let Some(tx) =
543 block_state.block_ref().recovered_block().body().transaction_by_hash(&hash)
544 {
545 return Some(tx.clone())
546 }
547 }
548 None
549 }
550
551 pub fn transaction_by_hash_with_meta(
554 &self,
555 tx_hash: TxHash,
556 ) -> Option<(N::SignedTx, TransactionMeta)> {
557 for block_state in self.canonical_chain() {
558 if let Some(indexed) = block_state.find_indexed(tx_hash) {
559 return Some((indexed.tx().clone(), indexed.meta()));
560 }
561 }
562 None
563 }
564}
565
566#[derive(Debug, PartialEq, Eq, Clone)]
569pub struct BlockState<N: NodePrimitives = EthPrimitives> {
570 block: ExecutedBlock<N>,
572 parent: Option<Arc<Self>>,
574}
575
576impl<N: NodePrimitives> BlockState<N> {
577 pub const fn new(block: ExecutedBlock<N>) -> Self {
579 Self { block, parent: None }
580 }
581
582 pub const fn with_parent(block: ExecutedBlock<N>, parent: Option<Arc<Self>>) -> Self {
584 Self { block, parent }
585 }
586
587 pub fn anchor(&self) -> BlockNumHash {
589 let mut current = self;
590 while let Some(parent) = ¤t.parent {
591 current = parent;
592 }
593 current.block.recovered_block().parent_num_hash()
594 }
595
596 pub fn block(&self) -> ExecutedBlock<N> {
598 self.block.clone()
599 }
600
601 pub const fn block_ref(&self) -> &ExecutedBlock<N> {
603 &self.block
604 }
605
606 pub fn hash(&self) -> B256 {
608 self.block.recovered_block().hash()
609 }
610
611 pub fn number(&self) -> u64 {
613 self.block.recovered_block().number()
614 }
615
616 pub fn state_root(&self) -> B256 {
619 self.block.recovered_block().state_root()
620 }
621
622 pub fn receipts(&self) -> &Vec<Vec<N::Receipt>> {
624 &self.block.execution_outcome().receipts
625 }
626
627 pub fn executed_block_receipts(&self) -> Vec<N::Receipt> {
632 let receipts = self.receipts();
633
634 debug_assert!(
635 receipts.len() <= 1,
636 "Expected at most one block's worth of receipts, found {}",
637 receipts.len()
638 );
639
640 receipts.first().cloned().unwrap_or_default()
641 }
642
643 pub fn parent_state_chain(&self) -> Vec<&Self> {
650 let mut parents = Vec::new();
651 let mut current = self.parent.as_deref();
652
653 while let Some(parent) = current {
654 parents.push(parent);
655 current = parent.parent.as_deref();
656 }
657
658 parents
659 }
660
661 pub fn chain(&self) -> impl Iterator<Item = &Self> {
665 std::iter::successors(Some(self), |state| state.parent.as_deref())
666 }
667
668 pub fn append_parent_chain<'a>(&'a self, chain: &mut Vec<&'a Self>) {
670 chain.extend(self.parent_state_chain());
671 }
672
673 pub fn iter(self: Arc<Self>) -> impl Iterator<Item = Arc<Self>> {
677 std::iter::successors(Some(self), |state| state.parent.clone())
678 }
679
680 pub fn state_provider(&self, historical: StateProviderBox) -> MemoryOverlayStateProvider<N> {
685 let in_memory = self.chain().map(|block_state| block_state.block()).collect();
686
687 MemoryOverlayStateProvider::new(historical, in_memory)
688 }
689
690 pub fn block_on_chain(&self, hash_or_num: BlockHashOrNumber) -> Option<&Self> {
692 self.chain().find(|block| match hash_or_num {
693 BlockHashOrNumber::Hash(hash) => block.hash() == hash,
694 BlockHashOrNumber::Number(number) => block.number() == number,
695 })
696 }
697
698 pub fn transaction_on_chain(&self, hash: TxHash) -> Option<N::SignedTx> {
700 self.chain().find_map(|block_state| {
701 block_state.block_ref().recovered_block().body().transaction_by_hash(&hash).cloned()
702 })
703 }
704
705 pub fn transaction_meta_on_chain(
707 &self,
708 tx_hash: TxHash,
709 ) -> Option<(N::SignedTx, TransactionMeta)> {
710 self.chain().find_map(|block_state| {
711 block_state.find_indexed(tx_hash).map(|indexed| (indexed.tx().clone(), indexed.meta()))
712 })
713 }
714
715 pub fn find_indexed(&self, tx_hash: TxHash) -> Option<IndexedTx<'_, N::Block>> {
717 self.block_ref().recovered_block().find_indexed(tx_hash)
718 }
719}
720
721#[derive(Clone, Debug, PartialEq, Eq)]
723pub struct ExecutedBlock<N: NodePrimitives = EthPrimitives> {
724 pub recovered_block: Arc<RecoveredBlock<N::Block>>,
726 pub execution_output: Arc<ExecutionOutcome<N::Receipt>>,
728 pub hashed_state: Arc<HashedPostState>,
730 pub trie_updates: Arc<TrieUpdates>,
732}
733
734impl<N: NodePrimitives> Default for ExecutedBlock<N> {
735 fn default() -> Self {
736 Self {
737 recovered_block: Default::default(),
738 execution_output: Default::default(),
739 hashed_state: Default::default(),
740 trie_updates: Default::default(),
741 }
742 }
743}
744
745impl<N: NodePrimitives> ExecutedBlock<N> {
746 #[inline]
748 pub fn sealed_block(&self) -> &SealedBlock<N::Block> {
749 self.recovered_block.sealed_block()
750 }
751
752 #[inline]
754 pub fn recovered_block(&self) -> &RecoveredBlock<N::Block> {
755 &self.recovered_block
756 }
757
758 #[inline]
760 pub fn execution_outcome(&self) -> &ExecutionOutcome<N::Receipt> {
761 &self.execution_output
762 }
763
764 #[inline]
766 pub fn hashed_state(&self) -> &HashedPostState {
767 &self.hashed_state
768 }
769
770 #[inline]
772 pub fn trie_updates(&self) -> &TrieUpdates {
773 &self.trie_updates
774 }
775
776 #[inline]
778 pub fn block_number(&self) -> BlockNumber {
779 self.recovered_block.header().number()
780 }
781}
782
783#[derive(Debug)]
785pub enum NewCanonicalChain<N: NodePrimitives = EthPrimitives> {
786 Commit {
788 new: Vec<ExecutedBlock<N>>,
790 },
791 Reorg {
794 new: Vec<ExecutedBlock<N>>,
796 old: Vec<ExecutedBlock<N>>,
798 },
799}
800
801impl<N: NodePrimitives<SignedTx: SignedTransaction>> NewCanonicalChain<N> {
802 pub const fn new_block_count(&self) -> usize {
804 match self {
805 Self::Commit { new } | Self::Reorg { new, .. } => new.len(),
806 }
807 }
808
809 pub const fn reorged_block_count(&self) -> usize {
811 match self {
812 Self::Commit { .. } => 0,
813 Self::Reorg { old, .. } => old.len(),
814 }
815 }
816
817 pub fn to_chain_notification(&self) -> CanonStateNotification<N> {
819 match self {
820 Self::Commit { new } => {
821 let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| {
822 chain.append_block(
823 exec.recovered_block().clone(),
824 exec.execution_outcome().clone(),
825 );
826 chain
827 }));
828 CanonStateNotification::Commit { new }
829 }
830 Self::Reorg { new, old } => {
831 let new = Arc::new(new.iter().fold(Chain::default(), |mut chain, exec| {
832 chain.append_block(
833 exec.recovered_block().clone(),
834 exec.execution_outcome().clone(),
835 );
836 chain
837 }));
838 let old = Arc::new(old.iter().fold(Chain::default(), |mut chain, exec| {
839 chain.append_block(
840 exec.recovered_block().clone(),
841 exec.execution_outcome().clone(),
842 );
843 chain
844 }));
845 CanonStateNotification::Reorg { new, old }
846 }
847 }
848 }
849
850 pub fn tip(&self) -> &SealedBlock<N::Block> {
855 match self {
856 Self::Commit { new } | Self::Reorg { new, .. } => {
857 new.last().expect("non empty blocks").recovered_block()
858 }
859 }
860 }
861}
862
863#[cfg(test)]
864mod tests {
865 use super::*;
866 use crate::test_utils::TestBlockBuilder;
867 use alloy_eips::eip7685::Requests;
868 use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, StorageValue};
869 use rand::Rng;
870 use reth_errors::ProviderResult;
871 use reth_ethereum_primitives::{EthPrimitives, Receipt};
872 use reth_primitives_traits::{Account, Bytecode};
873 use reth_storage_api::{
874 AccountReader, BlockHashReader, BytecodeReader, HashedPostStateProvider,
875 StateProofProvider, StateProvider, StateRootProvider, StorageRootProvider,
876 };
877 use reth_trie::{
878 AccountProof, HashedStorage, MultiProof, MultiProofTargets, StorageMultiProof,
879 StorageProof, TrieInput,
880 };
881
882 fn create_mock_state(
883 test_block_builder: &mut TestBlockBuilder<EthPrimitives>,
884 block_number: u64,
885 parent_hash: B256,
886 ) -> BlockState {
887 BlockState::new(
888 test_block_builder.get_executed_block_with_number(block_number, parent_hash),
889 )
890 }
891
892 fn create_mock_state_chain(
893 test_block_builder: &mut TestBlockBuilder<EthPrimitives>,
894 num_blocks: u64,
895 ) -> Vec<BlockState> {
896 let mut chain = Vec::with_capacity(num_blocks as usize);
897 let mut parent_hash = B256::random();
898 let mut parent_state: Option<BlockState> = None;
899
900 for i in 1..=num_blocks {
901 let mut state = create_mock_state(test_block_builder, i, parent_hash);
902 if let Some(parent) = parent_state {
903 state.parent = Some(Arc::new(parent));
904 }
905 parent_hash = state.hash();
906 parent_state = Some(state.clone());
907 chain.push(state);
908 }
909
910 chain
911 }
912
913 struct MockStateProvider;
914
915 impl StateProvider for MockStateProvider {
916 fn storage(
917 &self,
918 _address: Address,
919 _storage_key: StorageKey,
920 ) -> ProviderResult<Option<StorageValue>> {
921 Ok(None)
922 }
923 }
924
925 impl BytecodeReader for MockStateProvider {
926 fn bytecode_by_hash(&self, _code_hash: &B256) -> ProviderResult<Option<Bytecode>> {
927 Ok(None)
928 }
929 }
930
931 impl BlockHashReader for MockStateProvider {
932 fn block_hash(&self, _number: BlockNumber) -> ProviderResult<Option<B256>> {
933 Ok(None)
934 }
935
936 fn canonical_hashes_range(
937 &self,
938 _start: BlockNumber,
939 _end: BlockNumber,
940 ) -> ProviderResult<Vec<B256>> {
941 Ok(vec![])
942 }
943 }
944
945 impl AccountReader for MockStateProvider {
946 fn basic_account(&self, _address: &Address) -> ProviderResult<Option<Account>> {
947 Ok(None)
948 }
949 }
950
951 impl StateRootProvider for MockStateProvider {
952 fn state_root(&self, _hashed_state: HashedPostState) -> ProviderResult<B256> {
953 Ok(B256::random())
954 }
955
956 fn state_root_from_nodes(&self, _input: TrieInput) -> ProviderResult<B256> {
957 Ok(B256::random())
958 }
959
960 fn state_root_with_updates(
961 &self,
962 _hashed_state: HashedPostState,
963 ) -> ProviderResult<(B256, TrieUpdates)> {
964 Ok((B256::random(), TrieUpdates::default()))
965 }
966
967 fn state_root_from_nodes_with_updates(
968 &self,
969 _input: TrieInput,
970 ) -> ProviderResult<(B256, TrieUpdates)> {
971 Ok((B256::random(), TrieUpdates::default()))
972 }
973 }
974
975 impl HashedPostStateProvider for MockStateProvider {
976 fn hashed_post_state(&self, _bundle_state: &revm_database::BundleState) -> HashedPostState {
977 HashedPostState::default()
978 }
979 }
980
981 impl StorageRootProvider for MockStateProvider {
982 fn storage_root(
983 &self,
984 _address: Address,
985 _hashed_storage: HashedStorage,
986 ) -> ProviderResult<B256> {
987 Ok(B256::random())
988 }
989
990 fn storage_proof(
991 &self,
992 _address: Address,
993 slot: B256,
994 _hashed_storage: HashedStorage,
995 ) -> ProviderResult<StorageProof> {
996 Ok(StorageProof::new(slot))
997 }
998
999 fn storage_multiproof(
1000 &self,
1001 _address: Address,
1002 _slots: &[B256],
1003 _hashed_storage: HashedStorage,
1004 ) -> ProviderResult<StorageMultiProof> {
1005 Ok(StorageMultiProof::empty())
1006 }
1007 }
1008
1009 impl StateProofProvider for MockStateProvider {
1010 fn proof(
1011 &self,
1012 _input: TrieInput,
1013 _address: Address,
1014 _slots: &[B256],
1015 ) -> ProviderResult<AccountProof> {
1016 Ok(AccountProof::new(Address::random()))
1017 }
1018
1019 fn multiproof(
1020 &self,
1021 _input: TrieInput,
1022 _targets: MultiProofTargets,
1023 ) -> ProviderResult<MultiProof> {
1024 Ok(MultiProof::default())
1025 }
1026
1027 fn witness(
1028 &self,
1029 _input: TrieInput,
1030 _target: HashedPostState,
1031 ) -> ProviderResult<Vec<Bytes>> {
1032 Ok(Vec::default())
1033 }
1034 }
1035
1036 #[test]
1037 fn test_in_memory_state_impl_state_by_hash() {
1038 let mut state_by_hash = HashMap::default();
1039 let number = rand::rng().random::<u64>();
1040 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1041 let state = Arc::new(create_mock_state(&mut test_block_builder, number, B256::random()));
1042 state_by_hash.insert(state.hash(), state.clone());
1043
1044 let in_memory_state = InMemoryState::new(state_by_hash, BTreeMap::new(), None);
1045
1046 assert_eq!(in_memory_state.state_by_hash(state.hash()), Some(state));
1047 assert_eq!(in_memory_state.state_by_hash(B256::random()), None);
1048 }
1049
1050 #[test]
1051 fn test_in_memory_state_impl_state_by_number() {
1052 let mut state_by_hash = HashMap::default();
1053 let mut hash_by_number = BTreeMap::new();
1054
1055 let number = rand::rng().random::<u64>();
1056 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1057 let state = Arc::new(create_mock_state(&mut test_block_builder, number, B256::random()));
1058 let hash = state.hash();
1059
1060 state_by_hash.insert(hash, state.clone());
1061 hash_by_number.insert(number, hash);
1062
1063 let in_memory_state = InMemoryState::new(state_by_hash, hash_by_number, None);
1064
1065 assert_eq!(in_memory_state.state_by_number(number), Some(state));
1066 assert_eq!(in_memory_state.state_by_number(number + 1), None);
1067 }
1068
1069 #[test]
1070 fn test_in_memory_state_impl_head_state() {
1071 let mut state_by_hash = HashMap::default();
1072 let mut hash_by_number = BTreeMap::new();
1073 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1074 let state1 = Arc::new(create_mock_state(&mut test_block_builder, 1, B256::random()));
1075 let hash1 = state1.hash();
1076 let state2 = Arc::new(create_mock_state(&mut test_block_builder, 2, hash1));
1077 let hash2 = state2.hash();
1078 hash_by_number.insert(1, hash1);
1079 hash_by_number.insert(2, hash2);
1080 state_by_hash.insert(hash1, state1);
1081 state_by_hash.insert(hash2, state2);
1082
1083 let in_memory_state = InMemoryState::new(state_by_hash, hash_by_number, None);
1084 let head_state = in_memory_state.head_state().unwrap();
1085
1086 assert_eq!(head_state.hash(), hash2);
1087 assert_eq!(head_state.number(), 2);
1088 }
1089
1090 #[test]
1091 fn test_in_memory_state_impl_pending_state() {
1092 let pending_number = rand::rng().random::<u64>();
1093 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1094 let pending_state =
1095 create_mock_state(&mut test_block_builder, pending_number, B256::random());
1096 let pending_hash = pending_state.hash();
1097
1098 let in_memory_state =
1099 InMemoryState::new(HashMap::default(), BTreeMap::new(), Some(pending_state));
1100
1101 let result = in_memory_state.pending_state();
1102 assert!(result.is_some());
1103 let actual_pending_state = result.unwrap();
1104 assert_eq!(actual_pending_state.block.recovered_block().hash(), pending_hash);
1105 assert_eq!(actual_pending_state.block.recovered_block().number, pending_number);
1106 }
1107
1108 #[test]
1109 fn test_in_memory_state_impl_no_pending_state() {
1110 let in_memory_state: InMemoryState =
1111 InMemoryState::new(HashMap::default(), BTreeMap::new(), None);
1112
1113 assert_eq!(in_memory_state.pending_state(), None);
1114 }
1115
1116 #[test]
1117 fn test_state() {
1118 let number = rand::rng().random::<u64>();
1119 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1120 let block = test_block_builder.get_executed_block_with_number(number, B256::random());
1121
1122 let state = BlockState::new(block.clone());
1123
1124 assert_eq!(state.block(), block);
1125 assert_eq!(state.hash(), block.recovered_block().hash());
1126 assert_eq!(state.number(), number);
1127 assert_eq!(state.state_root(), block.recovered_block().state_root);
1128 }
1129
1130 #[test]
1131 fn test_state_receipts() {
1132 let receipts = vec![vec![Receipt::default()]];
1133 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1134 let block =
1135 test_block_builder.get_executed_block_with_receipts(receipts.clone(), B256::random());
1136
1137 let state = BlockState::new(block);
1138
1139 assert_eq!(state.receipts(), &receipts);
1140 }
1141
1142 #[test]
1143 fn test_in_memory_state_chain_update() {
1144 let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1145 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1146 let block1 = test_block_builder.get_executed_block_with_number(0, B256::random());
1147 let block2 = test_block_builder.get_executed_block_with_number(0, B256::random());
1148 let chain = NewCanonicalChain::Commit { new: vec![block1.clone()] };
1149 state.update_chain(chain);
1150 assert_eq!(
1151 state.head_state().unwrap().block_ref().recovered_block().hash(),
1152 block1.recovered_block().hash()
1153 );
1154 assert_eq!(
1155 state.state_by_number(0).unwrap().block_ref().recovered_block().hash(),
1156 block1.recovered_block().hash()
1157 );
1158
1159 let chain = NewCanonicalChain::Reorg { new: vec![block2.clone()], old: vec![block1] };
1160 state.update_chain(chain);
1161 assert_eq!(
1162 state.head_state().unwrap().block_ref().recovered_block().hash(),
1163 block2.recovered_block().hash()
1164 );
1165 assert_eq!(
1166 state.state_by_number(0).unwrap().block_ref().recovered_block().hash(),
1167 block2.recovered_block().hash()
1168 );
1169
1170 assert_eq!(state.inner.in_memory_state.block_count(), 1);
1171 }
1172
1173 #[test]
1174 fn test_in_memory_state_set_pending_block() {
1175 let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1176 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1177
1178 let block1 = test_block_builder.get_executed_block_with_number(0, B256::random());
1180
1181 let block2 =
1183 test_block_builder.get_executed_block_with_number(1, block1.recovered_block().hash());
1184
1185 let chain = NewCanonicalChain::Commit { new: vec![block1.clone(), block2.clone()] };
1187 state.update_chain(chain);
1188
1189 assert!(state.pending_state().is_none());
1191
1192 state.set_pending_block(block2.clone());
1194
1195 assert_eq!(
1197 state.pending_state().unwrap(),
1198 BlockState::with_parent(block2.clone(), Some(Arc::new(BlockState::new(block1))))
1199 );
1200
1201 assert_eq!(state.pending_block().unwrap(), block2.recovered_block().sealed_block().clone());
1203
1204 assert_eq!(
1206 state.pending_block_num_hash().unwrap(),
1207 BlockNumHash { number: 1, hash: block2.recovered_block().hash() }
1208 );
1209
1210 assert_eq!(state.pending_header().unwrap(), block2.recovered_block().header().clone());
1212
1213 assert_eq!(
1215 state.pending_sealed_header().unwrap(),
1216 block2.recovered_block().clone_sealed_header()
1217 );
1218
1219 assert_eq!(state.pending_recovered_block().unwrap(), block2.recovered_block().clone());
1221
1222 assert_eq!(
1224 state.pending_block_and_receipts().unwrap(),
1225 (block2.recovered_block().clone(), vec![])
1226 );
1227 }
1228
1229 #[test]
1230 fn test_canonical_in_memory_state_state_provider() {
1231 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1232 let block1 = test_block_builder.get_executed_block_with_number(1, B256::random());
1233 let block2 =
1234 test_block_builder.get_executed_block_with_number(2, block1.recovered_block().hash());
1235 let block3 =
1236 test_block_builder.get_executed_block_with_number(3, block2.recovered_block().hash());
1237
1238 let state1 = Arc::new(BlockState::new(block1.clone()));
1239 let state2 = Arc::new(BlockState::with_parent(block2.clone(), Some(state1.clone())));
1240 let state3 = Arc::new(BlockState::with_parent(block3.clone(), Some(state2.clone())));
1241
1242 let mut blocks = HashMap::default();
1243 blocks.insert(block1.recovered_block().hash(), state1);
1244 blocks.insert(block2.recovered_block().hash(), state2);
1245 blocks.insert(block3.recovered_block().hash(), state3);
1246
1247 let mut numbers = BTreeMap::new();
1248 numbers.insert(1, block1.recovered_block().hash());
1249 numbers.insert(2, block2.recovered_block().hash());
1250 numbers.insert(3, block3.recovered_block().hash());
1251
1252 let canonical_state = CanonicalInMemoryState::new(blocks, numbers, None, None, None);
1253
1254 let historical: StateProviderBox = Box::new(MockStateProvider);
1255
1256 let overlay_provider =
1257 canonical_state.state_provider(block3.recovered_block().hash(), historical);
1258
1259 assert_eq!(overlay_provider.in_memory.len(), 3);
1260 assert_eq!(overlay_provider.in_memory[0].recovered_block().number, 3);
1261 assert_eq!(overlay_provider.in_memory[1].recovered_block().number, 2);
1262 assert_eq!(overlay_provider.in_memory[2].recovered_block().number, 1);
1263
1264 assert_eq!(
1265 overlay_provider.in_memory[0].recovered_block().parent_hash,
1266 overlay_provider.in_memory[1].recovered_block().hash()
1267 );
1268 assert_eq!(
1269 overlay_provider.in_memory[1].recovered_block().parent_hash,
1270 overlay_provider.in_memory[2].recovered_block().hash()
1271 );
1272
1273 let unknown_hash = B256::random();
1274 let empty_overlay_provider =
1275 canonical_state.state_provider(unknown_hash, Box::new(MockStateProvider));
1276 assert_eq!(empty_overlay_provider.in_memory.len(), 0);
1277 }
1278
1279 #[test]
1280 fn test_canonical_in_memory_state_canonical_chain_empty() {
1281 let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1282 assert!(state.canonical_chain().next().is_none());
1283 }
1284
1285 #[test]
1286 fn test_canonical_in_memory_state_canonical_chain_single_block() {
1287 let block = TestBlockBuilder::eth().get_executed_block_with_number(1, B256::random());
1288 let hash = block.recovered_block().hash();
1289 let mut blocks = HashMap::default();
1290 blocks.insert(hash, Arc::new(BlockState::new(block)));
1291 let mut numbers = BTreeMap::new();
1292 numbers.insert(1, hash);
1293
1294 let state = CanonicalInMemoryState::new(blocks, numbers, None, None, None);
1295 let chain: Vec<_> = state.canonical_chain().collect();
1296
1297 assert_eq!(chain.len(), 1);
1298 assert_eq!(chain[0].number(), 1);
1299 assert_eq!(chain[0].hash(), hash);
1300 }
1301
1302 #[test]
1303 fn test_canonical_in_memory_state_canonical_chain_multiple_blocks() {
1304 let mut parent_hash = B256::random();
1305 let mut block_builder = TestBlockBuilder::eth();
1306 let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1307
1308 for i in 1..=3 {
1309 let block = block_builder.get_executed_block_with_number(i, parent_hash);
1310 let hash = block.recovered_block().hash();
1311 state.update_blocks(Some(block), None);
1312 parent_hash = hash;
1313 }
1314
1315 let chain: Vec<_> = state.canonical_chain().collect();
1316
1317 assert_eq!(chain.len(), 3);
1318 assert_eq!(chain[0].number(), 3);
1319 assert_eq!(chain[1].number(), 2);
1320 assert_eq!(chain[2].number(), 1);
1321 }
1322
1323 #[test]
1325 fn test_canonical_in_memory_state_canonical_chain_with_pending_block() {
1326 let mut parent_hash = B256::random();
1327 let mut block_builder = TestBlockBuilder::<EthPrimitives>::eth();
1328 let state: CanonicalInMemoryState = CanonicalInMemoryState::empty();
1329
1330 for i in 1..=2 {
1331 let block = block_builder.get_executed_block_with_number(i, parent_hash);
1332 let hash = block.recovered_block().hash();
1333 state.update_blocks(Some(block), None);
1334 parent_hash = hash;
1335 }
1336
1337 let pending_block = block_builder.get_executed_block_with_number(3, parent_hash);
1338 state.set_pending_block(pending_block);
1339 let chain: Vec<_> = state.canonical_chain().collect();
1340
1341 assert_eq!(chain.len(), 2);
1342 assert_eq!(chain[0].number(), 2);
1343 assert_eq!(chain[1].number(), 1);
1344 }
1345
1346 #[test]
1347 fn test_block_state_parent_blocks() {
1348 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1349 let chain = create_mock_state_chain(&mut test_block_builder, 4);
1350
1351 let parents = chain[3].parent_state_chain();
1352 assert_eq!(parents.len(), 3);
1353 assert_eq!(parents[0].block().recovered_block().number, 3);
1354 assert_eq!(parents[1].block().recovered_block().number, 2);
1355 assert_eq!(parents[2].block().recovered_block().number, 1);
1356
1357 let parents = chain[2].parent_state_chain();
1358 assert_eq!(parents.len(), 2);
1359 assert_eq!(parents[0].block().recovered_block().number, 2);
1360 assert_eq!(parents[1].block().recovered_block().number, 1);
1361
1362 let parents = chain[0].parent_state_chain();
1363 assert_eq!(parents.len(), 0);
1364 }
1365
1366 #[test]
1367 fn test_block_state_single_block_state_chain() {
1368 let single_block_number = 1;
1369 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1370 let single_block =
1371 create_mock_state(&mut test_block_builder, single_block_number, B256::random());
1372 let single_block_hash = single_block.block().recovered_block().hash();
1373
1374 let parents = single_block.parent_state_chain();
1375 assert_eq!(parents.len(), 0);
1376
1377 let block_state_chain = single_block.chain().collect::<Vec<_>>();
1378 assert_eq!(block_state_chain.len(), 1);
1379 assert_eq!(block_state_chain[0].block().recovered_block().number, single_block_number);
1380 assert_eq!(block_state_chain[0].block().recovered_block().hash(), single_block_hash);
1381 }
1382
1383 #[test]
1384 fn test_block_state_chain() {
1385 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1386 let chain = create_mock_state_chain(&mut test_block_builder, 3);
1387
1388 let block_state_chain = chain[2].chain().collect::<Vec<_>>();
1389 assert_eq!(block_state_chain.len(), 3);
1390 assert_eq!(block_state_chain[0].block().recovered_block().number, 3);
1391 assert_eq!(block_state_chain[1].block().recovered_block().number, 2);
1392 assert_eq!(block_state_chain[2].block().recovered_block().number, 1);
1393
1394 let block_state_chain = chain[1].chain().collect::<Vec<_>>();
1395 assert_eq!(block_state_chain.len(), 2);
1396 assert_eq!(block_state_chain[0].block().recovered_block().number, 2);
1397 assert_eq!(block_state_chain[1].block().recovered_block().number, 1);
1398
1399 let block_state_chain = chain[0].chain().collect::<Vec<_>>();
1400 assert_eq!(block_state_chain.len(), 1);
1401 assert_eq!(block_state_chain[0].block().recovered_block().number, 1);
1402 }
1403
1404 #[test]
1405 fn test_to_chain_notification() {
1406 let mut test_block_builder: TestBlockBuilder = TestBlockBuilder::default();
1408 let block0 = test_block_builder.get_executed_block_with_number(0, B256::random());
1409 let block1 =
1410 test_block_builder.get_executed_block_with_number(1, block0.recovered_block.hash());
1411 let block1a =
1412 test_block_builder.get_executed_block_with_number(1, block0.recovered_block.hash());
1413 let block2 =
1414 test_block_builder.get_executed_block_with_number(2, block1.recovered_block.hash());
1415 let block2a =
1416 test_block_builder.get_executed_block_with_number(2, block1.recovered_block.hash());
1417
1418 let sample_execution_outcome = ExecutionOutcome {
1419 receipts: vec![vec![], vec![]],
1420 requests: vec![Requests::default(), Requests::default()],
1421 ..Default::default()
1422 };
1423
1424 let chain_commit = NewCanonicalChain::Commit { new: vec![block0.clone(), block1.clone()] };
1426
1427 assert_eq!(
1428 chain_commit.to_chain_notification(),
1429 CanonStateNotification::Commit {
1430 new: Arc::new(Chain::new(
1431 vec![block0.recovered_block().clone(), block1.recovered_block().clone()],
1432 sample_execution_outcome.clone(),
1433 None
1434 ))
1435 }
1436 );
1437
1438 let chain_reorg = NewCanonicalChain::Reorg {
1440 new: vec![block1a.clone(), block2a.clone()],
1441 old: vec![block1.clone(), block2.clone()],
1442 };
1443
1444 assert_eq!(
1445 chain_reorg.to_chain_notification(),
1446 CanonStateNotification::Reorg {
1447 old: Arc::new(Chain::new(
1448 vec![block1.recovered_block().clone(), block2.recovered_block().clone()],
1449 sample_execution_outcome.clone(),
1450 None
1451 )),
1452 new: Arc::new(Chain::new(
1453 vec![block1a.recovered_block().clone(), block2a.recovered_block().clone()],
1454 sample_execution_outcome,
1455 None
1456 ))
1457 }
1458 );
1459 }
1460}