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

add test_shrink_ancient_overflow #29363

Merged
merged 1 commit into from
Jan 2, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
85 changes: 85 additions & 0 deletions runtime/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17398,6 +17398,83 @@ pub mod tests {
);
}

#[test]
fn test_shrink_ancient_overflow() {
solana_logger::setup();

let num_normal_slots = 2;
// build an ancient append vec at slot 'ancient_slot'
let (db, ancient_slot) = get_one_ancient_append_vec_and_others(true, num_normal_slots);

let max_slot_inclusive = ancient_slot + (num_normal_slots as Slot);
let initial_accounts = get_all_accounts(&db, ancient_slot..(max_slot_inclusive + 1));

let ancient = db
.get_storages_for_slot(ancient_slot)
.unwrap()
.first()
.unwrap()
.clone();
let initial_len = ancient.alive_bytes();
// set size of ancient to be 'full'
adjust_append_vec_len_for_tests(&ancient, ancient.accounts.capacity() as usize);

// combine 1 normal append vec into existing ancient append vec
// this will overflow the original ancient append vec because of the marking full above
db.combine_ancient_slots(
(ancient_slot..max_slot_inclusive).collect(),
CAN_RANDOMLY_SHRINK_FALSE,
);

// Restore size of ancient so we don't read garbage accounts when comparing. Now that we have created a second ancient append vec,
// This first one is happy to be quite empty.
adjust_append_vec_len_for_tests(&ancient, initial_len);

compare_all_accounts(
&initial_accounts,
&get_all_accounts(&db, ancient_slot..max_slot_inclusive),
);

// the append vec at max_slot_inclusive-1 should NOT have been removed since we created an ancient append vec there
assert!(is_ancient(
&db.get_storages_for_slot(max_slot_inclusive - 1)
.unwrap()
.first()
.unwrap()
.accounts
));

// combine normal append vec(s) into existing ancient append vec
// this will overflow the original ancient append vec because of the marking full above
db.combine_ancient_slots(
(ancient_slot..=max_slot_inclusive).collect(),
CAN_RANDOMLY_SHRINK_FALSE,
);

// now, combine the next slot into the one that was just overflow
compare_all_accounts(
&initial_accounts,
&get_all_accounts(&db, ancient_slot..(max_slot_inclusive + 1)),
);

// 2 ancients and then missing (because combined into 2nd ancient)
assert!(is_ancient(
&db.get_storages_for_slot(ancient_slot)
.unwrap()
.first()
.unwrap()
.accounts
));
assert!(is_ancient(
&db.get_storages_for_slot(max_slot_inclusive - 1)
.unwrap()
.first()
.unwrap()
.accounts
));
assert!(db.get_storages_for_slot(max_slot_inclusive).is_none());
}

#[test]
fn test_shrink_ancient() {
solana_logger::setup();
Expand Down Expand Up @@ -17910,11 +17987,19 @@ pub mod tests {
storage.alive_bytes.store(alive_bytes, Ordering::Release);
}

/// cause 'ancient' to appear to contain 'len' bytes
fn adjust_append_vec_len_for_tests(ancient: &Arc<AccountStorageEntry>, len: usize) {
assert!(is_ancient(&ancient.accounts));
ancient.accounts.set_current_len_for_tests(len);
adjust_alive_bytes(ancient, len);
}

fn make_ancient_append_vec_full(ancient: &Arc<AccountStorageEntry>) {
let vecs = vec![vec![ancient.clone()]];
for _ in 0..100 {
append_sample_data_to_storage(&vecs, &Pubkey::default(), 0);
}
// since we're not adding to the index, this is how we specify that all these accounts are alive
adjust_alive_bytes(ancient, ancient.total_bytes() as usize);
}

Expand Down
4 changes: 4 additions & 0 deletions runtime/src/append_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,10 @@ pub mod tests {
};

impl AppendVec {
pub(crate) fn set_current_len_for_tests(&self, len: usize) {
self.current_len.store(len, Ordering::Release);
}

fn append_account_test(&self, data: &(StoredMeta, AccountSharedData)) -> Option<usize> {
let slot_ignored = Slot::MAX;
let accounts = [(&data.0.pubkey, &data.1)];
Expand Down