reth_provider/providers/state/
overlay.rs

1use alloy_primitives::B256;
2use reth_db_api::DatabaseError;
3use reth_storage_api::DBProvider;
4use reth_trie::{
5    hashed_cursor::{HashedCursorFactory, HashedPostStateCursorFactory},
6    trie_cursor::{InMemoryTrieCursorFactory, TrieCursorFactory},
7    updates::TrieUpdatesSorted,
8    HashedPostStateSorted,
9};
10use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory};
11use std::sync::Arc;
12
13/// State provider with in-memory overlay from trie updates and hashed post state.
14///
15/// This provider uses in-memory trie updates and hashed post state as an overlay
16/// on top of a database provider, implementing [`TrieCursorFactory`] and [`HashedCursorFactory`]
17/// using the in-memory overlay factories.
18#[derive(Debug, Clone)]
19pub struct OverlayStateProvider<Provider: DBProvider> {
20    /// The in-memory trie cursor factory that wraps the database cursor factory.
21    trie_cursor_factory:
22        InMemoryTrieCursorFactory<DatabaseTrieCursorFactory<Provider::Tx>, Arc<TrieUpdatesSorted>>,
23    /// The hashed cursor factory that wraps the database cursor factory.
24    hashed_cursor_factory: HashedPostStateCursorFactory<
25        DatabaseHashedCursorFactory<Provider::Tx>,
26        Arc<HashedPostStateSorted>,
27    >,
28}
29
30impl<Provider> OverlayStateProvider<Provider>
31where
32    Provider: DBProvider + Clone,
33{
34    /// Create new overlay state provider. The `Provider` must be cloneable, which generally means
35    /// it should be wrapped in an `Arc`.
36    pub fn new(
37        provider: Provider,
38        trie_updates: Arc<TrieUpdatesSorted>,
39        hashed_post_state: Arc<HashedPostStateSorted>,
40    ) -> Self {
41        // Create the trie cursor factory
42        let db_trie_cursor_factory = DatabaseTrieCursorFactory::new(provider.clone().into_tx());
43        let trie_cursor_factory =
44            InMemoryTrieCursorFactory::new(db_trie_cursor_factory, trie_updates);
45
46        // Create the hashed cursor factory
47        let db_hashed_cursor_factory = DatabaseHashedCursorFactory::new(provider.into_tx());
48        let hashed_cursor_factory =
49            HashedPostStateCursorFactory::new(db_hashed_cursor_factory, hashed_post_state);
50
51        Self { trie_cursor_factory, hashed_cursor_factory }
52    }
53}
54
55impl<Provider> TrieCursorFactory for OverlayStateProvider<Provider>
56where
57    Provider: DBProvider + Clone,
58    InMemoryTrieCursorFactory<DatabaseTrieCursorFactory<Provider::Tx>, Arc<TrieUpdatesSorted>>:
59        TrieCursorFactory,
60{
61    type AccountTrieCursor = <InMemoryTrieCursorFactory<
62        DatabaseTrieCursorFactory<Provider::Tx>,
63        Arc<TrieUpdatesSorted>,
64    > as TrieCursorFactory>::AccountTrieCursor;
65
66    type StorageTrieCursor = <InMemoryTrieCursorFactory<
67        DatabaseTrieCursorFactory<Provider::Tx>,
68        Arc<TrieUpdatesSorted>,
69    > as TrieCursorFactory>::StorageTrieCursor;
70
71    fn account_trie_cursor(&self) -> Result<Self::AccountTrieCursor, DatabaseError> {
72        self.trie_cursor_factory.account_trie_cursor()
73    }
74
75    fn storage_trie_cursor(
76        &self,
77        hashed_address: B256,
78    ) -> Result<Self::StorageTrieCursor, DatabaseError> {
79        self.trie_cursor_factory.storage_trie_cursor(hashed_address)
80    }
81}
82
83impl<Provider> HashedCursorFactory for OverlayStateProvider<Provider>
84where
85    Provider: DBProvider + Clone,
86    HashedPostStateCursorFactory<
87        DatabaseHashedCursorFactory<Provider::Tx>,
88        Arc<HashedPostStateSorted>,
89    >: HashedCursorFactory,
90{
91    type AccountCursor = <HashedPostStateCursorFactory<
92        DatabaseHashedCursorFactory<Provider::Tx>,
93        Arc<HashedPostStateSorted>,
94    > as HashedCursorFactory>::AccountCursor;
95
96    type StorageCursor = <HashedPostStateCursorFactory<
97        DatabaseHashedCursorFactory<Provider::Tx>,
98        Arc<HashedPostStateSorted>,
99    > as HashedCursorFactory>::StorageCursor;
100
101    fn hashed_account_cursor(&self) -> Result<Self::AccountCursor, DatabaseError> {
102        self.hashed_cursor_factory.hashed_account_cursor()
103    }
104
105    fn hashed_storage_cursor(
106        &self,
107        hashed_address: B256,
108    ) -> Result<Self::StorageCursor, DatabaseError> {
109        self.hashed_cursor_factory.hashed_storage_cursor(hashed_address)
110    }
111}