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