Skip to main content

reth_storage_api/
account.rs

1use alloc::{
2    collections::{BTreeMap, BTreeSet},
3    vec::Vec,
4};
5use alloy_primitives::{Address, BlockNumber};
6use auto_impl::auto_impl;
7use core::ops::{RangeBounds, RangeInclusive};
8use reth_db_models::AccountBeforeTx;
9use reth_primitives_traits::Account;
10use reth_storage_errors::provider::ProviderResult;
11
12/// Account reader
13#[auto_impl(&, Arc, Box)]
14pub trait AccountReader {
15    /// Get basic account information.
16    ///
17    /// Returns `None` if the account doesn't exist.
18    fn basic_account(&self, address: &Address) -> ProviderResult<Option<Account>>;
19}
20
21/// Account reader
22#[auto_impl(&, Arc, Box)]
23pub trait AccountExtReader {
24    /// Iterate over account changesets and return all account address that were changed.
25    fn changed_accounts_with_range(
26        &self,
27        _range: RangeInclusive<BlockNumber>,
28    ) -> ProviderResult<BTreeSet<Address>>;
29
30    /// Get basic account information for multiple accounts. A more efficient version than calling
31    /// [`AccountReader::basic_account`] repeatedly.
32    ///
33    /// Returns `None` if the account doesn't exist.
34    fn basic_accounts(
35        &self,
36        _iter: impl IntoIterator<Item = Address>,
37    ) -> ProviderResult<Vec<(Address, Option<Account>)>>;
38
39    /// Iterate over account changesets and return all account addresses that were changed alongside
40    /// each specific set of blocks.
41    ///
42    /// NOTE: Get inclusive range of blocks.
43    fn changed_accounts_and_blocks_with_range(
44        &self,
45        range: RangeInclusive<BlockNumber>,
46    ) -> ProviderResult<BTreeMap<Address, Vec<BlockNumber>>>;
47}
48
49/// `AccountChange` reader
50#[auto_impl(&, Arc, Box)]
51pub trait ChangeSetReader {
52    /// Iterate over account changesets and return the account state from before this block.
53    fn account_block_changeset(
54        &self,
55        block_number: BlockNumber,
56    ) -> ProviderResult<Vec<AccountBeforeTx>>;
57
58    /// Search the block's changesets for the given address, and return the result.
59    ///
60    /// Returns `None` if the account was not changed in this block.
61    fn get_account_before_block(
62        &self,
63        block_number: BlockNumber,
64        address: Address,
65    ) -> ProviderResult<Option<AccountBeforeTx>>;
66
67    /// Get all account changesets in a range of blocks.
68    ///
69    /// Accepts any range type that implements `RangeBounds<BlockNumber>`, including:
70    /// - `Range<BlockNumber>` (e.g., `0..100`)
71    /// - `RangeInclusive<BlockNumber>` (e.g., `0..=99`)
72    /// - `RangeFrom<BlockNumber>` (e.g., `0..`) - iterates until exhausted
73    ///
74    /// If there is no start bound, 0 is used as the start block.
75    ///
76    /// Returns a vector of (`block_number`, changeset) pairs.
77    fn account_changesets_range(
78        &self,
79        range: impl RangeBounds<BlockNumber>,
80    ) -> ProviderResult<Vec<(BlockNumber, AccountBeforeTx)>>;
81
82    /// Get the total count of all account changes.
83    ///
84    /// Returns the total number of account changes across all blocks.
85    fn account_changeset_count(&self) -> ProviderResult<usize>;
86}