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 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
6 changes: 6 additions & 0 deletions core/tests/bank_forks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ mod tests {
let tx =
system_transaction::transfer(&mint_keypair, &key1, 1, bank.last_blockhash());
assert_eq!(bank.process_transaction(&tx), Ok(()));

let key2 = Keypair::new().pubkey();
let tx =
system_transaction::transfer(&mint_keypair, &key2, 0, bank.last_blockhash());
assert_eq!(bank.process_transaction(&tx), Ok(()));

bank.freeze();
},
1,
Expand Down
87 changes: 80 additions & 7 deletions runtime/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,29 @@ impl AccountsDB {
}
}
}

let mut counts = HashMap::new();
for slot_list in accounts_index.account_maps.values() {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@ryoqun I think this should be more accurate to capture the updated count, can you take a look?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, this looks good! This's kind of reverse of my implementation. Simper, nicer :)

for (_slot, account_entry) in slot_list.read().unwrap().iter() {
*counts.entry(account_entry.id).or_insert(0) += 1;
}
}
for slot_stores in storage.0.values() {
for (id, store) in slot_stores {
if let Some(count) = counts.get(&id) {
trace!(
"id: {} setting count: {} cur: {}",
id,
count,
store.count_and_status.read().unwrap().0
);
store.count_and_status.write().unwrap().0 = *count;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This discards the original value (=deserialized from snapshot) of count of count_and_status by unconditionally overwriting it.

} else {
trace!("id: {} clearing count", id);
store.count_and_status.write().unwrap().0 = 0;
}
}
}
}
}

Expand Down Expand Up @@ -1382,7 +1405,7 @@ pub mod tests {

fn check_accounts(
accounts: &AccountsDB,
pubkeys: &Vec<Pubkey>,
pubkeys: &[Pubkey],
slot: Slot,
num: usize,
count: usize,
Expand Down Expand Up @@ -1600,39 +1623,84 @@ pub mod tests {
assert_eq!(accounts.load_slow(&ancestors, &pubkey), Some((account, 1)));
}

fn print_count_and_status(label: &'static str, accounts: &AccountsDB) {
for (_slot, slot_stores) in &accounts.storage.read().unwrap().0 {
for (id, entry) in slot_stores {
info!(
"{}: {} count_and_status: {:?}",
label,
id,
*entry.count_and_status.read().unwrap()
);
}
}
}

#[test]
fn test_accounts_db_serialize() {
solana_logger::setup();
let accounts = AccountsDB::new_single();
let mut pubkeys: Vec<Pubkey> = vec![];

// Create 100 accounts in slot 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1 +1 +1 Got really more readable! :)

create_account(&accounts, &mut pubkeys, 0, 100, 0, 0);
assert_eq!(check_storage(&accounts, 0, 100), true);
check_accounts(&accounts, &pubkeys, 0, 100, 1);

// do some updates to those accounts and re-check
modify_accounts(&accounts, &pubkeys, 0, 100, 2);
check_accounts(&accounts, &pubkeys, 0, 100, 2);
accounts.add_root(0);

let mut pubkeys1: Vec<Pubkey> = vec![];
let latest_slot = 1;

// Modify the first 10 of the slot 0 accounts as updates in slot 1
modify_accounts(&accounts, &pubkeys, latest_slot, 10, 3);

// Create 10 new accounts in slot 1
create_account(&accounts, &mut pubkeys1, latest_slot, 10, 0, 0);

// Store a lamports=0 account in slot 1
let account = Account::new(0, 0, &Account::default().owner);
accounts.store(latest_slot, &[(&pubkeys[30], &account)]);
accounts.add_root(latest_slot);
info!("added root 1");

let latest_slot = 2;
let mut pubkeys2: Vec<Pubkey> = vec![];
// Modify original slot 0 accounts in slot 2
modify_accounts(&accounts, &pubkeys, latest_slot, 20, 4);

// Create 10 new accounts in slot 2
create_account(&accounts, &mut pubkeys2, latest_slot, 10, 0, 0);

// Store a lamports=0 account in slot 2
let account = Account::new(0, 0, &Account::default().owner);
accounts.store(latest_slot, &[(&pubkeys[31], &account)]);
accounts.add_root(latest_slot);

let mut writer = Cursor::new(vec![]);
serialize_into(
&mut writer,
&AccountsDBSerialize::new(&accounts, latest_slot),
)
.unwrap();
assert!(check_storage(&accounts, 0, 100));
assert!(check_storage(&accounts, 1, 10));
assert!(check_storage(&accounts, 0, 90));
assert!(check_storage(&accounts, 1, 21));
assert!(check_storage(&accounts, 2, 31));

let buf = writer.into_inner();
let mut reader = BufReader::new(&buf[..]);
let daccounts = AccountsDB::new(None);

print_count_and_status("accounts", &accounts);

let local_paths = {
let paths = daccounts.paths.read().unwrap();
AccountsDB::format_paths(paths.to_vec())
};

let copied_accounts = TempDir::new().unwrap();
// Simulate obtaining a copy of the AppendVecs from a tarball
copy_append_vecs(&accounts, copied_accounts.path()).unwrap();
Expand All @@ -1650,16 +1718,21 @@ pub mod tests {
);

// Get the hash for the latest slot, which should be the only hash in the
// slot_hashes map on the deserializied AccountsDb
// slot_hashes map on the deserialized AccountsDb
assert_eq!(daccounts.slot_hashes.read().unwrap().len(), 1);
assert_eq!(
daccounts.slot_hashes.read().unwrap().get(&latest_slot),
accounts.slot_hashes.read().unwrap().get(&latest_slot)
);
check_accounts(&daccounts, &pubkeys, 0, 100, 2);

print_count_and_status("daccounts", &daccounts);

// Don't check the first 35 accounts which have not been modified on slot 0
check_accounts(&daccounts, &pubkeys[35..], 0, 65, 37);
check_accounts(&daccounts, &pubkeys1, 1, 10, 1);
assert!(check_storage(&daccounts, 0, 100));
assert!(check_storage(&daccounts, 1, 10));
assert!(check_storage(&daccounts, 0, 78));
assert!(check_storage(&daccounts, 1, 11));
assert!(check_storage(&daccounts, 2, 31));
}

#[test]
Expand Down
4 changes: 4 additions & 0 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3605,6 +3605,9 @@ mod tests {
bank.deposit(&key.pubkey(), 10);
assert_eq!(bank.get_balance(&key.pubkey()), 10);

let key2 = Keypair::new();
bank.deposit(&key2.pubkey(), 0);

let len = serialized_size(&bank).unwrap() + serialized_size(&bank.rc).unwrap();
let mut buf = vec![0u8; len as usize];
let mut writer = Cursor::new(&mut buf[..]);
Expand All @@ -3629,6 +3632,7 @@ mod tests {
.accounts_from_stream(&mut reader, dbank_paths, copied_accounts.path())
.unwrap();
assert_eq!(dbank.get_balance(&key.pubkey()), 10);
assert_eq!(dbank.get_balance(&key2.pubkey()), 0);
bank.compare_bank(&dbank);
}

Expand Down