Skip to content

Commit

Permalink
Accounts index updates, remove pubkey when dead account (#7408)
Browse files Browse the repository at this point in the history
  • Loading branch information
sakridge committed Dec 11, 2019
1 parent f526c42 commit 0aa4dc9
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 17 deletions.
34 changes: 20 additions & 14 deletions runtime/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,15 +603,27 @@ impl AccountsDB {

// Recalculate reclaims with new purge set
let mut reclaims = Vec::new();
let mut dead_keys = Vec::new();
for pubkey in purges.keys() {
reclaims.extend(accounts_index.purge(&pubkey));
let (new_reclaims, is_empty) = accounts_index.purge(&pubkey);
if is_empty {
dead_keys.push(*pubkey);
}
reclaims.extend(new_reclaims);
}

let last_root = accounts_index.last_root;

drop(accounts_index);
drop(storage);

if !dead_keys.is_empty() {
let mut accounts_index = self.accounts_index.write().unwrap();
for key in &dead_keys {
accounts_index.account_maps.remove(key);
}
}

self.handle_reclaims(&reclaims, last_root);
}

Expand Down Expand Up @@ -1916,19 +1928,13 @@ pub mod tests {
print_accounts("post_purge", &accounts);

// Make sure the index is for pubkey cleared
assert_eq!(
accounts
.accounts_index
.read()
.unwrap()
.account_maps
.get(&pubkey)
.unwrap()
.read()
.unwrap()
.len(),
0
);
assert!(accounts
.accounts_index
.read()
.unwrap()
.account_maps
.get(&pubkey)
.is_none());

// slot 1 & 2 should not have any stores
assert_no_stores(&accounts, 1);
Expand Down
28 changes: 25 additions & 3 deletions runtime/src/accounts_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ impl<T: Clone> AccountsIndex<T> {
self.get_rooted_entries(&list)
}

pub fn purge(&self, pubkey: &Pubkey) -> Vec<(Slot, T)> {
// filter any rooted entries and return them along with a bool that indicates
// if this account has no more entries.
pub fn purge(&self, pubkey: &Pubkey) -> (Vec<(Slot, T)>, bool) {
let mut list = self.account_maps.get(&pubkey).unwrap().write().unwrap();
let reclaims = self.get_rooted_entries(&list);
list.retain(|(slot, _)| !self.is_root(*slot));
reclaims
(reclaims, list.is_empty())
}

// find the latest slot and T in a list for a given ancestor
Expand Down Expand Up @@ -133,7 +135,6 @@ impl<T: Clone> AccountsIndex<T> {
.cloned(),
);
slot_vec.retain(|(slot, _)| !Self::can_purge(max_root, *slot));

None
} else {
Some(account_info)
Expand Down Expand Up @@ -382,4 +383,25 @@ mod tests {
assert_eq!(num, 1);
assert!(found_key);
}

#[test]
fn test_purge() {
let key = Keypair::new();
let mut index = AccountsIndex::<u64>::default();
let mut gc = Vec::new();
assert_eq!(Some(12), index.update(1, &key.pubkey(), 12, &mut gc));

index.insert(1, &key.pubkey(), 12, &mut gc);

assert_eq!(None, index.update(1, &key.pubkey(), 10, &mut gc));

let purges = index.purge(&key.pubkey());
assert_eq!(purges, (vec![], false));
index.add_root(1);

let purges = index.purge(&key.pubkey());
assert_eq!(purges, (vec![(1, 10)], true));

assert_eq!(None, index.update(1, &key.pubkey(), 9, &mut gc));
}
}

0 comments on commit 0aa4dc9

Please sign in to comment.