Co-authored-by: Carl Lin <carl@solana.com>
(cherry picked from commit 955b99cf69
)
Co-authored-by: carllin <wumu727@gmail.com>
This commit is contained in:
@ -750,7 +750,8 @@ impl AccountsDB {
|
|||||||
if account_info.lamports == 0 {
|
if account_info.lamports == 0 {
|
||||||
purges.insert(
|
purges.insert(
|
||||||
*pubkey,
|
*pubkey,
|
||||||
self.accounts_index.roots_and_ref_count(&locked_entry),
|
self.accounts_index
|
||||||
|
.roots_and_ref_count(&locked_entry, max_clean_root),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4937,11 +4938,11 @@ pub mod tests {
|
|||||||
accounts_index.add_root(3);
|
accounts_index.add_root(3);
|
||||||
let mut purges = HashMap::new();
|
let mut purges = HashMap::new();
|
||||||
let (key0_entry, _) = accounts_index.get(&key0, None, None).unwrap();
|
let (key0_entry, _) = accounts_index.get(&key0, None, None).unwrap();
|
||||||
purges.insert(key0, accounts_index.roots_and_ref_count(&key0_entry));
|
purges.insert(key0, accounts_index.roots_and_ref_count(&key0_entry, None));
|
||||||
let (key1_entry, _) = accounts_index.get(&key1, None, None).unwrap();
|
let (key1_entry, _) = accounts_index.get(&key1, None, None).unwrap();
|
||||||
purges.insert(key1, accounts_index.roots_and_ref_count(&key1_entry));
|
purges.insert(key1, accounts_index.roots_and_ref_count(&key1_entry, None));
|
||||||
let (key2_entry, _) = accounts_index.get(&key2, None, None).unwrap();
|
let (key2_entry, _) = accounts_index.get(&key2, None, None).unwrap();
|
||||||
purges.insert(key2, accounts_index.roots_and_ref_count(&key2_entry));
|
purges.insert(key2, accounts_index.roots_and_ref_count(&key2_entry, None));
|
||||||
for (key, (list, ref_count)) in &purges {
|
for (key, (list, ref_count)) in &purges {
|
||||||
info!(" purge {} ref_count {} =>", key, ref_count);
|
info!(" purge {} ref_count {} =>", key, ref_count);
|
||||||
for x in list {
|
for x in list {
|
||||||
@ -5101,4 +5102,25 @@ pub mod tests {
|
|||||||
3
|
3
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_zero_lamport_new_root_not_cleaned() {
|
||||||
|
let db = AccountsDB::new(Vec::new(), &ClusterType::Development);
|
||||||
|
let account_key = Pubkey::new_unique();
|
||||||
|
let zero_lamport_account = Account::new(0, 0, &Account::default().owner);
|
||||||
|
|
||||||
|
// Store zero lamport account into slots 0 and 1, root both slots
|
||||||
|
db.store(0, &[(&account_key, &zero_lamport_account)]);
|
||||||
|
db.store(1, &[(&account_key, &zero_lamport_account)]);
|
||||||
|
db.add_root(0);
|
||||||
|
db.add_root(1);
|
||||||
|
|
||||||
|
// Only clean zero lamport accounts up to slot 0
|
||||||
|
db.clean_accounts(Some(0));
|
||||||
|
|
||||||
|
// Should still be able to find zero lamport account in slot 1
|
||||||
|
assert_eq!(
|
||||||
|
db.load_slow(&HashMap::new(), &account_key),
|
||||||
|
Some((zero_lamport_account, 1))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,10 +464,10 @@ impl<T: 'static + Clone> AccountsIndex<T> {
|
|||||||
self.do_unchecked_scan_accounts(ancestors, func, Some(range));
|
self.do_unchecked_scan_accounts(ancestors, func, Some(range));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rooted_entries(&self, slice: SlotSlice<T>) -> SlotList<T> {
|
pub fn get_rooted_entries(&self, slice: SlotSlice<T>, max: Option<Slot>) -> SlotList<T> {
|
||||||
slice
|
slice
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(slot, _)| self.is_root(*slot))
|
.filter(|(slot, _)| self.is_root(*slot) && max.map_or(true, |max| *slot <= max))
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@ -476,9 +476,10 @@ impl<T: 'static + Clone> AccountsIndex<T> {
|
|||||||
pub fn roots_and_ref_count(
|
pub fn roots_and_ref_count(
|
||||||
&self,
|
&self,
|
||||||
locked_account_entry: &ReadAccountMapEntry<T>,
|
locked_account_entry: &ReadAccountMapEntry<T>,
|
||||||
|
max: Option<Slot>,
|
||||||
) -> (SlotList<T>, RefCount) {
|
) -> (SlotList<T>, RefCount) {
|
||||||
(
|
(
|
||||||
self.get_rooted_entries(&locked_account_entry.slot_list()),
|
self.get_rooted_entries(&locked_account_entry.slot_list(), max),
|
||||||
locked_account_entry.ref_count().load(Ordering::Relaxed),
|
locked_account_entry.ref_count().load(Ordering::Relaxed),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -488,7 +489,7 @@ impl<T: 'static + Clone> AccountsIndex<T> {
|
|||||||
pub fn purge(&self, pubkey: &Pubkey) -> (SlotList<T>, bool) {
|
pub fn purge(&self, pubkey: &Pubkey) -> (SlotList<T>, bool) {
|
||||||
let mut write_account_map_entry = self.get_account_write_entry(pubkey).unwrap();
|
let mut write_account_map_entry = self.get_account_write_entry(pubkey).unwrap();
|
||||||
write_account_map_entry.slot_list_mut(|slot_list| {
|
write_account_map_entry.slot_list_mut(|slot_list| {
|
||||||
let reclaims = self.get_rooted_entries(slot_list);
|
let reclaims = self.get_rooted_entries(slot_list, None);
|
||||||
slot_list.retain(|(slot, _)| !self.is_root(*slot));
|
slot_list.retain(|(slot, _)| !self.is_root(*slot));
|
||||||
(reclaims, slot_list.is_empty())
|
(reclaims, slot_list.is_empty())
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user