diff --git a/core/src/accounts_hash_verifier.rs b/core/src/accounts_hash_verifier.rs index 4f759d8b71..4d06a3cbf9 100644 --- a/core/src/accounts_hash_verifier.rs +++ b/core/src/accounts_hash_verifier.rs @@ -9,10 +9,11 @@ use { solana_gossip::cluster_info::{ClusterInfo, MAX_SNAPSHOT_HASHES}, solana_measure::{measure::Measure, measure_us}, solana_runtime::{ - accounts_hash::{AccountsHashEnum, CalcAccountsHashConfig, HashStats}, + accounts_hash::{AccountsHash, AccountsHashEnum, CalcAccountsHashConfig, HashStats}, snapshot_config::SnapshotConfig, snapshot_package::{ self, retain_max_n_elements, AccountsPackage, AccountsPackageType, SnapshotPackage, + SnapshotType, }, sorted_storages::SortedStorages, }, @@ -55,6 +56,7 @@ impl AccountsHashVerifier { let t_accounts_hash_verifier = Builder::new() .name("solAcctHashVer".to_string()) .spawn(move || { + let mut last_full_snapshot = None; let mut hashes = vec![]; loop { if exit.load(Ordering::Relaxed) { @@ -85,6 +87,7 @@ impl AccountsHashVerifier { &exit, fault_injection_rate_slots, &snapshot_config, + &mut last_full_snapshot, )); datapoint_info!( @@ -184,8 +187,10 @@ impl AccountsHashVerifier { exit: &Arc, fault_injection_rate_slots: u64, snapshot_config: &SnapshotConfig, + last_full_snapshot: &mut Option, ) { - let accounts_hash = Self::calculate_and_verify_accounts_hash(&accounts_package); + let accounts_hash = + Self::calculate_and_verify_accounts_hash(&accounts_package, last_full_snapshot); Self::save_epoch_accounts_hash(&accounts_package, accounts_hash); @@ -209,7 +214,10 @@ impl AccountsHashVerifier { } /// returns calculated accounts hash - fn calculate_and_verify_accounts_hash(accounts_package: &AccountsPackage) -> AccountsHashEnum { + fn calculate_and_verify_accounts_hash( + accounts_package: &AccountsPackage, + last_full_snapshot: &mut Option, + ) -> AccountsHashEnum { let mut measure_hash = Measure::start("hash"); let mut sort_time = Measure::start("sort_storages"); let sorted_storages = SortedStorages::new(&accounts_package.snapshot_storages); @@ -302,6 +310,17 @@ impl AccountsHashVerifier { None, ); } + + if accounts_package.package_type + == AccountsPackageType::Snapshot(SnapshotType::FullSnapshot) + { + *last_full_snapshot = Some(FullSnapshotAccountsHashInfo { + slot: accounts_package.slot, + accounts_hash, + capitalization: lamports, + }); + } + datapoint_info!( "accounts_hash_verifier", ("calculate_hash", measure_hash.as_us(), i64), @@ -450,6 +469,16 @@ impl AccountsHashVerifier { } } +/// Soon incremental snapshots will no longer calculate a *full* accounts hash. To support correct +/// snapshot verification at load time, the incremental snapshot will need to include *this* +/// information about the full snapshot it was based on. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +struct FullSnapshotAccountsHashInfo { + slot: Slot, + accounts_hash: AccountsHash, + capitalization: u64, +} + #[cfg(test)] mod tests { use { @@ -536,6 +565,7 @@ mod tests { &exit, 0, &snapshot_config, + &mut None, ); // sleep for 1ms to create a newer timestamp for gossip entry