reth_trie_db/
hashed_cursor.rs1use alloy_primitives::{B256, U256};
2use reth_db_api::{
3 cursor::{DbCursorRO, DbDupCursorRO},
4 tables,
5 transaction::DbTx,
6 DatabaseError,
7};
8use reth_primitives_traits::Account;
9use reth_trie::hashed_cursor::{HashedCursor, HashedCursorFactory, HashedStorageCursor};
10
11#[derive(Debug, Clone)]
13pub struct DatabaseHashedCursorFactory<T>(T);
14
15impl<T> DatabaseHashedCursorFactory<T> {
16 pub const fn new(tx: T) -> Self {
18 Self(tx)
19 }
20}
21
22impl<TX: DbTx> HashedCursorFactory for DatabaseHashedCursorFactory<&TX> {
23 type AccountCursor<'a>
24 = DatabaseHashedAccountCursor<<TX as DbTx>::Cursor<tables::HashedAccounts>>
25 where
26 Self: 'a;
27 type StorageCursor<'a>
28 = DatabaseHashedStorageCursor<<TX as DbTx>::DupCursor<tables::HashedStorages>>
29 where
30 Self: 'a;
31
32 fn hashed_account_cursor(&self) -> Result<Self::AccountCursor<'_>, DatabaseError> {
33 Ok(DatabaseHashedAccountCursor(self.0.cursor_read::<tables::HashedAccounts>()?))
34 }
35
36 fn hashed_storage_cursor(
37 &self,
38 hashed_address: B256,
39 ) -> Result<Self::StorageCursor<'_>, DatabaseError> {
40 Ok(DatabaseHashedStorageCursor::new(
41 self.0.cursor_dup_read::<tables::HashedStorages>()?,
42 hashed_address,
43 ))
44 }
45}
46
47#[derive(Debug)]
50pub struct DatabaseHashedAccountCursor<C>(C);
51
52impl<C> DatabaseHashedAccountCursor<C> {
53 pub const fn new(cursor: C) -> Self {
55 Self(cursor)
56 }
57}
58
59impl<C> HashedCursor for DatabaseHashedAccountCursor<C>
60where
61 C: DbCursorRO<tables::HashedAccounts>,
62{
63 type Value = Account;
64
65 fn seek(&mut self, key: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
66 self.0.seek(key)
67 }
68
69 fn next(&mut self) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
70 self.0.next()
71 }
72}
73
74#[derive(Debug)]
78pub struct DatabaseHashedStorageCursor<C> {
79 cursor: C,
81 hashed_address: B256,
83}
84
85impl<C> DatabaseHashedStorageCursor<C> {
86 pub const fn new(cursor: C, hashed_address: B256) -> Self {
88 Self { cursor, hashed_address }
89 }
90}
91
92impl<C> HashedCursor for DatabaseHashedStorageCursor<C>
93where
94 C: DbCursorRO<tables::HashedStorages> + DbDupCursorRO<tables::HashedStorages>,
95{
96 type Value = U256;
97
98 fn seek(&mut self, subkey: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
99 Ok(self.cursor.seek_by_key_subkey(self.hashed_address, subkey)?.map(|e| (e.key, e.value)))
100 }
101
102 fn next(&mut self) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
103 Ok(self.cursor.next_dup_val()?.map(|e| (e.key, e.value)))
104 }
105}
106
107impl<C> HashedStorageCursor for DatabaseHashedStorageCursor<C>
108where
109 C: DbCursorRO<tables::HashedStorages> + DbDupCursorRO<tables::HashedStorages>,
110{
111 fn is_storage_empty(&mut self) -> Result<bool, DatabaseError> {
112 Ok(self.cursor.seek_exact(self.hashed_address)?.is_none())
113 }
114}