solana/src/bin/ledger-tool.rs

105 lines
3.4 KiB
Rust
Raw Normal View History

#[macro_use]
extern crate clap;
extern crate serde_json;
extern crate solana;
2018-08-06 16:03:08 -07:00
use clap::{App, Arg, SubCommand};
use solana::bank::Bank;
use solana::ledger::{read_ledger, verify_ledger};
2018-08-06 17:33:51 -07:00
use solana::logger;
use std::io::{stdout, Write};
2018-08-06 16:03:08 -07:00
use std::process::exit;
fn main() {
2018-08-06 17:33:51 -07:00
logger::setup();
2018-08-06 16:03:08 -07:00
let matches = App::new("ledger-tool")
.version(crate_version!())
.arg(
Arg::with_name("ledger")
.short("l")
.long("ledger")
.value_name("DIR")
.takes_value(true)
.required(true)
.help("use DIR for ledger location"),
)
.arg(
Arg::with_name("head")
.short("n")
.long("head")
.value_name("NUM")
.takes_value(true)
.help("at most the first NUM entries in ledger\n (only applies to verify, print, json commands)"),
)
2018-08-06 16:03:08 -07:00
.subcommand(SubCommand::with_name("print").about("Print the ledger"))
.subcommand(SubCommand::with_name("json").about("Print the ledger in JSON format"))
.subcommand(SubCommand::with_name("verify").about("Verify the ledger's PoH"))
.subcommand(
SubCommand::with_name("verify-internal")
.about("Verify the ledger's internal structure"),
)
.get_matches();
let ledger_path = matches.value_of("ledger").unwrap();
let entries = match read_ledger(ledger_path, true) {
2018-08-06 16:03:08 -07:00
Ok(entries) => entries,
Err(err) => {
eprintln!("Failed to open ledger at {}: {}", ledger_path, err);
2018-08-06 16:03:08 -07:00
exit(1);
}
};
let head = match matches.value_of("head") {
Some(head) => head.parse().expect("please pass a number for --head"),
None => <usize>::max_value(),
};
2018-08-06 16:03:08 -07:00
match matches.subcommand() {
("print", _) => {
2018-08-10 11:46:37 -07:00
for (i, entry) in entries.enumerate() {
if i >= head {
break;
}
let entry = entry.unwrap();
println!("{:?}", entry);
}
}
("json", _) => {
2018-08-06 16:03:08 -07:00
stdout().write_all(b"{\"ledger\":[\n").expect("open array");
2018-08-10 11:46:37 -07:00
for (i, entry) in entries.enumerate() {
if i >= head {
break;
}
2018-08-06 16:03:08 -07:00
let entry = entry.unwrap();
serde_json::to_writer(stdout(), &entry).expect("serialize");
stdout().write_all(b",\n").expect("newline");
}
stdout().write_all(b"\n]}\n").expect("close array");
}
("verify", _) => {
let bank = Bank::default();
if head != <usize>::max_value() {
let entries = entries.map(|entry| entry.unwrap()).take(head);
2018-08-10 11:46:37 -07:00
bank.process_ledger(entries).expect("process_ledger");
} else {
let entries = entries.map(|entry| entry.unwrap());
2018-08-10 11:46:37 -07:00
bank.process_ledger(entries).expect("process_ledger");
}
2018-08-06 16:03:08 -07:00
}
("verify-internal", _) => {
if let Err(e) = verify_ledger(&ledger_path, false) {
eprintln!("Error {:?} ", e);
exit(1);
} else {
println!("Ledger is valid");
}
}
2018-08-06 16:03:08 -07:00
("", _) => {
eprintln!("{}", matches.usage());
exit(1);
2018-08-06 16:03:08 -07:00
}
_ => unreachable!(),
};
}