assert we haven't squashed to ancient after hash calc (#25168)

This commit is contained in:
Jeff Washington (jwash) 2022-05-12 18:26:01 -05:00 committed by GitHub
parent 8902a66b20
commit 6f1cc5a2a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 38 additions and 6 deletions

View File

@ -2004,22 +2004,34 @@ impl AccountsDb {
} }
} }
/// return 'slot' - slots_in_epoch
fn get_slot_one_epoch_prior(slot: Slot, epoch_schedule: &EpochSchedule) -> Slot {
// would like to use:
// slot.saturating_sub(epoch_schedule.get_slots_in_epoch(epoch_schedule.get_epoch(slot)))
// but there are problems with warmup and such on tests and probably test clusters.
// So, just use the maximum below (epoch_schedule.slots_per_epoch)
slot.saturating_sub(epoch_schedule.slots_per_epoch)
}
/// hash calc is completed as of 'slot' /// hash calc is completed as of 'slot'
/// so, any process that wants to take action on really old slots can now proceed up to 'slot'-slots per epoch /// so, any process that wants to take action on really old slots can now proceed up to 'completed_slot'-slots per epoch
pub fn notify_accounts_hash_calculated_complete( pub fn notify_accounts_hash_calculated_complete(
&self, &self,
completed_slot: Slot, completed_slot: Slot,
epoch_schedule: &EpochSchedule, epoch_schedule: &EpochSchedule,
) { ) {
let one_epoch_old_slot = completed_slot.saturating_sub( let one_epoch_old_slot = Self::get_slot_one_epoch_prior(completed_slot, epoch_schedule);
epoch_schedule.get_slots_in_epoch(epoch_schedule.get_epoch(completed_slot)),
);
let mut accounts_hash_complete_one_epoch_old = let mut accounts_hash_complete_one_epoch_old =
self.accounts_hash_complete_one_epoch_old.write().unwrap(); self.accounts_hash_complete_one_epoch_old.write().unwrap();
*accounts_hash_complete_one_epoch_old = *accounts_hash_complete_one_epoch_old =
std::cmp::max(*accounts_hash_complete_one_epoch_old, one_epoch_old_slot); std::cmp::max(*accounts_hash_complete_one_epoch_old, one_epoch_old_slot);
} }
/// get the slot that is one epoch older than the highest slot that has been used for hash calculation
fn get_accounts_hash_complete_one_epoch_old(&self) -> Slot {
*self.accounts_hash_complete_one_epoch_old.read().unwrap()
}
/// Collect all the uncleaned slots, up to a max slot /// Collect all the uncleaned slots, up to a max slot
/// ///
/// Search through the uncleaned Pubkeys and return all the slots, up to a maximum slot. /// Search through the uncleaned Pubkeys and return all the slots, up to a maximum slot.
@ -5339,6 +5351,8 @@ impl AccountsDb {
i64 i64
), ),
); );
self.assert_safe_squashing_accounts_hash(max_slot, config.epoch_schedule);
Ok((accumulated_hash, total_lamports)) Ok((accumulated_hash, total_lamports))
} }
@ -5888,6 +5902,19 @@ impl AccountsDb {
) )
} }
/// if we ever try to calc hash where there are squashed append vecs within the last epoch, we will fail
fn assert_safe_squashing_accounts_hash(&self, slot: Slot, epoch_schedule: &EpochSchedule) {
let previous = self.get_accounts_hash_complete_one_epoch_old();
let current = Self::get_slot_one_epoch_prior(slot, epoch_schedule);
assert!(
previous <= current,
"get_accounts_hash_complete_one_epoch_old: {}, get_slot_one_epoch_prior: {}, slot: {}",
previous,
current,
slot
);
}
// modeled after get_accounts_delta_hash // modeled after get_accounts_delta_hash
// intended to be faster than calculate_accounts_hash // intended to be faster than calculate_accounts_hash
pub fn calculate_accounts_hash_without_index( pub fn calculate_accounts_hash_without_index(
@ -5946,11 +5973,16 @@ impl AccountsDb {
); );
Ok(final_result) Ok(final_result)
}; };
if use_bg_thread_pool { let result = if use_bg_thread_pool {
self.thread_pool_clean.install(scan_and_hash) self.thread_pool_clean.install(scan_and_hash)
} else { } else {
scan_and_hash() scan_and_hash()
} };
self.assert_safe_squashing_accounts_hash(
storages.max_slot_inclusive(),
config.epoch_schedule,
);
result
} }
/// calculate oldest_slot_to_keep and alive_roots /// calculate oldest_slot_to_keep and alive_roots