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 = DatabaseHashedAccountCursor<<TX as DbTx>::Cursor<tables::HashedAccounts>>;
24 type StorageCursor =
25 DatabaseHashedStorageCursor<<TX as DbTx>::DupCursor<tables::HashedStorages>>;
26
27 fn hashed_account_cursor(&self) -> Result<Self::AccountCursor, DatabaseError> {
28 Ok(DatabaseHashedAccountCursor(self.0.cursor_read::<tables::HashedAccounts>()?))
29 }
30
31 fn hashed_storage_cursor(
32 &self,
33 hashed_address: B256,
34 ) -> Result<Self::StorageCursor, DatabaseError> {
35 Ok(DatabaseHashedStorageCursor::new(
36 self.0.cursor_dup_read::<tables::HashedStorages>()?,
37 hashed_address,
38 ))
39 }
40}
41
42#[derive(Debug)]
45pub struct DatabaseHashedAccountCursor<C>(C);
46
47impl<C> DatabaseHashedAccountCursor<C> {
48 pub const fn new(cursor: C) -> Self {
50 Self(cursor)
51 }
52}
53
54impl<C> HashedCursor for DatabaseHashedAccountCursor<C>
55where
56 C: DbCursorRO<tables::HashedAccounts>,
57{
58 type Value = Account;
59
60 fn seek(&mut self, key: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
61 self.0.seek(key)
62 }
63
64 fn next(&mut self) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
65 self.0.next()
66 }
67}
68
69#[derive(Debug)]
73pub struct DatabaseHashedStorageCursor<C> {
74 cursor: C,
76 hashed_address: B256,
78}
79
80impl<C> DatabaseHashedStorageCursor<C> {
81 pub const fn new(cursor: C, hashed_address: B256) -> Self {
83 Self { cursor, hashed_address }
84 }
85}
86
87impl<C> HashedCursor for DatabaseHashedStorageCursor<C>
88where
89 C: DbCursorRO<tables::HashedStorages> + DbDupCursorRO<tables::HashedStorages>,
90{
91 type Value = U256;
92
93 fn seek(&mut self, subkey: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
94 Ok(self.cursor.seek_by_key_subkey(self.hashed_address, subkey)?.map(|e| (e.key, e.value)))
95 }
96
97 fn next(&mut self) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
98 Ok(self.cursor.next_dup_val()?.map(|e| (e.key, e.value)))
99 }
100}
101
102impl<C> HashedStorageCursor for DatabaseHashedStorageCursor<C>
103where
104 C: DbCursorRO<tables::HashedStorages> + DbDupCursorRO<tables::HashedStorages>,
105{
106 fn is_storage_empty(&mut self) -> Result<bool, DatabaseError> {
107 Ok(self.cursor.seek_exact(self.hashed_address)?.is_none())
108 }
109}