From c02373493b4faf08f2bc373cc71f6b2a112b13d0 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 9 Aug 2019 15:57:31 -0700 Subject: [PATCH] Add print-slot subcommand (#5478) automerge --- install/src/lib.rs | 1 + ledger-tool/src/main.rs | 103 ++++++++++++++++++++++++---------------- 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/install/src/lib.rs b/install/src/lib.rs index 23f13794d..4cf136d70 100644 --- a/install/src/lib.rs +++ b/install/src/lib.rs @@ -60,6 +60,7 @@ pub fn main() -> Result<(), String> { .long("config") .value_name("PATH") .takes_value(true) + .global(true) .help("Configuration file to use"); match *defaults::CONFIG_FILE { Some(ref config_file) => arg.default_value(&config_file), diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs index 536f4f53d..d5d2cff1f 100644 --- a/ledger-tool/src/main.rs +++ b/ledger-tool/src/main.rs @@ -1,7 +1,8 @@ -use clap::{crate_description, crate_name, crate_version, value_t, App, Arg, SubCommand}; +use clap::{crate_description, crate_name, crate_version, value_t_or_exit, App, Arg, SubCommand}; use solana::blocktree::Blocktree; use solana::blocktree_processor::process_blocktree; use solana_sdk::genesis_block::GenesisBlock; +use solana_sdk::timing::Slot; use std::collections::BTreeMap; use std::fs::File; use std::io::{stdout, Write}; @@ -14,6 +15,26 @@ enum LedgerOutputMethod { Print, Json, } + +fn output_slot(blocktree: &Blocktree, slot: u64, method: &LedgerOutputMethod) { + let entries = blocktree + .get_slot_entries(slot, 0, None) + .unwrap_or_else(|err| { + eprintln!("Failed to load entries for slot {}: {:?}", slot, err); + exit(1); + }); + + for entry in entries { + match method { + LedgerOutputMethod::Print => println!("{:?}", entry), + LedgerOutputMethod::Json => { + serde_json::to_writer(stdout(), &entry).expect("serialize entry"); + stdout().write_all(b",\n").expect("newline"); + } + } + } +} + fn output_ledger(blocktree: Blocktree, starting_slot: u64, method: LedgerOutputMethod) { let rooted_slot_iterator = blocktree .rooted_slot_iterator(starting_slot) @@ -38,22 +59,7 @@ fn output_ledger(blocktree: Blocktree, starting_slot: u64, method: LedgerOutputM } } - let entries = blocktree - .get_slot_entries(slot, 0, None) - .unwrap_or_else(|err| { - eprintln!("Failed to load entries for slot {}: {:?}", slot, err); - exit(1); - }); - - for entry in entries { - match method { - LedgerOutputMethod::Print => println!("{:?}", entry), - LedgerOutputMethod::Json => { - serde_json::to_writer(stdout(), &entry).expect("serialize entry"); - stdout().write_all(b",\n").expect("newline"); - } - } - } + output_slot(&blocktree, slot, &method); } if method == LedgerOutputMethod::Json { @@ -64,6 +70,14 @@ fn output_ledger(blocktree: Blocktree, starting_slot: u64, method: LedgerOutputM fn main() { const DEFAULT_ROOT_COUNT: &str = "1"; solana_logger::setup(); + + let starting_slot_arg = Arg::with_name("starting_slot") + .long("starting-slot") + .value_name("NUM") + .takes_value(true) + .default_value("0") + .help("Start at this slot"); + let matches = App::new(crate_name!()) .about(crate_description!()) .version(crate_version!()) @@ -73,19 +87,19 @@ fn main() { .long("ledger") .value_name("DIR") .takes_value(true) - .required(true) + .global(true) .help("Use directory for ledger location"), ) - .arg( - Arg::with_name("starting_slot") - .long("starting-slot") - .value_name("NUM") + .subcommand(SubCommand::with_name("print").about("Print the ledger").arg(&starting_slot_arg)) + .subcommand(SubCommand::with_name("print-slot").about("Print the contents of one slot").arg( + Arg::with_name("slot") + .index(1) + .value_name("SLOT") .takes_value(true) - .default_value("0") - .help("Start at this slot (only applies to print and json commands)"), - ) - .subcommand(SubCommand::with_name("print").about("Print the ledger")) - .subcommand(SubCommand::with_name("json").about("Print the ledger in JSON format")) + .required(true) + .help("The slot to print"), + )) + .subcommand(SubCommand::with_name("json").about("Print the ledger in JSON format").arg(&starting_slot_arg)) .subcommand(SubCommand::with_name("verify").about("Verify the ledger's PoH")) .subcommand(SubCommand::with_name("prune").about("Prune the ledger at the block height").arg( Arg::with_name("slot_list") @@ -95,21 +109,22 @@ fn main() { .required(true) .help("The location of the YAML file with a list of rollback slot heights and hashes"), )) - .subcommand(SubCommand::with_name("list-roots").about("Output upto last root hashes and their heights starting at the given block height").arg( - Arg::with_name("max_height") - .long("max-height") - .value_name("NUM") - .takes_value(true) - .required(true) - .help("Maximum block height"), - ).arg( + .subcommand( + SubCommand::with_name("list-roots") + .about("Output upto last root hashes and their heights starting at the given block height") + .arg( + Arg::with_name("max_height") + .long("max-height") + .value_name("NUM") + .takes_value(true) + .required(true) + .help("Maximum block height")).arg( Arg::with_name("slot_list") .long("slot-list") .value_name("FILENAME") .required(false) .takes_value(true) - .help("The location of the output YAML file. A list of rollback slot heights and hashes will be written to the file."), - ).arg( + .help("The location of the output YAML file. A list of rollback slot heights and hashes will be written to the file.")).arg( Arg::with_name("num_roots") .long("num-roots") .value_name("NUM") @@ -120,7 +135,7 @@ fn main() { )) .get_matches(); - let ledger_path = PathBuf::from(matches.value_of("ledger").unwrap()); + let ledger_path = PathBuf::from(value_t_or_exit!(matches, "ledger", String)); let genesis_block = GenesisBlock::load(&ledger_path).unwrap_or_else(|err| { eprintln!( @@ -138,13 +153,17 @@ fn main() { } }; - let starting_slot = value_t!(matches, "starting_slot", u64).unwrap_or_else(|e| e.exit()); - match matches.subcommand() { - ("print", _) => { + ("print", Some(args_matches)) => { + let starting_slot = value_t_or_exit!(args_matches, "starting_slot", Slot); output_ledger(blocktree, starting_slot, LedgerOutputMethod::Print); } - ("json", _) => { + ("print-slot", Some(args_matches)) => { + let slot = value_t_or_exit!(args_matches, "slot", Slot); + output_slot(&blocktree, slot, &LedgerOutputMethod::Print); + } + ("json", Some(args_matches)) => { + let starting_slot = value_t_or_exit!(args_matches, "starting_slot", Slot); output_ledger(blocktree, starting_slot, LedgerOutputMethod::Json); } ("verify", _) => {