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

bank_from_latest_snapshot_dir #31115

Merged
120 changes: 120 additions & 0 deletions runtime/src/snapshot_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1722,6 +1722,60 @@ pub fn bank_from_snapshot_dir(
Ok((bank, timings))
}

/// follow the prototype of fn bank_from_latest_snapshot_archives, implement the from_dir case
#[allow(clippy::too_many_arguments)]
pub fn bank_from_latest_snapshot_dir(
bank_snapshots_dir: impl AsRef<Path>,
genesis_config: &GenesisConfig,
runtime_config: &RuntimeConfig,
account_paths: &[PathBuf],
debug_keys: Option<Arc<HashSet<Pubkey>>>,
additional_builtins: Option<&Builtins>,
account_secondary_indexes: AccountSecondaryIndexes,
limit_load_slot_count_from_snapshot: Option<usize>,
shrink_ratio: AccountShrinkThreshold,
verify_index: bool,
accounts_db_config: Option<AccountsDbConfig>,
accounts_update_notifier: Option<AccountsUpdateNotifier>,
exit: &Arc<AtomicBool>,
) -> Result<Bank> {
info!("Loading bank from snapshot dir");
let bank_snapshot = get_highest_bank_snapshot_post(&bank_snapshots_dir).ok_or_else(|| {
SnapshotError::NoSnapshotSlotDir(bank_snapshots_dir.as_ref().to_path_buf())
})?;

let (bank, timings) = bank_from_snapshot_dir(
account_paths,
&bank_snapshot,
genesis_config,
runtime_config,
debug_keys,
additional_builtins,
account_secondary_indexes,
limit_load_slot_count_from_snapshot,
shrink_ratio,
verify_index,
accounts_db_config,
accounts_update_notifier,
exit,
)?;

datapoint_info!(
"bank_from_snapshot_dir",
(
"build_storage_from_snapshot_dir_us",
timings.build_storage_us,
i64
),
(
"rebuild_bank_from_snapshot_us",
timings.rebuild_bank_from_snapshot_us,
i64
),
);
Ok(bank)
}

/// Check to make sure the deserialized bank's slot and hash matches the snapshot archive's slot
/// and hash
fn verify_bank_against_expected_slot_hash(
Expand Down Expand Up @@ -5469,4 +5523,70 @@ mod tests {
let next_id = bank.accounts().accounts_db.next_id.load(Ordering::Relaxed) as usize;
assert_eq!(max_id, next_id - 1);
}

#[test]
fn test_bank_from_latest_snapshot_dir() {
solana_logger::setup();
let genesis_config = GenesisConfig::default();
let mut bank = Arc::new(Bank::new_for_tests(&genesis_config));

let tmp_dir = tempfile::TempDir::new().unwrap();
let bank_snapshots_dir = tmp_dir.path();
let collecter_id = Pubkey::new_unique();
let snapshot_version = SnapshotVersion::default();

for _ in 0..3 {
// prepare the bank
bank = Arc::new(Bank::new_from_parent(&bank, &collecter_id, bank.slot() + 1));
bank.fill_bank_with_ticks_for_tests();
bank.squash();
bank.force_flush_accounts_cache();

// generate the bank snapshot directory for slot+1
let snapshot_storages = bank.get_snapshot_storages(None);
let slot_deltas = bank.status_cache.read().unwrap().root_slot_deltas();
add_bank_snapshot(
bank_snapshots_dir,
&bank,
&snapshot_storages,
snapshot_version,
slot_deltas,
)
.unwrap();
// Reserialize the snapshot dir to convert it from PRE to POST, because only the POST type can be used
// to construct a bank.
assert!(
crate::serde_snapshot::reserialize_bank_with_new_accounts_hash(
bank_snapshots_dir,
bank.slot(),
&AccountsHash(Hash::new_unique()),
None
)
);
}

let account_paths = &bank.rc.accounts.accounts_db.paths;

let deserialized_bank = bank_from_latest_snapshot_dir(
brooksprumo marked this conversation as resolved.
Show resolved Hide resolved
bank_snapshots_dir,
&genesis_config,
&RuntimeConfig::default(),
account_paths,
None,
None,
AccountSecondaryIndexes::default(),
None,
AccountShrinkThreshold::default(),
false,
Some(ACCOUNTS_DB_CONFIG_FOR_TESTING),
None,
&Arc::default(),
)
.unwrap();

assert_eq!(
deserialized_bank, *bank,
"Ensure rebuilding bank from the highest snapshot dir results in the highest bank",
);
}
}