Fix ref-count for multiple stores to the same pubkey in a slot, fixes zero lamport purge detection (#12462)
Co-authored-by: Carl Lin <carl@solana.com>
This commit is contained in:
@@ -159,15 +159,32 @@ impl<'a, T: 'a + Clone> AccountsIndex<T> {
|
||||
reclaims: &mut SlotList<T>,
|
||||
) -> Option<T> {
|
||||
if let Some(lock) = self.account_maps.get(pubkey) {
|
||||
let mut list = &mut lock.1.write().unwrap();
|
||||
// filter out other dirty entries
|
||||
reclaims.extend(list.iter().filter(|(f, _)| *f == slot).cloned());
|
||||
list.retain(|(f, _)| *f != slot);
|
||||
let list = &mut lock.1.write().unwrap();
|
||||
// filter out other dirty entries from the same slot
|
||||
let mut same_slot_previous_updates: Vec<(usize, (Slot, &T))> = list
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, (s, value))| {
|
||||
if *s == slot {
|
||||
Some((i, (*s, value)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
assert!(same_slot_previous_updates.len() <= 1);
|
||||
|
||||
lock.0.fetch_add(1, Ordering::Relaxed);
|
||||
if let Some((list_index, (s, previous_update_value))) = same_slot_previous_updates.pop()
|
||||
{
|
||||
reclaims.push((s, previous_update_value.clone()));
|
||||
list.remove(list_index);
|
||||
} else {
|
||||
// Only increment ref count if the account was not prevously updated in this slot
|
||||
lock.0.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
list.push((slot, account_info));
|
||||
// now, do lazy clean
|
||||
self.purge_older_root_entries(&mut list, reclaims);
|
||||
self.purge_older_root_entries(list, reclaims);
|
||||
|
||||
None
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user