create-snapshot subcommad now accepts the ROOT keyword

This commit is contained in:
Michael Vines
2021-02-26 13:44:38 -08:00
parent 0b510ac9b4
commit d69f09f152
2 changed files with 110 additions and 53 deletions

View File

@ -651,24 +651,23 @@ fn hardforks_of(matches: &ArgMatches<'_>, name: &str) -> Option<Vec<Slot>> {
fn load_bank_forks( fn load_bank_forks(
arg_matches: &ArgMatches, arg_matches: &ArgMatches,
ledger_path: &Path,
genesis_config: &GenesisConfig, genesis_config: &GenesisConfig,
blockstore: &Blockstore,
process_options: ProcessOptions, process_options: ProcessOptions,
access_type: AccessType,
wal_recovery_mode: Option<BlockstoreRecoveryMode>,
snapshot_archive_path: Option<PathBuf>, snapshot_archive_path: Option<PathBuf>,
) -> bank_forks_utils::LoadResult { ) -> bank_forks_utils::LoadResult {
let blockstore = open_blockstore(&ledger_path, access_type, wal_recovery_mode); let snapshot_path = blockstore
let snapshot_path = ledger_path.join(if blockstore.is_primary_access() { .ledger_path()
"snapshot" .join(if blockstore.is_primary_access() {
} else { "snapshot"
"snapshot.ledger-tool" } else {
}); "snapshot.ledger-tool"
});
let snapshot_config = if arg_matches.is_present("no_snapshot") { let snapshot_config = if arg_matches.is_present("no_snapshot") {
None None
} else { } else {
let snapshot_package_output_path = let snapshot_package_output_path =
snapshot_archive_path.unwrap_or_else(|| ledger_path.to_path_buf()); snapshot_archive_path.unwrap_or_else(|| blockstore.ledger_path().to_path_buf());
Some(SnapshotConfig { Some(SnapshotConfig {
snapshot_interval_slots: 0, // Value doesn't matter snapshot_interval_slots: 0, // Value doesn't matter
snapshot_package_output_path, snapshot_package_output_path,
@ -686,9 +685,9 @@ fn load_bank_forks(
} }
account_paths.split(',').map(PathBuf::from).collect() account_paths.split(',').map(PathBuf::from).collect()
} else if blockstore.is_primary_access() { } else if blockstore.is_primary_access() {
vec![ledger_path.join("accounts")] vec![blockstore.ledger_path().join("accounts")]
} else { } else {
let non_primary_accounts_path = ledger_path.join("accounts.ledger-tool"); let non_primary_accounts_path = blockstore.ledger_path().join("accounts.ledger-tool");
warn!( warn!(
"Default accounts path is switched aligning with Blockstore's secondary access: {:?}", "Default accounts path is switched aligning with Blockstore's secondary access: {:?}",
non_primary_accounts_path non_primary_accounts_path
@ -1067,16 +1066,27 @@ fn main() {
Arg::with_name("snapshot_slot") Arg::with_name("snapshot_slot")
.index(1) .index(1)
.value_name("SLOT") .value_name("SLOT")
.validator(is_slot) .validator(|value| {
if value.parse::<Slot>().is_ok()
|| value == "ROOT"
{
Ok(())
} else {
Err(format!(
"Unable to parse as a number or the keyword ROOT, provided: {}",
value
))
}
})
.takes_value(true) .takes_value(true)
.help("Slot at which to create the snapshot"), .help("Slot at which to create the snapshot; accepts keyword ROOT for the highest root"),
) )
.arg( .arg(
Arg::with_name("output_directory") Arg::with_name("output_directory")
.index(2) .index(2)
.value_name("DIR") .value_name("DIR")
.takes_value(true) .takes_value(true)
.help("Output directory for the snapshot"), .help("Output directory for the snapshot [default: --ledger directory]"),
) )
.arg( .arg(
Arg::with_name("warp_slot") Arg::with_name("warp_slot")
@ -1444,13 +1454,16 @@ fn main() {
..ProcessOptions::default() ..ProcessOptions::default()
}; };
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches); let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
match load_bank_forks( let blockstore = open_blockstore(
arg_matches,
&ledger_path, &ledger_path,
&genesis_config,
process_options,
AccessType::TryPrimaryThenSecondary, AccessType::TryPrimaryThenSecondary,
wal_recovery_mode, wal_recovery_mode,
);
match load_bank_forks(
arg_matches,
&genesis_config,
&blockstore,
process_options,
snapshot_archive_path, snapshot_archive_path,
) { ) {
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => { Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
@ -1516,13 +1529,16 @@ fn main() {
..ProcessOptions::default() ..ProcessOptions::default()
}; };
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches); let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
match load_bank_forks( let blockstore = open_blockstore(
arg_matches,
&ledger_path, &ledger_path,
&genesis_config,
process_options,
AccessType::TryPrimaryThenSecondary, AccessType::TryPrimaryThenSecondary,
wal_recovery_mode, wal_recovery_mode,
);
match load_bank_forks(
arg_matches,
&genesis_config,
&blockstore,
process_options,
snapshot_archive_path, snapshot_archive_path,
) { ) {
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => { Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
@ -1679,13 +1695,16 @@ fn main() {
open_genesis_config_by(&ledger_path, arg_matches).hash() open_genesis_config_by(&ledger_path, arg_matches).hash()
); );
let (bank_forks, _, _) = load_bank_forks( let blockstore = open_blockstore(
arg_matches,
&ledger_path, &ledger_path,
&open_genesis_config_by(&ledger_path, arg_matches),
process_options,
AccessType::TryPrimaryThenSecondary, AccessType::TryPrimaryThenSecondary,
wal_recovery_mode, wal_recovery_mode,
);
let (bank_forks, _, _) = load_bank_forks(
arg_matches,
&open_genesis_config_by(&ledger_path, arg_matches),
&blockstore,
process_options,
snapshot_archive_path, snapshot_archive_path,
) )
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
@ -1708,13 +1727,16 @@ fn main() {
..ProcessOptions::default() ..ProcessOptions::default()
}; };
match load_bank_forks( let blockstore = open_blockstore(
arg_matches,
&ledger_path, &ledger_path,
&open_genesis_config_by(&ledger_path, arg_matches),
process_options,
AccessType::TryPrimaryThenSecondary, AccessType::TryPrimaryThenSecondary,
wal_recovery_mode, wal_recovery_mode,
);
match load_bank_forks(
arg_matches,
&open_genesis_config_by(&ledger_path, arg_matches),
&blockstore,
process_options,
snapshot_archive_path, snapshot_archive_path,
) { ) {
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => { Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
@ -1742,8 +1764,8 @@ fn main() {
} }
} }
("create-snapshot", Some(arg_matches)) => { ("create-snapshot", Some(arg_matches)) => {
let snapshot_slot = value_t_or_exit!(arg_matches, "snapshot_slot", Slot); let output_directory = value_t!(arg_matches, "output_directory", PathBuf)
let output_directory = value_t_or_exit!(arg_matches, "output_directory", String); .unwrap_or_else(|_| ledger_path.clone());
let mut warp_slot = value_t!(arg_matches, "warp_slot", Slot).ok(); let mut warp_slot = value_t!(arg_matches, "warp_slot", Slot).ok();
let remove_stake_accounts = arg_matches.is_present("remove_stake_accounts"); let remove_stake_accounts = arg_matches.is_present("remove_stake_accounts");
let new_hard_forks = hardforks_of(arg_matches, "hard_forks"); let new_hard_forks = hardforks_of(arg_matches, "hard_forks");
@ -1762,13 +1784,16 @@ fn main() {
value_t_or_exit!(arg_matches, "bootstrap_validator_stake_lamports", u64); value_t_or_exit!(arg_matches, "bootstrap_validator_stake_lamports", u64);
let minimum_stake_lamports = StakeState::get_rent_exempt_reserve(&rent); let minimum_stake_lamports = StakeState::get_rent_exempt_reserve(&rent);
if bootstrap_validator_stake_lamports < minimum_stake_lamports { if bootstrap_validator_stake_lamports < minimum_stake_lamports {
eprintln!("Error: insufficient --bootstrap-validator-stake-lamports. Minimum amount is {}", minimum_stake_lamports); eprintln!(
"Error: insufficient --bootstrap-validator-stake-lamports. \
Minimum amount is {}",
minimum_stake_lamports
);
exit(1); exit(1);
} }
let bootstrap_validator_pubkeys = pubkeys_of(&arg_matches, "bootstrap_validator"); let bootstrap_validator_pubkeys = pubkeys_of(&arg_matches, "bootstrap_validator");
let accounts_to_remove = let accounts_to_remove =
pubkeys_of(&arg_matches, "accounts_to_remove").unwrap_or_default(); pubkeys_of(&arg_matches, "accounts_to_remove").unwrap_or_default();
let snapshot_version = let snapshot_version =
arg_matches arg_matches
.value_of("snapshot_version") .value_of("snapshot_version")
@ -1778,20 +1803,40 @@ fn main() {
exit(1) exit(1)
}) })
}); });
let process_options = ProcessOptions {
dev_halt_at_slot: Some(snapshot_slot),
new_hard_forks,
poh_verify: false,
..ProcessOptions::default()
};
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches); let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
match load_bank_forks( let blockstore = open_blockstore(
arg_matches,
&ledger_path, &ledger_path,
&genesis_config,
process_options,
AccessType::TryPrimaryThenSecondary, AccessType::TryPrimaryThenSecondary,
wal_recovery_mode, wal_recovery_mode,
);
let snapshot_slot = if Some("ROOT") == arg_matches.value_of("snapshot_slot") {
blockstore
.rooted_slot_iterator(0)
.expect("Failed to get rooted slot iterator")
.last()
.expect("Failed to get root")
} else {
value_t_or_exit!(arg_matches, "snapshot_slot", Slot)
};
info!(
"Creating snapshot of slot {} in {}",
snapshot_slot,
output_directory.display()
);
match load_bank_forks(
arg_matches,
&genesis_config,
&blockstore,
ProcessOptions {
dev_halt_at_slot: Some(snapshot_slot),
new_hard_forks,
poh_verify: false,
..ProcessOptions::default()
},
snapshot_archive_path, snapshot_archive_path,
) { ) {
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => { Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
@ -2010,13 +2055,16 @@ fn main() {
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches); let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
let include_sysvars = arg_matches.is_present("include_sysvars"); let include_sysvars = arg_matches.is_present("include_sysvars");
let exclude_account_data = arg_matches.is_present("exclude_account_data"); let exclude_account_data = arg_matches.is_present("exclude_account_data");
match load_bank_forks( let blockstore = open_blockstore(
arg_matches,
&ledger_path, &ledger_path,
&genesis_config,
process_options,
AccessType::TryPrimaryThenSecondary, AccessType::TryPrimaryThenSecondary,
wal_recovery_mode, wal_recovery_mode,
);
match load_bank_forks(
arg_matches,
&genesis_config,
&blockstore,
process_options,
snapshot_archive_path, snapshot_archive_path,
) { ) {
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => { Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {
@ -2065,13 +2113,16 @@ fn main() {
..ProcessOptions::default() ..ProcessOptions::default()
}; };
let genesis_config = open_genesis_config_by(&ledger_path, arg_matches); let genesis_config = open_genesis_config_by(&ledger_path, arg_matches);
match load_bank_forks( let blockstore = open_blockstore(
arg_matches,
&ledger_path, &ledger_path,
&genesis_config,
process_options,
AccessType::TryPrimaryThenSecondary, AccessType::TryPrimaryThenSecondary,
wal_recovery_mode, wal_recovery_mode,
);
match load_bank_forks(
arg_matches,
&genesis_config,
&blockstore,
process_options,
snapshot_archive_path, snapshot_archive_path,
) { ) {
Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => { Ok((bank_forks, _leader_schedule_cache, _snapshot_hash)) => {

View File

@ -118,6 +118,7 @@ pub struct BlockstoreSignals {
// ledger window // ledger window
pub struct Blockstore { pub struct Blockstore {
ledger_path: PathBuf,
db: Arc<Database>, db: Arc<Database>,
meta_cf: LedgerColumn<cf::SlotMeta>, meta_cf: LedgerColumn<cf::SlotMeta>,
dead_slots_cf: LedgerColumn<cf::DeadSlots>, dead_slots_cf: LedgerColumn<cf::DeadSlots>,
@ -243,6 +244,10 @@ impl Blockstore {
self.db self.db
} }
pub fn ledger_path(&self) -> &Path {
&self.ledger_path
}
/// Opens a Ledger in directory, provides "infinite" window of shreds /// Opens a Ledger in directory, provides "infinite" window of shreds
pub fn open(ledger_path: &Path) -> Result<Blockstore> { pub fn open(ledger_path: &Path) -> Result<Blockstore> {
Self::do_open(ledger_path, AccessType::PrimaryOnly, None, true) Self::do_open(ledger_path, AccessType::PrimaryOnly, None, true)
@ -330,6 +335,7 @@ impl Blockstore {
measure.stop(); measure.stop();
info!("{:?} {}", blockstore_path, measure); info!("{:?} {}", blockstore_path, measure);
let blockstore = Blockstore { let blockstore = Blockstore {
ledger_path: ledger_path.to_path_buf(),
db, db,
meta_cf, meta_cf,
dead_slots_cf, dead_slots_cf,