diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs index 7f0501e038..bfc225b357 100644 --- a/ledger-tool/src/main.rs +++ b/ledger-tool/src/main.rs @@ -1028,6 +1028,12 @@ fn main() { .takes_value(false) .help("Include sysvars too"), ) + .arg( + Arg::with_name("exclude_account_data") + .long("exclude-account-data") + .takes_value(false) + .help("Exclude account data (useful for large number of accounts)"), + ) .arg(&max_genesis_archive_unpacked_size_arg) ).subcommand( SubCommand::with_name("capitalization") @@ -1537,6 +1543,7 @@ fn main() { }; let genesis_config = open_genesis_config_by(&ledger_path, arg_matches); let include_sysvars = arg_matches.is_present("include_sysvars"); + let exclude_account_data = arg_matches.is_present("exclude_account_data"); match load_bank_forks( arg_matches, &ledger_path, @@ -1554,21 +1561,26 @@ fn main() { }); let accounts: BTreeMap<_, _> = bank - .get_program_accounts(None) + .get_all_accounts_with_modified_slots() .into_iter() - .filter(|(pubkey, _account)| { + .filter(|(pubkey, _account, _slot)| { include_sysvars || !solana_sdk::sysvar::is_sysvar_id(pubkey) }) + .map(|(pubkey, account, slot)| (pubkey, (account, slot))) .collect(); println!("---"); - for (pubkey, account) in accounts.into_iter() { + 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); println!(" - executable: {}", account.executable); - println!(" - data: '{}'", bs58::encode(account.data).into_string()); + println!(" - slot: {}", slot); + println!(" - rent_epoch: {}", account.rent_epoch); + if !exclude_account_data { + println!(" - data: '{}'", bs58::encode(account.data).into_string()); + } println!(" - data_len: {}", data_len); } } diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index 50dd2d1284..bab8b3de53 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -437,18 +437,22 @@ impl Accounts { } } + fn is_loadable(account: &Account) -> bool { + // Don't ever load zero lamport accounts into runtime because + // the existence of zero-lamport accounts are never deterministic!! + account.lamports > 0 + } + fn load_while_filtering bool>( collector: &mut Vec<(Pubkey, Account)>, - option: Option<(&Pubkey, Account, Slot)>, + some_account_tuple: Option<(&Pubkey, Account, Slot)>, filter: F, ) { - if let Some(data) = option - // Don't ever load zero lamport accounts into runtime because - // the existence of zero-lamport accounts are never deterministic!! - .filter(|(_, account, _)| account.lamports > 0 && filter(account)) + if let Some(mapped_account_tuple) = some_account_tuple + .filter(|(_, account, _)| Self::is_loadable(account) && filter(account)) .map(|(pubkey, account, _slot)| (*pubkey, account)) { - collector.push(data) + collector.push(mapped_account_tuple) } } @@ -459,14 +463,27 @@ impl Accounts { ) -> Vec<(Pubkey, Account)> { self.accounts_db.scan_accounts( ancestors, - |collector: &mut Vec<(Pubkey, Account)>, option| { - Self::load_while_filtering(collector, option, |account| { + |collector: &mut Vec<(Pubkey, Account)>, some_account_tuple| { + Self::load_while_filtering(collector, some_account_tuple, |account| { program_id.is_none() || Some(&account.owner) == program_id }) }, ) } + pub fn load_all(&self, ancestors: &Ancestors) -> Vec<(Pubkey, Account, Slot)> { + self.accounts_db.scan_accounts( + ancestors, + |collector: &mut Vec<(Pubkey, Account, Slot)>, some_account_tuple| { + if let Some((pubkey, account, slot)) = + some_account_tuple.filter(|(_, account, _)| Self::is_loadable(account)) + { + collector.push((*pubkey, account, slot)) + } + }, + ) + } + pub fn load_to_collect_rent_eagerly>( &self, ancestors: &Ancestors, diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 48d59b5d9b..5838078128 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -2684,6 +2684,10 @@ impl Bank { .load_by_program(&self.ancestors, program_id) } + pub fn get_all_accounts_with_modified_slots(&self) -> Vec<(Pubkey, Account, Slot)> { + self.rc.accounts.load_all(&self.ancestors) + } + pub fn get_program_accounts_modified_since_parent( &self, program_id: &Pubkey,