diff --git a/accounts-db/src/accounts_db.rs b/accounts-db/src/accounts_db.rs index 1b31033c3884e0..1268b308f85ebd 100644 --- a/accounts-db/src/accounts_db.rs +++ b/accounts-db/src/accounts_db.rs @@ -4941,8 +4941,7 @@ impl AccountsDb { self.scan_cache_storage_fallback(slot, cache_map_func, |retval, storage| { match scan_account_storage_data { ScanAccountStorageData::NoData => { - storage.scan_accounts(|account| { - let account_without_data = StoredAccountInfoWithoutData::new_from(&account); + storage.scan_accounts_without_data(|account_without_data| { storage_scan_func(retval, &account_without_data, None); }); } diff --git a/accounts-db/src/accounts_file.rs b/accounts-db/src/accounts_file.rs index e09909d0ff0645..89c33fe6b55977 100644 --- a/accounts-db/src/accounts_file.rs +++ b/accounts-db/src/accounts_file.rs @@ -3,7 +3,7 @@ use crate::account_storage::meta::StoredAccountMeta; use { crate::{ account_info::AccountInfo, - account_storage::stored_account_info::StoredAccountInfo, + account_storage::stored_account_info::{StoredAccountInfo, StoredAccountInfoWithoutData}, accounts_db::AccountsFileId, accounts_update_notifier_interface::AccountForGeyser, append_vec::{AppendVec, AppendVecError, IndexInfo}, @@ -265,6 +265,26 @@ impl AccountsFile { } /// Iterate over all accounts and call `callback` with each account. + /// + /// Note that account data is not read/passed to the callback. + pub fn scan_accounts_without_data( + &self, + callback: impl for<'local> FnMut(StoredAccountInfoWithoutData<'local>), + ) { + match self { + Self::AppendVec(av) => av.scan_accounts_without_data(callback), + Self::TieredStorage(ts) => { + if let Some(reader) = ts.reader() { + _ = reader.scan_accounts_without_data(callback); + } + } + } + } + + /// Iterate over all accounts and call `callback` with each account. + /// + /// Prefer scan_accounts_without_data() when account data is not needed, + /// as it can potentially read less and be faster. pub fn scan_accounts(&self, callback: impl for<'local> FnMut(StoredAccountInfo<'local>)) { match self { Self::AppendVec(av) => av.scan_accounts(callback), diff --git a/accounts-db/src/append_vec.rs b/accounts-db/src/append_vec.rs index 808ec2c990df6a..96503aee55f7c1 100644 --- a/accounts-db/src/append_vec.rs +++ b/accounts-db/src/append_vec.rs @@ -8,7 +8,7 @@ use { crate::{ account_storage::{ meta::{AccountMeta, StoredAccountMeta, StoredMeta}, - stored_account_info::StoredAccountInfo, + stored_account_info::{StoredAccountInfo, StoredAccountInfoWithoutData}, }, accounts_file::{ AccountsFileError, InternalsForArchive, MatchAccountOwnerError, Result, StorageAccess, @@ -1100,6 +1100,29 @@ impl AppendVec { } /// Iterate over all accounts and call `callback` with each account. + /// + /// Note that account data is not read/passed to the callback. + pub fn scan_accounts_without_data( + &self, + mut callback: impl for<'local> FnMut(StoredAccountInfoWithoutData<'local>), + ) { + self.scan_stored_accounts_no_data(|stored_account| { + let account = StoredAccountInfoWithoutData { + pubkey: stored_account.pubkey(), + lamports: stored_account.lamports(), + owner: stored_account.owner(), + data_len: stored_account.data_len() as usize, + executable: stored_account.executable(), + rent_epoch: stored_account.rent_epoch(), + }; + callback(account); + }) + } + + /// Iterate over all accounts and call `callback` with each account. + /// + /// Prefer scan_accounts_without_data() when account data is not needed, + /// as it can potentially read less and be faster. pub fn scan_accounts(&self, mut callback: impl for<'local> FnMut(StoredAccountInfo<'local>)) { self.scan_accounts_stored_meta(|stored_account_meta| { let account = StoredAccountInfo { diff --git a/accounts-db/src/tiered_storage/readable.rs b/accounts-db/src/tiered_storage/readable.rs index 0ff979991bb2ed..82d0df89f40295 100644 --- a/accounts-db/src/tiered_storage/readable.rs +++ b/accounts-db/src/tiered_storage/readable.rs @@ -1,6 +1,9 @@ use { crate::{ - account_storage::{meta::StoredAccountMeta, stored_account_info::StoredAccountInfo}, + account_storage::{ + meta::StoredAccountMeta, + stored_account_info::{StoredAccountInfo, StoredAccountInfoWithoutData}, + }, accounts_file::MatchAccountOwnerError, append_vec::{IndexInfo, IndexInfoInner}, tiered_storage::{ @@ -168,6 +171,30 @@ impl TieredStorageReader { } /// Iterate over all accounts and call `callback` with each account. + /// + /// Note that account data is not read/passed to the callback. + pub fn scan_accounts_without_data( + &self, + mut callback: impl for<'local> FnMut(StoredAccountInfoWithoutData<'local>), + ) -> TieredStorageResult<()> { + // Note, this should be reimplemented to not read account data + self.scan_accounts(|stored_account| { + let account = StoredAccountInfoWithoutData { + pubkey: stored_account.pubkey(), + lamports: stored_account.lamports(), + owner: stored_account.owner(), + data_len: stored_account.data().len(), + executable: stored_account.executable(), + rent_epoch: stored_account.rent_epoch(), + }; + callback(account); + }) + } + + /// Iterate over all accounts and call `callback` with each account. + /// + /// Prefer scan_accounts_without_data() when account data is not needed, + /// as it can potentially read less and be faster. pub fn scan_accounts( &self, mut callback: impl for<'local> FnMut(StoredAccountInfo<'local>),