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:
carllin
2020-09-25 18:54:48 -07:00
committed by GitHub
parent e50386f928
commit 00b36e6db2
2 changed files with 55 additions and 19 deletions

View File

@@ -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 {