From c4923d29b4e545eae97e1e39c49218620163caea Mon Sep 17 00:00:00 2001 From: "Jeff Washington (jwash)" Date: Tue, 19 Apr 2022 11:29:29 -0500 Subject: [PATCH] bank_hash_at uses rewrites (#24439) --- runtime/src/accounts.rs | 14 ++++++---- runtime/src/accounts_db.rs | 43 +++++++++++++++++++++++++++++ runtime/src/bank.rs | 5 +++- runtime/src/serde_snapshot/tests.rs | 7 +++-- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index 64efcae15..7f51ecf07 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -10,7 +10,7 @@ use { accounts_update_notifier_interface::AccountsUpdateNotifier, ancestors::Ancestors, bank::{ - Bank, NonceFull, NonceInfo, RentDebits, TransactionCheckResult, + Bank, NonceFull, NonceInfo, RentDebits, Rewrites, TransactionCheckResult, TransactionExecutionResult, }, blockhash_queue::BlockhashQueue, @@ -1031,12 +1031,14 @@ impl Accounts { } } - pub fn bank_hash_at(&self, slot: Slot) -> Hash { - self.bank_hash_info_at(slot).hash + pub fn bank_hash_at(&self, slot: Slot, rewrites: &Rewrites) -> Hash { + self.bank_hash_info_at(slot, rewrites).hash } - pub fn bank_hash_info_at(&self, slot: Slot) -> BankHashInfo { - let delta_hash = self.accounts_db.get_accounts_delta_hash(slot); + pub fn bank_hash_info_at(&self, slot: Slot, rewrites: &Rewrites) -> BankHashInfo { + let delta_hash = self + .accounts_db + .get_accounts_delta_hash_with_rewrites(slot, rewrites); let bank_hashes = self.accounts_db.bank_hashes.read().unwrap(); let mut hash_info = bank_hashes .get(&slot) @@ -2396,7 +2398,7 @@ mod tests { false, AccountShrinkThreshold::default(), ); - accounts.bank_hash_at(1); + accounts.bank_hash_at(1, &Rewrites::default()); } #[test] diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index 50b548fb4..794fcfbb4 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -38,6 +38,7 @@ use { active_stats::{ActiveStatItem, ActiveStats}, ancestors::Ancestors, append_vec::{AppendVec, StoredAccountMeta, StoredMeta, StoredMetaWriteVersion}, + bank::Rewrites, cache_hash_data::CacheHashData, contains::Contains, expected_rent_collection::ExpectedRentCollection, @@ -5992,6 +5993,13 @@ impl AccountsDb { } pub fn get_accounts_delta_hash(&self, slot: Slot) -> Hash { + self.get_accounts_delta_hash_with_rewrites(slot, &Rewrites::default()) + } + pub fn get_accounts_delta_hash_with_rewrites( + &self, + slot: Slot, + skipped_rewrites: &Rewrites, + ) -> Hash { let mut scan = Measure::start("scan"); let scan_result: ScanStorageResult<(Pubkey, Hash), DashMapVersionHash> = self @@ -6035,6 +6043,8 @@ impl AccountsDb { hashes.retain(|(pubkey, _hash)| !self.is_filler_account(pubkey)); } + Self::extend_hashes_with_skipped_rewrites(&mut hashes, skipped_rewrites); + let ret = AccountsHash::accumulate_account_hashes(hashes); accumulate.stop(); let mut uncleaned_time = Measure::start("uncleaned_index"); @@ -6054,6 +6064,18 @@ impl AccountsDb { ret } + /// add all items from 'skipped_rewrites' to 'hashes' where the pubkey doesn't already exist in 'hashes' + fn extend_hashes_with_skipped_rewrites( + hashes: &mut Vec<(Pubkey, Hash)>, + skipped_rewrites: &Rewrites, + ) { + let mut skipped_rewrites = skipped_rewrites.read().unwrap().clone(); + hashes.iter().for_each(|(key, _)| { + skipped_rewrites.remove(key); + }); + hashes.extend(skipped_rewrites.into_iter()); + } + // previous_slot_entry_was_cached = true means we just need to assert that after this update is complete // that there are no items we would have put in reclaims that are not cached fn update_index<'a, T: ReadableAccount + Sync>( @@ -13825,4 +13847,25 @@ pub mod tests { ); } } + + #[test] + fn test_extend_hashes_with_skipped_rewrites() { + let mut hashes = Vec::default(); + let rewrites = Rewrites::default(); + AccountsDb::extend_hashes_with_skipped_rewrites(&mut hashes, &rewrites); + assert!(hashes.is_empty()); + let pubkey = Pubkey::new(&[1; 32]); + let hash = Hash::new(&[2; 32]); + rewrites.write().unwrap().insert(pubkey, hash); + AccountsDb::extend_hashes_with_skipped_rewrites(&mut hashes, &rewrites); + assert_eq!(hashes, vec![(pubkey, hash)]); + // pubkey is already in hashes, will not be added a second time + AccountsDb::extend_hashes_with_skipped_rewrites(&mut hashes, &rewrites); + assert_eq!(hashes, vec![(pubkey, hash)]); + let pubkey2 = Pubkey::new(&[2; 32]); + let hash2 = Hash::new(&[3; 32]); + rewrites.write().unwrap().insert(pubkey2, hash2); + AccountsDb::extend_hashes_with_skipped_rewrites(&mut hashes, &rewrites); + assert_eq!(hashes, vec![(pubkey, hash), (pubkey2, hash2)]); + } } diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 24bf72109..607d788bc 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -5893,7 +5893,10 @@ impl Bank { /// of the delta of the ledger since the last vote and up to now fn hash_internal_state(&self) -> Hash { // If there are no accounts, return the hash of the previous state and the latest blockhash - let accounts_delta_hash = self.rc.accounts.bank_hash_info_at(self.slot()); + let accounts_delta_hash = self + .rc + .accounts + .bank_hash_info_at(self.slot(), &self.rewrites_skipped_this_slot); let mut signature_count_buf = [0u8; 8]; LittleEndian::write_u64(&mut signature_count_buf[..], self.signature_count() as u64); diff --git a/runtime/src/serde_snapshot/tests.rs b/runtime/src/serde_snapshot/tests.rs index d8cf74e8b..898a84673 100644 --- a/runtime/src/serde_snapshot/tests.rs +++ b/runtime/src/serde_snapshot/tests.rs @@ -4,7 +4,7 @@ use { crate::{ accounts::{test_utils::create_test_accounts, Accounts}, accounts_db::{get_temp_accounts_paths, AccountShrinkThreshold}, - bank::{Bank, StatusCacheRc}, + bank::{Bank, Rewrites, StatusCacheRc}, hardened_unpack::UnpackedAppendVecMap, }, bincode::serialize_into, @@ -175,7 +175,10 @@ fn test_accounts_serialize_style(serde_style: SerdeStyle) { .unwrap(), ); check_accounts(&daccounts, &pubkeys, 100); - assert_eq!(accounts.bank_hash_at(0), daccounts.bank_hash_at(0)); + assert_eq!( + accounts.bank_hash_at(0, &Rewrites::default()), + daccounts.bank_hash_at(0, &Rewrites::default()) + ); } fn test_bank_serialize_style(