mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
chore: simplify HashedCursorFactory trait (#4984)
This commit is contained in:
@ -6,15 +6,15 @@ use reth_db::{
|
||||
};
|
||||
use reth_primitives::{Account, StorageEntry, B256};
|
||||
|
||||
impl<'a, 'tx, TX: DbTx<'tx>> HashedCursorFactory<'a> for TX {
|
||||
type AccountCursor = <TX as DbTxGAT<'a>>::Cursor<tables::HashedAccount> where Self: 'a;
|
||||
type StorageCursor = <TX as DbTxGAT<'a>>::DupCursor<tables::HashedStorage> where Self: 'a;
|
||||
impl<'a, 'tx, TX: DbTx<'tx>> HashedCursorFactory for &'a TX {
|
||||
type AccountCursor = <TX as DbTxGAT<'a>>::Cursor<tables::HashedAccount>;
|
||||
type StorageCursor = <TX as DbTxGAT<'a>>::DupCursor<tables::HashedStorage>;
|
||||
|
||||
fn hashed_account_cursor(&'a self) -> Result<Self::AccountCursor, reth_db::DatabaseError> {
|
||||
fn hashed_account_cursor(&self) -> Result<Self::AccountCursor, reth_db::DatabaseError> {
|
||||
self.cursor_read::<tables::HashedAccount>()
|
||||
}
|
||||
|
||||
fn hashed_storage_cursor(&'a self) -> Result<Self::StorageCursor, reth_db::DatabaseError> {
|
||||
fn hashed_storage_cursor(&self) -> Result<Self::StorageCursor, reth_db::DatabaseError> {
|
||||
self.cursor_dup_read::<tables::HashedStorage>()
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,21 +8,17 @@ mod post_state;
|
||||
pub use post_state::*;
|
||||
|
||||
/// The factory trait for creating cursors over the hashed state.
|
||||
pub trait HashedCursorFactory<'a> {
|
||||
pub trait HashedCursorFactory {
|
||||
/// The hashed account cursor type.
|
||||
type AccountCursor: HashedAccountCursor
|
||||
where
|
||||
Self: 'a;
|
||||
type AccountCursor: HashedAccountCursor;
|
||||
/// The hashed storage cursor type.
|
||||
type StorageCursor: HashedStorageCursor
|
||||
where
|
||||
Self: 'a;
|
||||
type StorageCursor: HashedStorageCursor;
|
||||
|
||||
/// Returns a cursor for iterating over all hashed accounts in the state.
|
||||
fn hashed_account_cursor(&'a self) -> Result<Self::AccountCursor, reth_db::DatabaseError>;
|
||||
fn hashed_account_cursor(&self) -> Result<Self::AccountCursor, reth_db::DatabaseError>;
|
||||
|
||||
/// Returns a cursor for iterating over all hashed storage entries in the state.
|
||||
fn hashed_storage_cursor(&'a self) -> Result<Self::StorageCursor, reth_db::DatabaseError>;
|
||||
fn hashed_storage_cursor(&self) -> Result<Self::StorageCursor, reth_db::DatabaseError>;
|
||||
}
|
||||
|
||||
/// The cursor for iterating over hashed accounts.
|
||||
|
||||
@ -156,6 +156,12 @@ pub struct HashedPostStateCursorFactory<'a, 'b, TX> {
|
||||
post_state: &'b HashedPostState,
|
||||
}
|
||||
|
||||
impl<'a, 'b, TX> Clone for HashedPostStateCursorFactory<'a, 'b, TX> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { tx: self.tx, post_state: self.post_state }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, TX> HashedPostStateCursorFactory<'a, 'b, TX> {
|
||||
/// Create a new factory.
|
||||
pub fn new(tx: &'a TX, post_state: &'b HashedPostState) -> Self {
|
||||
@ -163,20 +169,18 @@ impl<'a, 'b, TX> HashedPostStateCursorFactory<'a, 'b, TX> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tx, TX: DbTx<'tx>> HashedCursorFactory<'a>
|
||||
for HashedPostStateCursorFactory<'a, 'b, TX>
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
type AccountCursor = HashedPostStateAccountCursor<'b, <TX as DbTxGAT<'a>>::Cursor<tables::HashedAccount>> where Self: 'a;
|
||||
type StorageCursor = HashedPostStateStorageCursor<'b, <TX as DbTxGAT<'a>>::DupCursor<tables::HashedStorage>> where Self: 'a;
|
||||
impl<'a, 'b, 'tx, TX: DbTx<'tx>> HashedCursorFactory for HashedPostStateCursorFactory<'a, 'b, TX> {
|
||||
type AccountCursor =
|
||||
HashedPostStateAccountCursor<'b, <TX as DbTxGAT<'a>>::Cursor<tables::HashedAccount>>;
|
||||
type StorageCursor =
|
||||
HashedPostStateStorageCursor<'b, <TX as DbTxGAT<'a>>::DupCursor<tables::HashedStorage>>;
|
||||
|
||||
fn hashed_account_cursor(&'a self) -> Result<Self::AccountCursor, reth_db::DatabaseError> {
|
||||
fn hashed_account_cursor(&self) -> Result<Self::AccountCursor, reth_db::DatabaseError> {
|
||||
let cursor = self.tx.cursor_read::<tables::HashedAccount>()?;
|
||||
Ok(HashedPostStateAccountCursor::new(cursor, self.post_state))
|
||||
}
|
||||
|
||||
fn hashed_storage_cursor(&'a self) -> Result<Self::StorageCursor, reth_db::DatabaseError> {
|
||||
fn hashed_storage_cursor(&self) -> Result<Self::StorageCursor, reth_db::DatabaseError> {
|
||||
let cursor = self.tx.cursor_dup_read::<tables::HashedStorage>()?;
|
||||
Ok(HashedPostStateStorageCursor::new(cursor, self.post_state))
|
||||
}
|
||||
@ -544,12 +548,10 @@ mod tests {
|
||||
use reth_db::{database::Database, test_utils::create_test_rw_db, transaction::DbTxMut};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
fn assert_account_cursor_order<'a, 'b>(
|
||||
factory: &'a impl HashedCursorFactory<'b>,
|
||||
fn assert_account_cursor_order(
|
||||
factory: &impl HashedCursorFactory,
|
||||
mut expected: impl Iterator<Item = (B256, Account)>,
|
||||
) where
|
||||
'a: 'b,
|
||||
{
|
||||
) {
|
||||
let mut cursor = factory.hashed_account_cursor().unwrap();
|
||||
|
||||
let first_account = cursor.seek(B256::default()).unwrap();
|
||||
@ -563,12 +565,10 @@ mod tests {
|
||||
assert!(cursor.next().unwrap().is_none());
|
||||
}
|
||||
|
||||
fn assert_storage_cursor_order<'a, 'b>(
|
||||
factory: &'a impl HashedCursorFactory<'b>,
|
||||
fn assert_storage_cursor_order(
|
||||
factory: &impl HashedCursorFactory,
|
||||
expected: impl Iterator<Item = (B256, BTreeMap<B256, U256>)>,
|
||||
) where
|
||||
'a: 'b,
|
||||
{
|
||||
) {
|
||||
let mut cursor = factory.hashed_storage_cursor().unwrap();
|
||||
|
||||
for (account, storage) in expected {
|
||||
|
||||
@ -35,32 +35,32 @@ use reth_primitives::{
|
||||
/// After traversing the path, the proof generator continues to restore the root node of the trie
|
||||
/// until completion. The root node is then inserted at the start of the proof.
|
||||
#[derive(Debug)]
|
||||
pub struct Proof<'a, 'b, TX, H> {
|
||||
pub struct Proof<'a, TX, H> {
|
||||
/// A reference to the database transaction.
|
||||
tx: &'a TX,
|
||||
/// The factory for hashed cursors.
|
||||
hashed_cursor_factory: &'b H,
|
||||
hashed_cursor_factory: H,
|
||||
}
|
||||
|
||||
impl<'a, TX> Proof<'a, 'a, TX, TX> {
|
||||
impl<'a, TX> Proof<'a, TX, &'a TX> {
|
||||
/// Create a new [Proof] instance.
|
||||
pub fn new(tx: &'a TX) -> Self {
|
||||
Self { tx, hashed_cursor_factory: tx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tx, TX, H> Proof<'a, 'b, TX, H>
|
||||
impl<'a, 'tx, TX, H> Proof<'a, TX, H>
|
||||
where
|
||||
TX: DbTx<'tx>,
|
||||
H: HashedCursorFactory<'b>,
|
||||
H: HashedCursorFactory + Clone,
|
||||
{
|
||||
/// Generate an account proof from intermediate nodes.
|
||||
pub fn account_proof(&self, address: Address) -> Result<Vec<Bytes>, ProofError> {
|
||||
let hashed_address = keccak256(address);
|
||||
let target_nibbles = Nibbles::unpack(hashed_address);
|
||||
|
||||
let mut proof_restorer =
|
||||
ProofRestorer::new(self.tx)?.with_hashed_cursor_factory(self.hashed_cursor_factory)?;
|
||||
let mut proof_restorer = ProofRestorer::new(self.tx)?
|
||||
.with_hashed_cursor_factory(self.hashed_cursor_factory.clone())?;
|
||||
let mut trie_cursor =
|
||||
AccountTrieCursor::new(self.tx.cursor_read::<tables::AccountsTrie>()?);
|
||||
|
||||
@ -101,7 +101,7 @@ where
|
||||
fn traverse_path<T: DbCursorRO<'a, tables::AccountsTrie>>(
|
||||
&self,
|
||||
trie_cursor: &mut AccountTrieCursor<T>,
|
||||
proof_restorer: &mut ProofRestorer<'a, 'b, TX, H>,
|
||||
proof_restorer: &mut ProofRestorer<'a, TX, H>,
|
||||
hashed_address: B256,
|
||||
) -> Result<Vec<Bytes>, ProofError> {
|
||||
let mut intermediate_proofs = Vec::new();
|
||||
@ -129,14 +129,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
struct ProofRestorer<'a, 'b, TX, H>
|
||||
struct ProofRestorer<'a, TX, H>
|
||||
where
|
||||
H: HashedCursorFactory<'b>,
|
||||
H: HashedCursorFactory,
|
||||
{
|
||||
/// A reference to the database transaction.
|
||||
tx: &'a TX,
|
||||
/// The factory for hashed cursors.
|
||||
hashed_cursor_factory: &'b H,
|
||||
hashed_cursor_factory: H,
|
||||
/// The hashed account cursor.
|
||||
hashed_account_cursor: H::AccountCursor,
|
||||
/// Pre-allocated buffer for account RLP encoding
|
||||
@ -145,7 +145,7 @@ where
|
||||
node_rlp_buf: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a, 'tx, TX> ProofRestorer<'a, 'a, TX, TX>
|
||||
impl<'a, 'tx, TX> ProofRestorer<'a, TX, &'a TX>
|
||||
where
|
||||
TX: DbTx<'tx>,
|
||||
{
|
||||
@ -161,18 +161,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tx, TX, H> ProofRestorer<'a, 'b, TX, H>
|
||||
impl<'a, 'tx, TX, H> ProofRestorer<'a, TX, H>
|
||||
where
|
||||
TX: DbTx<'tx> + HashedCursorFactory<'a>,
|
||||
H: HashedCursorFactory<'b>,
|
||||
TX: DbTx<'tx>,
|
||||
H: HashedCursorFactory + Clone,
|
||||
{
|
||||
/// Set the hashed cursor factory.
|
||||
fn with_hashed_cursor_factory<'c, HF>(
|
||||
fn with_hashed_cursor_factory<HF>(
|
||||
self,
|
||||
hashed_cursor_factory: &'c HF,
|
||||
) -> Result<ProofRestorer<'a, 'c, TX, HF>, ProofError>
|
||||
hashed_cursor_factory: HF,
|
||||
) -> Result<ProofRestorer<'a, TX, HF>, ProofError>
|
||||
where
|
||||
HF: HashedCursorFactory<'c>,
|
||||
HF: HashedCursorFactory,
|
||||
{
|
||||
let hashed_account_cursor = hashed_cursor_factory.hashed_account_cursor()?;
|
||||
Ok(ProofRestorer {
|
||||
@ -222,7 +222,7 @@ where
|
||||
|
||||
// Restore account's storage root.
|
||||
let storage_root = StorageRoot::new_hashed(self.tx, hashed_address)
|
||||
.with_hashed_cursor_factory(self.hashed_cursor_factory)
|
||||
.with_hashed_cursor_factory(self.hashed_cursor_factory.clone())
|
||||
.root()?;
|
||||
|
||||
self.account_rlp_buf.clear();
|
||||
@ -250,7 +250,7 @@ where
|
||||
|
||||
// Restore account's storage root.
|
||||
let storage_root = StorageRoot::new_hashed(self.tx, hashed_address)
|
||||
.with_hashed_cursor_factory(self.hashed_cursor_factory)
|
||||
.with_hashed_cursor_factory(self.hashed_cursor_factory.clone())
|
||||
.root()?;
|
||||
|
||||
self.account_rlp_buf.clear();
|
||||
|
||||
@ -23,11 +23,11 @@ use std::{
|
||||
|
||||
/// StateRoot is used to compute the root node of a state trie.
|
||||
#[derive(Debug)]
|
||||
pub struct StateRoot<'a, 'b, TX, H> {
|
||||
pub struct StateRoot<'a, TX, H> {
|
||||
/// A reference to the database transaction.
|
||||
pub tx: &'a TX,
|
||||
/// The factory for hashed cursors.
|
||||
pub hashed_cursor_factory: &'b H,
|
||||
pub hashed_cursor_factory: H,
|
||||
/// A set of account prefixes that have changed.
|
||||
pub changed_account_prefixes: PrefixSet,
|
||||
/// A map containing storage changes with the hashed address as key and a set of storage key
|
||||
@ -41,7 +41,7 @@ pub struct StateRoot<'a, 'b, TX, H> {
|
||||
threshold: u64,
|
||||
}
|
||||
|
||||
impl<'a, 'b, TX, H> StateRoot<'a, 'b, TX, H> {
|
||||
impl<'a, TX, H> StateRoot<'a, TX, H> {
|
||||
/// Set the changed account prefixes.
|
||||
pub fn with_changed_account_prefixes(mut self, prefixes: PrefixSet) -> Self {
|
||||
self.changed_account_prefixes = prefixes;
|
||||
@ -79,10 +79,10 @@ impl<'a, 'b, TX, H> StateRoot<'a, 'b, TX, H> {
|
||||
}
|
||||
|
||||
/// Set the hashed cursor factory.
|
||||
pub fn with_hashed_cursor_factory<'c, HF>(
|
||||
pub fn with_hashed_cursor_factory<HF>(
|
||||
self,
|
||||
hashed_cursor_factory: &'c HF,
|
||||
) -> StateRoot<'a, 'c, TX, HF> {
|
||||
hashed_cursor_factory: HF,
|
||||
) -> StateRoot<'a, TX, HF> {
|
||||
StateRoot {
|
||||
tx: self.tx,
|
||||
changed_account_prefixes: self.changed_account_prefixes,
|
||||
@ -95,9 +95,9 @@ impl<'a, 'b, TX, H> StateRoot<'a, 'b, TX, H> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tx, TX> StateRoot<'a, 'a, TX, TX>
|
||||
impl<'a, 'tx, TX> StateRoot<'a, TX, &'a TX>
|
||||
where
|
||||
TX: DbTx<'tx> + HashedCursorFactory<'a>,
|
||||
TX: DbTx<'tx>,
|
||||
{
|
||||
/// Create a new [StateRoot] instance.
|
||||
pub fn new(tx: &'a TX) -> Self {
|
||||
@ -180,10 +180,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tx, TX, H> StateRoot<'a, 'b, TX, H>
|
||||
impl<'a, 'tx, TX, H> StateRoot<'a, TX, H>
|
||||
where
|
||||
TX: DbTx<'tx>,
|
||||
H: HashedCursorFactory<'b>,
|
||||
H: HashedCursorFactory + Clone,
|
||||
{
|
||||
/// Walks the intermediate nodes of existing state trie (if any) and hashed entries. Feeds the
|
||||
/// nodes into the hash builder. Collects the updates in the process.
|
||||
@ -300,7 +300,7 @@ where
|
||||
// TODO: We can consider introducing the TrieProgress::Progress/Complete
|
||||
// abstraction inside StorageRoot, but let's give it a try as-is for now.
|
||||
let storage_root_calculator = StorageRoot::new_hashed(self.tx, hashed_address)
|
||||
.with_hashed_cursor_factory(self.hashed_cursor_factory)
|
||||
.with_hashed_cursor_factory(self.hashed_cursor_factory.clone())
|
||||
.with_changed_prefixes(
|
||||
self.changed_storage_prefixes
|
||||
.get(&hashed_address)
|
||||
@ -370,20 +370,20 @@ where
|
||||
|
||||
/// StorageRoot is used to compute the root node of an account storage trie.
|
||||
#[derive(Debug)]
|
||||
pub struct StorageRoot<'a, 'b, TX, H> {
|
||||
pub struct StorageRoot<'a, TX, H> {
|
||||
/// A reference to the database transaction.
|
||||
pub tx: &'a TX,
|
||||
/// The factory for hashed cursors.
|
||||
pub hashed_cursor_factory: &'b H,
|
||||
pub hashed_cursor_factory: H,
|
||||
/// The hashed address of an account.
|
||||
pub hashed_address: B256,
|
||||
/// The set of storage slot prefixes that have changed.
|
||||
pub changed_prefixes: PrefixSet,
|
||||
}
|
||||
|
||||
impl<'a, 'tx, TX> StorageRoot<'a, 'a, TX, TX>
|
||||
impl<'a, 'tx, TX> StorageRoot<'a, TX, &'a TX>
|
||||
where
|
||||
TX: DbTx<'tx> + HashedCursorFactory<'a>,
|
||||
TX: DbTx<'tx>,
|
||||
{
|
||||
/// Creates a new storage root calculator given an raw address.
|
||||
pub fn new(tx: &'a TX, address: Address) -> Self {
|
||||
@ -401,16 +401,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, TX, H> StorageRoot<'a, 'b, TX, H> {
|
||||
impl<'a, TX, H> StorageRoot<'a, TX, H> {
|
||||
/// Creates a new storage root calculator given an raw address.
|
||||
pub fn new_with_factory(tx: &'a TX, hashed_cursor_factory: &'b H, address: Address) -> Self {
|
||||
pub fn new_with_factory(tx: &'a TX, hashed_cursor_factory: H, address: Address) -> Self {
|
||||
Self::new_hashed_with_factory(tx, hashed_cursor_factory, keccak256(address))
|
||||
}
|
||||
|
||||
/// Creates a new storage root calculator given a hashed address.
|
||||
pub fn new_hashed_with_factory(
|
||||
tx: &'a TX,
|
||||
hashed_cursor_factory: &'b H,
|
||||
hashed_cursor_factory: H,
|
||||
hashed_address: B256,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -428,10 +428,10 @@ impl<'a, 'b, TX, H> StorageRoot<'a, 'b, TX, H> {
|
||||
}
|
||||
|
||||
/// Set the hashed cursor factory.
|
||||
pub fn with_hashed_cursor_factory<'c, HF>(
|
||||
pub fn with_hashed_cursor_factory<HF>(
|
||||
self,
|
||||
hashed_cursor_factory: &'c HF,
|
||||
) -> StorageRoot<'a, 'c, TX, HF> {
|
||||
hashed_cursor_factory: HF,
|
||||
) -> StorageRoot<'a, TX, HF> {
|
||||
StorageRoot {
|
||||
tx: self.tx,
|
||||
hashed_address: self.hashed_address,
|
||||
@ -441,10 +441,10 @@ impl<'a, 'b, TX, H> StorageRoot<'a, 'b, TX, H> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tx, TX, H> StorageRoot<'a, 'b, TX, H>
|
||||
impl<'a, 'tx, TX, H> StorageRoot<'a, TX, H>
|
||||
where
|
||||
TX: DbTx<'tx>,
|
||||
H: HashedCursorFactory<'b>,
|
||||
H: HashedCursorFactory,
|
||||
{
|
||||
/// Walks the hashed storage table entries for a given address and calculates the storage root.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user