Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surface shred version more in tools (bp #8163) #8165

Merged
merged 1 commit into from
Feb 7, 2020
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
32 changes: 4 additions & 28 deletions core/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use crate::{
tvu::{Sockets, Tvu},
};
use crossbeam_channel::unbounded;
use solana_ledger::shred::Shred;
use solana_ledger::{
bank_forks::{BankForks, SnapshotConfig},
bank_forks_utils,
Expand All @@ -28,13 +27,14 @@ use solana_ledger::{
create_new_tmp_ledger,
leader_schedule::FixedSchedule,
leader_schedule_cache::LeaderScheduleCache,
shred_version::compute_shred_version,
};
use solana_metrics::datapoint_info;
use solana_runtime::{bank::Bank, hard_forks::HardForks};
use solana_runtime::bank::Bank;
use solana_sdk::{
clock::{Slot, DEFAULT_SLOTS_PER_TURN},
genesis_config::GenesisConfig,
hash::{extend_and_hash, Hash},
hash::Hash,
poh_config::PohConfig,
pubkey::Pubkey,
signature::{Keypair, KeypairUtil},
Expand Down Expand Up @@ -193,7 +193,7 @@ impl Validator {

node.info.wallclock = timestamp();
node.info.shred_version =
compute_shred_version(&genesis_hash, &bank.hard_forks().read().unwrap());
compute_shred_version(&genesis_hash, Some(&bank.hard_forks().read().unwrap()));
Self::print_node_info(&node);

if let Some(expected_shred_version) = config.expected_shred_version {
Expand Down Expand Up @@ -471,20 +471,6 @@ impl Validator {
}
}

fn compute_shred_version(genesis_hash: &Hash, hard_forks: &HardForks) -> u16 {
use byteorder::{ByteOrder, LittleEndian};

let mut hash = *genesis_hash;
for (slot, count) in hard_forks.iter() {
let mut buf = [0u8; 16];
LittleEndian::write_u64(&mut buf[..8], *slot);
LittleEndian::write_u64(&mut buf[8..], *count as u64);
hash = extend_and_hash(&hash, &buf);
}

Shred::version_from_hash(&hash)
}

fn new_banks_from_blockstore(
expected_genesis_hash: Option<Hash>,
blockstore_path: &Path,
Expand Down Expand Up @@ -683,16 +669,6 @@ mod tests {
use crate::genesis_utils::create_genesis_config_with_leader;
use std::fs::remove_dir_all;

#[test]
fn test_compute_shred_version() {
let mut hard_forks = HardForks::default();
assert_eq!(compute_shred_version(&Hash::default(), &hard_forks), 1);
hard_forks.register(1);
assert_eq!(compute_shred_version(&Hash::default(), &hard_forks), 55551);
hard_forks.register(1);
assert_eq!(compute_shred_version(&Hash::default(), &hard_forks), 46353);
}

#[test]
fn validator_exit() {
solana_logger::setup();
Expand Down
21 changes: 17 additions & 4 deletions genesis/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use solana_clap_utils::{
input_validators::{is_rfc3339_datetime, is_valid_percentage},
};
use solana_genesis::{genesis_accounts::add_genesis_accounts, Base64Account};
use solana_ledger::{blockstore::create_new_ledger, poh::compute_hashes_per_tick};
use solana_ledger::{
blockstore::create_new_ledger, poh::compute_hashes_per_tick,
shred_version::compute_shred_version,
};
use solana_sdk::{
account::Account,
clock,
Expand Down Expand Up @@ -521,10 +524,19 @@ fn main() -> Result<(), Box<dyn error::Error>> {
create_new_ledger(&ledger_path, &genesis_config)?;

println!(
"Genesis hash: {}\nCreation time: {}\nOperating mode: {:?}\nHashes per tick: {:?}\nSlots per epoch: {}\nCapitalization: {} SOL in {} accounts",
genesis_config.hash(),
"\
Creation time: {}\n\
Operating mode: {:?}\n\
Genesis hash: {}\n\
Shred version: {}\n\
Hashes per tick: {:?}\n\
Slots per epoch: {}\n\
Capitalization: {} SOL in {} accounts\
",
Utc.timestamp(genesis_config.creation_time, 0).to_rfc3339(),
operating_mode,
genesis_config.hash(),
compute_shred_version(&genesis_config.hash(), None),
genesis_config.poh_config.hashes_per_tick,
slots_per_epoch,
lamports_to_sol(
Expand All @@ -537,7 +549,8 @@ fn main() -> Result<(), Box<dyn error::Error>> {
}
account.lamports
})
.sum::<u64>()),
.sum::<u64>()
),
genesis_config.accounts.len()
);

Expand Down
97 changes: 77 additions & 20 deletions ledger-tool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use solana_ledger::{
blockstore_db::{self, Column, Database},
blockstore_processor::{BankForksInfo, BlockstoreProcessorResult, ProcessOptions},
rooted_slot_iterator::RootedSlotIterator,
shred_version::compute_shred_version,
snapshot_utils,
};
use solana_sdk::{
Expand Down Expand Up @@ -526,6 +527,7 @@ fn hardforks_of(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<Slot>> {
fn load_bank_forks(
arg_matches: &ArgMatches,
ledger_path: &PathBuf,
genesis_config: &GenesisConfig,
process_options: ProcessOptions,
) -> BlockstoreProcessorResult {
let snapshot_config = if arg_matches.is_present("no_snapshot") {
Expand All @@ -544,7 +546,7 @@ fn load_bank_forks(
};

bank_forks_utils::load(
&open_genesis_config(&ledger_path),
&genesis_config,
&open_blockstore(&ledger_path),
account_paths,
snapshot_config.as_ref(),
Expand Down Expand Up @@ -615,9 +617,14 @@ fn main() {
)
)
.subcommand(
SubCommand::with_name("print-genesis-hash")
SubCommand::with_name("genesis-hash")
.about("Prints the ledger's genesis hash")
)
.subcommand(
SubCommand::with_name("shred-version")
.about("Prints the ledger's shred hash")
.arg(&hard_forks_arg)
)
.subcommand(
SubCommand::with_name("bounds")
.about("Print lowest and highest non-empty slots. Note that there may be empty slots within the bounds")
Expand Down Expand Up @@ -741,19 +748,49 @@ fn main() {
});

match matches.subcommand() {
("print", Some(args_matches)) => {
let starting_slot = value_t_or_exit!(args_matches, "starting_slot", Slot);
("print", Some(arg_matches)) => {
let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot);
output_ledger(
open_blockstore(&ledger_path),
starting_slot,
LedgerOutputMethod::Print,
);
}
("print-genesis-hash", Some(_args_matches)) => {
("genesis-hash", Some(_arg_matches)) => {
println!("{}", open_genesis_config(&ledger_path).hash());
}
("print-slot", Some(args_matches)) => {
let slots = values_t_or_exit!(args_matches, "slots", Slot);
("shred-version", Some(arg_matches)) => {
let genesis_config = open_genesis_config(&ledger_path);
println!("{}", genesis_config.hash());

let process_options = ProcessOptions {
dev_halt_at_slot: Some(0),
new_hard_forks: hardforks_of(arg_matches, "hard_forks"),
poh_verify: false,
..ProcessOptions::default()
};
let genesis_config = open_genesis_config(&ledger_path);
match load_bank_forks(arg_matches, &ledger_path, &genesis_config, process_options) {
Ok((bank_forks, bank_forks_info, _leader_schedule_cache)) => {
let bank_info = &bank_forks_info[0];
let bank = bank_forks[bank_info.bank_slot].clone();

println!(
"{}",
compute_shred_version(
&genesis_config.hash(),
Some(&bank.hard_forks().read().unwrap())
)
);
}
Err(err) => {
eprintln!("Failed to load ledger: {:?}", err);
exit(1);
}
}
}
("print-slot", Some(arg_matches)) => {
let slots = values_t_or_exit!(arg_matches, "slots", Slot);
for slot in slots {
println!("Slot {}", slot);
output_slot(
Expand All @@ -763,8 +800,8 @@ fn main() {
);
}
}
("json", Some(args_matches)) => {
let starting_slot = value_t_or_exit!(args_matches, "starting_slot", Slot);
("json", Some(arg_matches)) => {
let starting_slot = value_t_or_exit!(arg_matches, "starting_slot", Slot);
output_ledger(
open_blockstore(&ledger_path),
starting_slot,
Expand All @@ -778,8 +815,15 @@ fn main() {
poh_verify: !arg_matches.is_present("skip_poh_verify"),
..ProcessOptions::default()
};
println!("{}", open_genesis_config(&ledger_path).hash());

load_bank_forks(arg_matches, &ledger_path, process_options).unwrap_or_else(|err| {
load_bank_forks(
arg_matches,
&ledger_path,
&open_genesis_config(&ledger_path),
process_options,
)
.unwrap_or_else(|err| {
eprintln!("Ledger verification failed: {:?}", err);
exit(1);
});
Expand All @@ -795,7 +839,12 @@ fn main() {
..ProcessOptions::default()
};

match load_bank_forks(arg_matches, &ledger_path, process_options) {
match load_bank_forks(
arg_matches,
&ledger_path,
&open_genesis_config(&ledger_path),
process_options,
) {
Ok((bank_forks, bank_forks_info, _leader_schedule_cache)) => {
let dot = graph_forks(
&bank_forks,
Expand Down Expand Up @@ -834,7 +883,8 @@ fn main() {
poh_verify: false,
..ProcessOptions::default()
};
match load_bank_forks(arg_matches, &ledger_path, process_options) {
let genesis_config = open_genesis_config(&ledger_path);
match load_bank_forks(arg_matches, &ledger_path, &genesis_config, process_options) {
Ok((bank_forks, _bank_forks_info, _leader_schedule_cache)) => {
let bank = bank_forks.get(snapshot_slot).unwrap_or_else(|| {
eprintln!("Error: Slot {} is not available", snapshot_slot);
Expand Down Expand Up @@ -865,6 +915,13 @@ fn main() {
"Successfully created snapshot for slot {}: {:?}",
snapshot_slot, package.tar_output_file
);
println!(
"Shred version: {}",
compute_shred_version(
&genesis_config.hash(),
Some(&bank.hard_forks().read().unwrap())
)
);
ok
})
})
Expand All @@ -879,8 +936,8 @@ fn main() {
}
}
}
("prune", Some(args_matches)) => {
if let Some(prune_file_path) = args_matches.value_of("slot_list") {
("prune", Some(arg_matches)) => {
if let Some(prune_file_path) = arg_matches.value_of("slot_list") {
let blockstore = open_blockstore(&ledger_path);
let prune_file = File::open(prune_file_path.to_string()).unwrap();
let slot_hashes: BTreeMap<u64, String> =
Expand Down Expand Up @@ -916,14 +973,14 @@ fn main() {
blockstore.prune(*target_slot);
}
}
("list-roots", Some(args_matches)) => {
("list-roots", Some(arg_matches)) => {
let blockstore = open_blockstore(&ledger_path);
let max_height = if let Some(height) = args_matches.value_of("max_height") {
let max_height = if let Some(height) = arg_matches.value_of("max_height") {
usize::from_str(height).expect("Maximum height must be a number")
} else {
panic!("Maximum height must be provided");
};
let num_roots = if let Some(roots) = args_matches.value_of("num_roots") {
let num_roots = if let Some(roots) = arg_matches.value_of("num_roots") {
usize::from_str(roots).expect("Number of roots must be a number")
} else {
usize::from_str(DEFAULT_ROOT_COUNT).unwrap()
Expand All @@ -948,7 +1005,7 @@ fn main() {
.collect();

let mut output_file: Box<dyn Write> =
if let Some(path) = args_matches.value_of("slot_list") {
if let Some(path) = arg_matches.value_of("slot_list") {
match File::create(path) {
Ok(file) => Box::new(file),
_ => Box::new(stdout()),
Expand All @@ -969,10 +1026,10 @@ fn main() {
}
});
}
("bounds", Some(args_matches)) => {
("bounds", Some(arg_matches)) => {
match open_blockstore(&ledger_path).slot_meta_iterator(0) {
Ok(metas) => {
let all = args_matches.is_present("all");
let all = arg_matches.is_present("all");

println!("Collecting Ledger information...");
let slots: Vec<_> = metas.map(|(slot, _)| slot).collect();
Expand Down
1 change: 1 addition & 0 deletions ledger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod leader_schedule_utils;
pub mod poh;
pub mod rooted_slot_iterator;
pub mod shred;
pub mod shred_version;
pub mod sigverify_shreds;
pub mod snapshot_package;
pub mod snapshot_utils;
Expand Down
44 changes: 44 additions & 0 deletions ledger/src/shred_version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::shred::Shred;
use solana_runtime::hard_forks::HardForks;
use solana_sdk::hash::{extend_and_hash, Hash};

pub fn compute_shred_version(genesis_hash: &Hash, hard_forks: Option<&HardForks>) -> u16 {
use byteorder::{ByteOrder, LittleEndian};

let mut hash = *genesis_hash;
if let Some(hard_forks) = hard_forks {
for (slot, count) in hard_forks.iter() {
let mut buf = [0u8; 16];
LittleEndian::write_u64(&mut buf[..8], *slot);
LittleEndian::write_u64(&mut buf[8..], *count as u64);
hash = extend_and_hash(&hash, &buf);
}
}

Shred::version_from_hash(&hash)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_compute_shred_version() {
assert_eq!(compute_shred_version(&Hash::default(), None), 1);
let mut hard_forks = HardForks::default();
assert_eq!(
compute_shred_version(&Hash::default(), Some(&hard_forks)),
1
);
hard_forks.register(1);
assert_eq!(
compute_shred_version(&Hash::default(), Some(&hard_forks)),
55551
);
hard_forks.register(1);
assert_eq!(
compute_shred_version(&Hash::default(), Some(&hard_forks)),
46353
);
}
}