diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs index 564e7a983..7878a979b 100644 --- a/ledger-tool/src/main.rs +++ b/ledger-tool/src/main.rs @@ -28,7 +28,7 @@ use solana_measure::measure::Measure; use solana_runtime::{ accounts_db::AccountsDbConfig, accounts_index::AccountsIndexConfig, - bank::{Bank, RewardCalculationEvent, TotalAccountsStats}, + bank::{Bank, RewardCalculationEvent}, bank_forks::BankForks, cost_model::CostModel, cost_tracker::CostTracker, @@ -2509,26 +2509,21 @@ fn main() { measure.stop(); info!("{}", measure); - let print_account_contents = !arg_matches.is_present("no_account_contents"); - let print_account_data = !arg_matches.is_present("no_account_data"); - let rent_collector = bank.rent_collector(); - let mut total_accounts_stats = TotalAccountsStats::default(); - let mut measure = Measure::start("processing accounts"); - for (pubkey, (account, slot)) in accounts.into_iter() { - let data_len = account.data().len(); - total_accounts_stats.num_accounts += 1; - total_accounts_stats.data_len += data_len; - if account.executable() { - total_accounts_stats.num_executable_accounts += 1; - total_accounts_stats.executable_data_len += data_len; - } - if !rent_collector.should_collect_rent(&pubkey, &account, false) - || rent_collector.get_rent_due(&account).1 - { - total_accounts_stats.num_rent_exempt_accounts += 1; - } + let mut measure = Measure::start("calculating total accounts stats"); + let total_accounts_stats = bank.calculate_total_accounts_stats( + accounts + .iter() + .map(|(pubkey, (account, _slot))| (pubkey, account)), + ); + measure.stop(); + info!("{}", measure); - if print_account_contents { + let print_account_contents = !arg_matches.is_present("no_account_contents"); + if print_account_contents { + let print_account_data = !arg_matches.is_present("no_account_data"); + let mut measure = Measure::start("printing account contents"); + for (pubkey, (account, slot)) in accounts.into_iter() { + let data_len = account.data().len(); println!("{}:", pubkey); println!(" - balance: {} SOL", lamports_to_sol(account.lamports())); println!(" - owner: '{}'", account.owner()); @@ -2540,9 +2535,9 @@ fn main() { } println!(" - data_len: {}", data_len); } + measure.stop(); + info!("{}", measure); } - measure.stop(); - info!("{}", measure); println!("{:#?}", total_accounts_stats); } diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index abcb31d17..b788bdaf6 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -6320,33 +6320,48 @@ impl Bank { self.feature_set .is_active(&feature_set::rent_for_sysvars::id()) } -} -/// Scan all the accounts for this bank and collect stats -pub fn get_total_accounts_stats(bank: &Bank) -> ScanResult { - let rent_collector = bank.rent_collector(); - bank.rc.accounts.accounts_db.scan_accounts( - &Ancestors::default(), - bank.bank_id(), - |total_accounts_stats: &mut TotalAccountsStats, item| { - if let Some((pubkey, account, _slot)) = item { - total_accounts_stats.num_accounts += 1; - total_accounts_stats.data_len += account.data().len(); + /// Get all the accounts for this bank and calculate stats + pub fn get_total_accounts_stats(&self) -> ScanResult { + let accounts = self.get_all_accounts_with_modified_slots()?; + Ok(self.calculate_total_accounts_stats( + accounts + .iter() + .map(|(pubkey, account, _slot)| (pubkey, account)), + )) + } - if account.executable() { - total_accounts_stats.num_executable_accounts += 1; - total_accounts_stats.executable_data_len += account.data().len(); - } + /// Given all the accounts for a bank, calculate stats + pub fn calculate_total_accounts_stats<'a>( + &self, + accounts: impl Iterator, + ) -> TotalAccountsStats { + let rent_collector = self.rent_collector(); + let mut total_accounts_stats = TotalAccountsStats::default(); + accounts.for_each(|(pubkey, account)| { + let data_len = account.data().len(); + total_accounts_stats.num_accounts += 1; + total_accounts_stats.data_len += data_len; - if !rent_collector.should_collect_rent(pubkey, &account, false) || { - let (_rent_due, exempt) = rent_collector.get_rent_due(&account); - exempt - } { - total_accounts_stats.num_rent_exempt_accounts += 1; + if account.executable() { + total_accounts_stats.num_executable_accounts += 1; + total_accounts_stats.executable_data_len += data_len; + } + + if !rent_collector.should_collect_rent(pubkey, account, false) + || rent_collector.get_rent_due(account).1 + { + total_accounts_stats.num_rent_exempt_accounts += 1; + } else { + total_accounts_stats.num_rent_paying_accounts += 1; + if data_len == 0 { + total_accounts_stats.num_rent_paying_accounts_without_data += 1; } } - }, - ) + }); + + total_accounts_stats + } } /// Struct to collect stats when scanning all accounts in `get_total_accounts_stats()` @@ -6364,6 +6379,10 @@ pub struct TotalAccountsStats { /// Total number of rent exempt accounts pub num_rent_exempt_accounts: usize, + /// Total number of rent paying accounts + pub num_rent_paying_accounts: usize, + /// Total number of rent paying accounts without data + pub num_rent_paying_accounts_without_data: usize, } impl Drop for Bank {