Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Enable conservative out-of-bound snapshot cleaning
  • Loading branch information
ryoqun committed Mar 12, 2020
commit 4cc6cee396fde55f4301f7747d496b1ce69f735f
4 changes: 0 additions & 4 deletions runtime/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,10 +555,6 @@ impl Accounts {
.for_each(|(tx, result)| self.unlock_account(tx, result, &mut account_locks));
}

pub fn has_accounts(&self, slot: Slot) -> bool {
self.accounts_db.has_accounts(slot)
}

/// Store the accounts into the DB
pub fn store_accounts(
&self,
Expand Down
60 changes: 29 additions & 31 deletions runtime/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ impl AccountStorageEntry {
self.count_and_status.read().unwrap().0
}

pub fn has_accounts(&self) -> bool {
self.count() > 0
}

pub fn slot_id(&self) -> Slot {
self.slot_id
}
Expand Down Expand Up @@ -627,17 +631,6 @@ impl AccountsDB {
)
}

pub fn has_accounts(&self, slot: Slot) -> bool {
if let Some(storage_slots) = self.storage.read().unwrap().0.get(&slot) {
for x in storage_slots.values() {
if x.count() > 0 {
return true;
}
}
}
false
}

// Reclaim older states of rooted non-zero lamport accounts as a general
// AccountsDB bloat mitigation and preprocess for better zero-lamport purging.
fn clean_old_rooted_accounts(&self, purges_in_root: Vec<Pubkey>) {
Expand Down Expand Up @@ -1415,10 +1408,17 @@ impl AccountsDB {
r_storage
.0
.iter()
.filter(|(slot, storage)| {
**slot <= snapshot_slot && !storage.is_empty() && accounts_index.is_root(**slot)
.filter(|(slot, _slot_stores)| {
**slot <= snapshot_slot && accounts_index.is_root(**slot)
})
.map(|(_slot, slot_stores)| {
slot_stores
.values()
.filter(|x| x.has_accounts())
.cloned()
.collect()
})
.map(|(_, slot_store)| slot_store.values().cloned().collect())
.filter(|snapshot_storage: &SnapshotStorage| !snapshot_storage.is_empty())
.collect()
}

Expand Down Expand Up @@ -1494,7 +1494,7 @@ impl AccountsDB {
}
// Need to add these last, otherwise older updates will be cleaned
for slot_id in slots {
accounts_index.roots.insert(slot_id);
accounts_index.add_root(slot_id);
}

let mut counts = HashMap::new();
Expand Down Expand Up @@ -2550,12 +2550,12 @@ pub mod tests {

print_accounts("post_f", &accounts);

accounts.verify_bank_hash(4, &HashMap::default()).unwrap();

assert_load_account(&accounts, current_slot, pubkey, some_lamport);
assert_load_account(&accounts, current_slot, purged_pubkey1, 0);
assert_load_account(&accounts, current_slot, purged_pubkey2, 0);
assert_load_account(&accounts, current_slot, dummy_pubkey, dummy_lamport);

accounts.verify_bank_hash(4, &HashMap::default()).unwrap();
}

#[test]
Expand Down Expand Up @@ -2965,10 +2965,9 @@ pub mod tests {
}

#[test]
fn test_accounts_purge_chained_purge_after_snapshot_restore_complex() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understood this mystical test finally...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fn test_accounts_purge_long_chained_after_snapshot_restore() {
solana_logger::setup();
let old_lamport = 223;
let latest_lamport = 777;
let zero_lamport = 0;
let no_data = 0;
let owner = Account::default().owner;
Expand All @@ -2977,24 +2976,28 @@ pub mod tests {
let account2 = Account::new(old_lamport + 100_001, no_data, &owner);
let account3 = Account::new(old_lamport + 100_002, no_data, &owner);
let dummy_account = Account::new(99999999, no_data, &owner);
let latest_account = Account::new(latest_lamport, no_data, &owner);
let zero_lamport_account = Account::new(zero_lamport, no_data, &owner);

let pubkey = Pubkey::new_rand();
let zero_lamport_pubkey = Pubkey::new_rand();
let dummy_pubkey = Pubkey::new_rand();
let purged_pubkey1 = Pubkey::new_rand();
let purged_pubkey2 = Pubkey::new_rand();

let mut current_slot = 0;
let accounts = AccountsDB::new_single();

// create intermidiate updates to purged_pubkey1 so that
// generate_index must add slots as root last at once
current_slot += 1;
accounts.store(current_slot, &[(&pubkey, &account)]);
accounts.store(
current_slot,
&[(&zero_lamport_pubkey, &zero_lamport_account)],
);
accounts.store(current_slot, &[(&purged_pubkey1, &account2)]);
accounts.add_root(current_slot);

current_slot += 1;
accounts.store(current_slot, &[(&purged_pubkey1, &account2)]);
accounts.add_root(current_slot);

current_slot += 1;
accounts.store(current_slot, &[(&purged_pubkey1, &account2)]);
accounts.add_root(current_slot);

Expand All @@ -3008,21 +3011,16 @@ pub mod tests {
accounts.add_root(current_slot);

current_slot += 1;
accounts.store(current_slot, &[(&pubkey, &latest_account)]);
accounts.store(current_slot, &[(&dummy_pubkey, &dummy_account)]);
accounts.add_root(current_slot);

current_slot += 1;
accounts.store(current_slot, &[(&pubkey, &latest_account)]);
accounts.add_root(current_slot);

print_count_and_status("before reconstruct", &accounts);
let accounts = reconstruct_accounts_db_via_serialization(&accounts, current_slot);
print_count_and_status("before purge zero", &accounts);
accounts.clean_accounts();
print_count_and_status("after purge zero", &accounts);

assert_load_account(&accounts, current_slot, pubkey, latest_lamport);
assert_load_account(&accounts, current_slot, pubkey, old_lamport);
assert_load_account(&accounts, current_slot, purged_pubkey1, 0);
assert_load_account(&accounts, current_slot, purged_pubkey2, 0);
}
Expand Down