Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accounts index updates, remove pubkey when dead account #7408

Merged
merged 1 commit into from
Dec 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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() {
sakridge marked this conversation as resolved.
Show resolved Hide resolved
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));
}
}