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