Fix vote_accounts test

This commit is contained in:
Stephen Akridge 2019-02-28 10:29:29 -08:00 committed by sakridge
parent 217f30f9c3
commit 1c44b738fe
2 changed files with 63 additions and 21 deletions

View File

@ -246,7 +246,7 @@ impl AccountsDB {
))) )))
} }
pub fn get_vote_accounts(&self, fork: Fork) -> Vec<Account> { fn get_vote_accounts(&self, fork: Fork) -> Vec<Account> {
self.index_info self.index_info
.vote_index .vote_index
.read() .read()
@ -400,6 +400,21 @@ impl AccountsDB {
forks.is_empty() forks.is_empty()
} }
fn update_vote_cache(
&self,
account: &Account,
index: &HashMap<Pubkey, AccountMap>,
pubkey: &Pubkey,
) {
if vote_program::check_id(&account.owner) {
if index.get(pubkey).is_none() {
self.index_info.vote_index.write().unwrap().remove(pubkey);
} else {
self.index_info.vote_index.write().unwrap().insert(*pubkey);
}
}
}
fn insert_account_entry(&self, fork: Fork, id: AppendVecId, offset: u64, map: &AccountMap) { fn insert_account_entry(&self, fork: Fork, id: AppendVecId, offset: u64, map: &AccountMap) {
let mut forks = map.0.write().unwrap(); let mut forks = map.0.write().unwrap();
let stores = self.storage.read().unwrap(); let stores = self.storage.read().unwrap();
@ -419,22 +434,13 @@ impl AccountsDB {
let index = self.index_info.index.read().unwrap(); let index = self.index_info.index.read().unwrap();
let map = index.get(&pubkey).unwrap(); let map = index.get(&pubkey).unwrap();
self.remove_account_entries(&[fork], &map); self.remove_account_entries(&[fork], &map);
if vote_program::check_id(&account.owner) { self.update_vote_cache(account, &index, pubkey);
self.index_info.vote_index.write().unwrap().remove(pubkey);
}
} else { } else {
let (id, offset) = self.append_account(&account); let (id, offset) = self.append_account(&account);
if vote_program::check_id(&account.owner) {
let mut index = self.index_info.vote_index.write().unwrap();
if account.tokens == 0 {
index.remove(pubkey);
} else {
index.insert(*pubkey);
}
}
let index = self.index_info.index.read().unwrap(); let index = self.index_info.index.read().unwrap();
self.update_vote_cache(account, &index, pubkey);
let map = index.get(&pubkey).unwrap(); let map = index.get(&pubkey).unwrap();
self.insert_account_entry(fork, id, offset, &map); self.insert_account_entry(fork, id, offset, &map);
} }
@ -680,9 +686,7 @@ impl AccountsDB {
if self.remove_account_entries(&[fork], &map) { if self.remove_account_entries(&[fork], &map) {
keys.push(pubkey.clone()); keys.push(pubkey.clone());
} }
if vote_program::check_id(&account.owner) { self.update_vote_cache(&account, &index, pubkey);
self.index_info.vote_index.write().unwrap().remove(pubkey);
}
} }
} }
} }
@ -881,6 +885,14 @@ impl Accounts {
assert!(!self.account_locks.lock().unwrap().contains_key(&fork)); assert!(!self.account_locks.lock().unwrap().contains_key(&fork));
self.accounts_db.squash(fork); self.accounts_db.squash(fork);
} }
pub fn get_vote_accounts(&self, fork: Fork) -> Vec<Account> {
self.accounts_db
.get_vote_accounts(fork)
.into_iter()
.filter(|acc| acc.tokens != 0)
.collect()
}
} }
#[cfg(test)] #[cfg(test)]
@ -1554,6 +1566,37 @@ mod tests {
cleanup_dirs(&paths); cleanup_dirs(&paths);
} }
#[test]
fn test_accounts_vote_filter() {
solana_logger::setup();
let accounts = Accounts::new(0, None);
let mut vote_account = Account::new(1, 0, vote_program::id());
let key = Keypair::new().pubkey();
accounts.store_slow(0, &key, &vote_account);
accounts.new_from_parent(1, 0);
assert_eq!(accounts.get_vote_accounts(1).len(), 1);
vote_account.tokens = 0;
accounts.store_slow(1, &key, &vote_account);
assert_eq!(accounts.get_vote_accounts(1).len(), 0);
let mut vote_account1 = Account::new(2, 0, vote_program::id());
let key1 = Keypair::new().pubkey();
accounts.store_slow(1, &key1, &vote_account1);
accounts.squash(1);
assert_eq!(accounts.get_vote_accounts(0).len(), 1);
assert_eq!(accounts.get_vote_accounts(1).len(), 1);
vote_account1.tokens = 0;
accounts.store_slow(1, &key1, &vote_account1);
assert_eq!(accounts.get_vote_accounts(1).len(), 0);
}
#[test] #[test]
fn test_account_vote() { fn test_account_vote() {
let paths = "vote0".to_string(); let paths = "vote0".to_string();
@ -1577,14 +1620,14 @@ mod tests {
accounts_db.get_vote_accounts(0) accounts_db.get_vote_accounts(0)
); );
// should delete it from 1 // should store a tokens=0 account in 1
lastaccount.tokens = 0; lastaccount.tokens = 0;
accounts_db.store(1, &lastkey, &lastaccount); accounts_db.store(1, &lastkey, &lastaccount);
assert_eq!(accounts_db.get_vote_accounts(1).len(), 6); // len == 7 because tokens=0 accounts are filtered at the Accounts interface.
assert_eq!(accounts_db.get_vote_accounts(1).len(), 7);
// should still be in 0 // should still be in 0
// TODO: uncomment me, issue #2994 assert_eq!(accounts_db.get_vote_accounts(0).len(), 7);
// assert_eq!(accounts_db.get_vote_accounts(0).len(), 7);
// delete it from 0 // delete it from 0
accounts_db.store(0, &lastkey, &lastaccount); accounts_db.store(0, &lastkey, &lastaccount);

View File

@ -722,7 +722,6 @@ impl Bank {
F: Fn(&VoteState) -> bool, F: Fn(&VoteState) -> bool,
{ {
self.accounts() self.accounts()
.accounts_db
.get_vote_accounts(self.id) .get_vote_accounts(self.id)
.iter() .iter()
.filter_map(|account| { .filter_map(|account| {