Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

ledger-tool: stream output of accounts subcommand #28461

Merged
merged 1 commit into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 66 additions & 44 deletions ledger-tool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use {
itertools::Itertools,
log::*,
regex::Regex,
serde::Serialize,
serde::{
ser::{SerializeSeq, Serializer},
Serialize,
},
serde_json::json,
solana_account_decoder::{UiAccount, UiAccountData, UiAccountEncoding},
solana_clap_utils::{
Expand All @@ -20,6 +23,7 @@ use {
is_parsable, is_pow2, is_pubkey, is_pubkey_or_keypair, is_slot, is_valid_percentage,
},
},
solana_cli_output::{CliAccount, CliAccountNewConfig, OutputFormat},
solana_core::{
system_monitor_service::SystemMonitorService, validator::move_and_async_delete_path,
},
Expand All @@ -39,14 +43,15 @@ use {
},
solana_measure::{measure, measure::Measure},
solana_runtime::{
accounts::Accounts,
accounts_background_service::{
AbsRequestHandlers, AbsRequestSender, AccountsBackgroundService,
PrunedBanksRequestHandler, SnapshotRequestHandler,
},
accounts_db::{AccountsDbConfig, FillerAccountsConfig},
accounts_index::{AccountsIndexConfig, IndexLimitMb, ScanConfig},
accounts_update_notifier_interface::AccountsUpdateNotifier,
bank::{Bank, RewardCalculationEvent},
bank::{Bank, RewardCalculationEvent, TotalAccountsStats},
bank_forks::BankForks,
cost_model::CostModel,
cost_tracker::CostTracker,
Expand Down Expand Up @@ -3362,52 +3367,69 @@ fn main() {
});

let bank = bank_forks.read().unwrap().working_bank();
let mut measure = Measure::start("getting accounts");
let accounts: BTreeMap<_, _> = bank
.get_all_accounts_with_modified_slots()
.unwrap()
.into_iter()
.filter(|(pubkey, _account, _slot)| {
include_sysvars || !solana_sdk::sysvar::is_sysvar_id(pubkey)
})
.map(|(pubkey, account, slot)| (pubkey, (account, slot)))
.collect();
measure.stop();
info!("{}", measure);
let mut serializer = serde_json::Serializer::new(stdout());
let (summarize, mut json_serializer) =
match OutputFormat::from_matches(arg_matches, "output_format", false) {
OutputFormat::Json | OutputFormat::JsonCompact => {
(false, Some(serializer.serialize_seq(None).unwrap()))
}
_ => (true, None),
};
let mut total_accounts_stats = TotalAccountsStats::default();
let rent_collector = bank.rent_collector();
let print_account_contents = !arg_matches.is_present("no_account_contents");
let print_account_data = !arg_matches.is_present("no_account_data");
let data_encoding = match arg_matches.value_of("encoding") {
Some("jsonParsed") => UiAccountEncoding::JsonParsed,
Some("base64") => UiAccountEncoding::Base64,
Some("base64+zstd") => UiAccountEncoding::Base64Zstd,
_ => UiAccountEncoding::Base64,
};
let cli_account_new_config = CliAccountNewConfig {
data_encoding,
..CliAccountNewConfig::default()
};
let scan_func = |some_account_tuple: Option<(&Pubkey, AccountSharedData, Slot)>| {
if let Some((pubkey, account, slot)) = some_account_tuple
.filter(|(_, account, _)| Accounts::is_loadable(account.lamports()))
{
if !include_sysvars && solana_sdk::sysvar::is_sysvar_id(pubkey) {
return;
}

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);
total_accounts_stats.accumulate_account(pubkey, &account, rent_collector);

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 print_encoding_format = match arg_matches.value_of("encoding") {
Some("jsonParsed") => UiAccountEncoding::JsonParsed,
Some("base64") => UiAccountEncoding::Base64,
Some("base64+zstd") => UiAccountEncoding::Base64Zstd,
_ => UiAccountEncoding::Base64,
};
let mut measure = Measure::start("printing account contents");
for (pubkey, (account, slot)) in accounts.into_iter() {
output_account(
&pubkey,
&account,
Some(slot),
print_account_data,
print_encoding_format,
);
if print_account_contents {
if let Some(json_serializer) = json_serializer.as_mut() {
let cli_account = CliAccount::new_with_config(
pubkey,
&account,
&cli_account_new_config,
);
json_serializer.serialize_element(&cli_account).unwrap();
} else {
output_account(
pubkey,
&account,
Some(slot),
print_account_data,
data_encoding,
);
}
}
}
measure.stop();
info!("{}", measure);
};
let mut measure = Measure::start("scanning accounts");
bank.scan_all_accounts_with_modified_slots(scan_func)
.unwrap();
measure.stop();
info!("{}", measure);
if let Some(json_serializer) = json_serializer {
json_serializer.end().unwrap();
}
if summarize {
println!("\n{:#?}", total_accounts_stats);
}

println!("{:#?}", total_accounts_stats);
}
("capitalization", Some(arg_matches)) => {
let halt_at_slot = value_t!(arg_matches, "halt_at_slot", Slot).ok();
Expand Down
15 changes: 14 additions & 1 deletion runtime/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ impl Accounts {
}
}

fn is_loadable(lamports: u64) -> bool {
pub fn is_loadable(lamports: u64) -> bool {
// Don't ever load zero lamport accounts into runtime because
// the existence of zero-lamport accounts are never deterministic!!
lamports > 0
Expand Down Expand Up @@ -1018,6 +1018,19 @@ impl Accounts {
.map(|_| collector)
}

pub fn scan_all<F>(
&self,
ancestors: &Ancestors,
bank_id: BankId,
scan_func: F,
) -> ScanResult<()>
where
F: FnMut(Option<(&Pubkey, AccountSharedData, Slot)>),
{
self.accounts_db
.scan_accounts(ancestors, bank_id, scan_func, &ScanConfig::default())
}

pub fn hold_range_in_memory<R>(
&self,
range: &R,
Expand Down
9 changes: 9 additions & 0 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6543,6 +6543,15 @@ impl Bank {
self.rc.accounts.load_all(&self.ancestors, self.bank_id)
}

pub fn scan_all_accounts_with_modified_slots<F>(&self, scan_func: F) -> ScanResult<()>
where
F: FnMut(Option<(&Pubkey, AccountSharedData, Slot)>),
{
self.rc
.accounts
.scan_all(&self.ancestors, self.bank_id, scan_func)
}

pub fn get_program_accounts_modified_since_parent(
&self,
program_id: &Pubkey,
Expand Down