diff --git a/core/src/accounts_hash_verifier.rs b/core/src/accounts_hash_verifier.rs index 03ff4ef319..e4ce5269e3 100644 --- a/core/src/accounts_hash_verifier.rs +++ b/core/src/accounts_hash_verifier.rs @@ -387,7 +387,7 @@ impl AccountsHashVerifier { return; } - let snapshot_package = SnapshotPackage::new(accounts_package, accounts_hash); + let snapshot_package = SnapshotPackage::new(accounts_package, accounts_hash.into()); let pending_snapshot_package = pending_snapshot_package.unwrap(); // If the snapshot package is an Incremental Snapshot, do not submit it if there's already diff --git a/core/tests/snapshots.rs b/core/tests/snapshots.rs index f10aefc578..3ee2c2504a 100644 --- a/core/tests/snapshots.rs +++ b/core/tests/snapshots.rs @@ -284,7 +284,7 @@ fn run_bank_forks_snapshot_n( &accounts_hash, None, ); - let snapshot_package = SnapshotPackage::new(accounts_package, accounts_hash); + let snapshot_package = SnapshotPackage::new(accounts_package, accounts_hash.into()); snapshot_utils::archive_snapshot_package( &snapshot_package, &snapshot_config.full_snapshot_archives_dir, @@ -544,7 +544,7 @@ fn test_concurrent_snapshot_packaging( None, ); let snapshot_package = - SnapshotPackage::new(accounts_package, AccountsHash(Hash::default())); + SnapshotPackage::new(accounts_package, AccountsHash(Hash::default()).into()); pending_snapshot_package .lock() .unwrap() diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index 4d32c7ac75..a0b1bd2bb4 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -26,8 +26,9 @@ use { accounts_cache::{AccountsCache, CachedAccount, SlotCache}, accounts_file::AccountsFile, accounts_hash::{ - AccountsDeltaHash, AccountsHash, AccountsHasher, CalcAccountsHashConfig, - CalculateHashIntermediate, HashStats, ZeroLamportAccounts, + AccountsDeltaHash, AccountsHash, AccountsHashEnum, AccountsHasher, + CalcAccountsHashConfig, CalculateHashIntermediate, HashStats, IncrementalAccountsHash, + ZeroLamportAccounts, }, accounts_index::{ AccountIndexGetResult, AccountSecondaryIndexes, AccountsIndex, AccountsIndexConfig, @@ -7453,13 +7454,17 @@ impl AccountsDb { storages: &SortedStorages<'_>, stats: HashStats, ) -> Result<(AccountsHash, u64), BankHashVerificationError> { - self._calculate_accounts_hash_from_storages( + let (accounts_hash, capitalization) = self._calculate_accounts_hash_from_storages( config, storages, stats, CalcAccountsHashFlavor::Full, self.full_accounts_hash_cache_path.clone(), - ) + )?; + let AccountsHashEnum::Full(accounts_hash) = accounts_hash else { + panic!("calculate_accounts_hash_from_storages must return a FullAccountsHash"); + }; + Ok((accounts_hash, capitalization)) } /// Calculate the incremental accounts hash @@ -7477,15 +7482,20 @@ impl AccountsDb { storages: &SortedStorages<'_>, base_slot: Slot, stats: HashStats, - ) -> Result<(AccountsHash, /* capitalization */ u64), BankHashVerificationError> { + ) -> Result<(IncrementalAccountsHash, /* capitalization */ u64), BankHashVerificationError> + { assert!(storages.range().start > base_slot, "The storages for calculating an incremental accounts hash must all be higher than the base slot"); - self._calculate_accounts_hash_from_storages( + let (accounts_hash, capitalization) = self._calculate_accounts_hash_from_storages( config, storages, stats, CalcAccountsHashFlavor::Incremental, self.incremental_accounts_hash_cache_path.clone(), - ) + )?; + let AccountsHashEnum::Incremental(incremental_accounts_hash) = accounts_hash else { + panic!("calculate_incremental_accounts_hash must return an IncrementalAccountsHash"); + }; + Ok((incremental_accounts_hash, capitalization)) } fn _calculate_accounts_hash_from_storages( @@ -7495,19 +7505,16 @@ impl AccountsDb { mut stats: HashStats, flavor: CalcAccountsHashFlavor, accounts_hash_cache_path: PathBuf, - ) -> Result<(AccountsHash, u64), BankHashVerificationError> { + ) -> Result<(AccountsHashEnum, u64), BankHashVerificationError> { let _guard = self.active_stats.activate(ActiveStatItem::Hash); stats.oldest_root = storages.range().start; self.mark_old_slots_as_dirty(storages, config.epoch_schedule.slots_per_epoch, &mut stats); + let slot = storages.max_slot_inclusive(); let use_bg_thread_pool = config.use_bg_thread_pool; let scan_and_hash = || { - let cache_hash_data = Self::get_cache_hash_data( - accounts_hash_cache_path, - config, - storages.max_slot_inclusive(), - ); + let cache_hash_data = Self::get_cache_hash_data(accounts_hash_cache_path, config, slot); let bounds = Range { start: 0, @@ -7548,14 +7555,16 @@ impl AccountsDb { ); // turn raw data into merkle tree hashes and sum of lamports - let final_result = accounts_hasher.rest_of_hash_calculation(result, &mut stats); - info!( - "calculate_accounts_hash_from_storages: slot: {} {:?}", - storages.max_slot_inclusive(), - final_result - ); - let final_result = (AccountsHash(final_result.0), final_result.1); - Ok(final_result) + let (accounts_hash, capitalization) = + accounts_hasher.rest_of_hash_calculation(result, &mut stats); + let accounts_hash = match flavor { + CalcAccountsHashFlavor::Full => AccountsHashEnum::Full(AccountsHash(accounts_hash)), + CalcAccountsHashFlavor::Incremental => { + AccountsHashEnum::Incremental(IncrementalAccountsHash(accounts_hash)) + } + }; + info!("calculate_accounts_hash_from_storages: slot: {slot}, {accounts_hash:?}, capitalization: {capitalization}"); + Ok((accounts_hash, capitalization)) }; let result = if use_bg_thread_pool { @@ -7563,10 +7572,7 @@ impl AccountsDb { } else { scan_and_hash() }; - self.assert_safe_squashing_accounts_hash( - storages.max_slot_inclusive(), - config.epoch_schedule, - ); + self.assert_safe_squashing_accounts_hash(slot, config.epoch_schedule); stats.log(); result } @@ -18083,7 +18089,8 @@ pub mod tests { AccountsDb::hash_account(slot, account, pubkey, INCLUDE_SLOT_IN_HASH_TESTS) } }); - let expected_accounts_hash = AccountsHash(compute_merkle_root(incremental_account_hashes)); + let expected_accounts_hash = + IncrementalAccountsHash(compute_merkle_root(incremental_account_hashes)); assert_eq!(incremental_accounts_hash.0, expected_accounts_hash); } diff --git a/runtime/src/accounts_hash.rs b/runtime/src/accounts_hash.rs index d362a5e6c7..8879ca5d04 100644 --- a/runtime/src/accounts_hash.rs +++ b/runtime/src/accounts_hash.rs @@ -1109,9 +1109,38 @@ pub enum ZeroLamportAccounts { Included, } +/// Hash of accounts +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum AccountsHashEnum { + Full(AccountsHash), + Incremental(IncrementalAccountsHash), +} +impl AccountsHashEnum { + pub fn as_hash(&self) -> &Hash { + match self { + AccountsHashEnum::Full(AccountsHash(hash)) + | AccountsHashEnum::Incremental(IncrementalAccountsHash(hash)) => hash, + } + } +} +impl From for AccountsHashEnum { + fn from(accounts_hash: AccountsHash) -> Self { + AccountsHashEnum::Full(accounts_hash) + } +} +impl From for AccountsHashEnum { + fn from(incremental_accounts_hash: IncrementalAccountsHash) -> Self { + AccountsHashEnum::Incremental(incremental_accounts_hash) + } +} + /// Hash of accounts #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct AccountsHash(pub Hash); +/// Hash of accounts that includes zero-lamport accounts +/// Used with incremental snapshots +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct IncrementalAccountsHash(pub Hash); /// Hash of accounts written in a single slot #[derive(Debug, Copy, Clone, Eq, PartialEq)] diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index e8bdda6ffd..dded98acff 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -7023,7 +7023,7 @@ impl Bank { .get_accounts_hash() .expect("accounts hash is required to get snapshot hash"); let epoch_accounts_hash = self.get_epoch_accounts_hash_to_serialize(); - SnapshotHash::new(&accounts_hash, epoch_accounts_hash.as_ref()) + SnapshotHash::new(&accounts_hash.into(), epoch_accounts_hash.as_ref()) } pub fn get_thread_pool(&self) -> &ThreadPool { diff --git a/runtime/src/snapshot_hash.rs b/runtime/src/snapshot_hash.rs index 5a6dc6cc88..27053187d7 100644 --- a/runtime/src/snapshot_hash.rs +++ b/runtime/src/snapshot_hash.rs @@ -1,6 +1,6 @@ //! Helper types and functions for handling and dealing with snapshot hashes. use { - crate::{accounts_hash::AccountsHash, epoch_accounts_hash::EpochAccountsHash}, + crate::{accounts_hash::AccountsHashEnum, epoch_accounts_hash::EpochAccountsHash}, solana_sdk::{ clock::Slot, hash::{Hash, Hasher}, @@ -57,14 +57,14 @@ impl SnapshotHash { /// Make a snapshot hash from an accounts hash and epoch accounts hash #[must_use] pub fn new( - accounts_hash: &AccountsHash, + accounts_hash: &AccountsHashEnum, epoch_accounts_hash: Option<&EpochAccountsHash>, ) -> Self { let snapshot_hash = match epoch_accounts_hash { - None => accounts_hash.0, + None => *accounts_hash.as_hash(), Some(epoch_accounts_hash) => { let mut hasher = Hasher::default(); - hasher.hash(accounts_hash.0.as_ref()); + hasher.hash(accounts_hash.as_hash().as_ref()); hasher.hash(epoch_accounts_hash.as_ref().as_ref()); hasher.result() } diff --git a/runtime/src/snapshot_package.rs b/runtime/src/snapshot_package.rs index 07e42d83ca..0127558d25 100644 --- a/runtime/src/snapshot_package.rs +++ b/runtime/src/snapshot_package.rs @@ -2,7 +2,7 @@ use { crate::{ accounts::Accounts, accounts_db::AccountStorageEntry, - accounts_hash::AccountsHash, + accounts_hash::{AccountsHash, AccountsHashEnum}, bank::Bank, epoch_accounts_hash::EpochAccountsHash, rent_collector::RentCollector, @@ -251,7 +251,7 @@ pub struct SnapshotPackage { } impl SnapshotPackage { - pub fn new(accounts_package: AccountsPackage, accounts_hash: AccountsHash) -> Self { + pub fn new(accounts_package: AccountsPackage, accounts_hash: AccountsHashEnum) -> Self { let AccountsPackageType::Snapshot(snapshot_type) = accounts_package.package_type else { panic!("The AccountsPackage must be of type Snapshot in order to make a SnapshotPackage!"); }; diff --git a/runtime/src/snapshot_utils.rs b/runtime/src/snapshot_utils.rs index 0d7ac2ea79..7bd59b2cbf 100644 --- a/runtime/src/snapshot_utils.rs +++ b/runtime/src/snapshot_utils.rs @@ -2571,7 +2571,7 @@ pub fn package_and_archive_full_snapshot( None, ); - let snapshot_package = SnapshotPackage::new(accounts_package, accounts_hash); + let snapshot_package = SnapshotPackage::new(accounts_package, accounts_hash.into()); archive_snapshot_package( &snapshot_package, full_snapshot_archives_dir, @@ -2625,7 +2625,7 @@ pub fn package_and_archive_incremental_snapshot( None, ); - let snapshot_package = SnapshotPackage::new(accounts_package, accounts_hash); + let snapshot_package = SnapshotPackage::new(accounts_package, accounts_hash.into()); archive_snapshot_package( &snapshot_package, full_snapshot_archives_dir,