diff --git a/runtime/src/accounts_cache.rs b/runtime/src/accounts_cache.rs index 4c04da38ee..053764ef7a 100644 --- a/runtime/src/accounts_cache.rs +++ b/runtime/src/accounts_cache.rs @@ -277,6 +277,10 @@ impl AccountsCache { } } + pub fn contains_any_slots(&self, max_slot_inclusive: Slot) -> bool { + self.cache.iter().any(|e| e.key() <= &max_slot_inclusive) + } + // Removes slots less than or equal to `max_root`. Only safe to pass in a rooted slot, // otherwise the slot removed could still be undergoing replay! pub fn remove_slots_le(&self, max_root: Slot) -> Vec<(Slot, SlotCache)> { diff --git a/runtime/src/accounts_db.rs b/runtime/src/accounts_db.rs index 94cd9a3dfe..02c0e5ec1f 100644 --- a/runtime/src/accounts_db.rs +++ b/runtime/src/accounts_db.rs @@ -7103,6 +7103,11 @@ impl AccountsDb { config: &CalcAccountsHashConfig<'_>, ) -> Result<(Hash, u64), BankHashVerificationError> { if !use_index { + if !config.use_write_cache && self.accounts_cache.contains_any_slots(slot) { + // this indicates a race condition + inc_new_counter_info!("accounts_hash_items_in_write_cache", 1); + } + let mut collect_time = Measure::start("collect"); let (combined_maps, slots) = self.get_snapshot_storages(slot, None, config.ancestors); collect_time.stop();