checks that cached vote accounts are consistent with accounts-db (#27286)
The commit adds sanity checks that when loading a bank from snapshots: * cached vote accounts are consistent with accounts-db. * all valid vote-accounts referenced in stake delegations are already cached.
This commit is contained in:
parent
389bedda5e
commit
7fda0287cb
|
@ -8,6 +8,7 @@ use {
|
||||||
},
|
},
|
||||||
dashmap::DashMap,
|
dashmap::DashMap,
|
||||||
im::HashMap as ImHashMap,
|
im::HashMap as ImHashMap,
|
||||||
|
log::error,
|
||||||
num_derive::ToPrimitive,
|
num_derive::ToPrimitive,
|
||||||
num_traits::ToPrimitive,
|
num_traits::ToPrimitive,
|
||||||
rayon::{prelude::*, ThreadPool},
|
rayon::{prelude::*, ThreadPool},
|
||||||
|
@ -19,7 +20,7 @@ use {
|
||||||
},
|
},
|
||||||
solana_vote_program::vote_state::VoteState,
|
solana_vote_program::vote_state::VoteState,
|
||||||
std::{
|
std::{
|
||||||
collections::HashMap,
|
collections::{HashMap, HashSet},
|
||||||
ops::Add,
|
ops::Add,
|
||||||
sync::{Arc, RwLock, RwLockReadGuard},
|
sync::{Arc, RwLock, RwLockReadGuard},
|
||||||
},
|
},
|
||||||
|
@ -34,6 +35,12 @@ pub enum Error {
|
||||||
InvalidStakeAccount(#[from] stake_account::Error),
|
InvalidStakeAccount(#[from] stake_account::Error),
|
||||||
#[error("Stake account not found: {0}")]
|
#[error("Stake account not found: {0}")]
|
||||||
StakeAccountNotFound(Pubkey),
|
StakeAccountNotFound(Pubkey),
|
||||||
|
#[error("Vote account mismatch: {0}")]
|
||||||
|
VoteAccountMismatch(Pubkey),
|
||||||
|
#[error("Vote account not cached: {0}")]
|
||||||
|
VoteAccountNotCached(Pubkey),
|
||||||
|
#[error("Vote account not found: {0}")]
|
||||||
|
VoteAccountNotFound(Pubkey),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, ToPrimitive)]
|
#[derive(Debug, Clone, PartialEq, Eq, ToPrimitive)]
|
||||||
|
@ -222,6 +229,47 @@ impl Stakes<StakeAccount> {
|
||||||
Err(Error::InvalidDelegation(*pubkey))
|
Err(Error::InvalidDelegation(*pubkey))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Assert that cached vote accounts are consistent with accounts-db.
|
||||||
|
for (pubkey, vote_account) in stakes.vote_accounts.iter() {
|
||||||
|
let account = match get_account(pubkey) {
|
||||||
|
None => return Err(Error::VoteAccountNotFound(*pubkey)),
|
||||||
|
Some(account) => account,
|
||||||
|
};
|
||||||
|
// Ignoring rent_epoch until the feature for
|
||||||
|
// preserve_rent_epoch_for_rent_exempt_accounts is activated.
|
||||||
|
let vote_account = vote_account.account();
|
||||||
|
if vote_account.lamports() != account.lamports()
|
||||||
|
|| vote_account.owner() != account.owner()
|
||||||
|
|| vote_account.executable() != account.executable()
|
||||||
|
|| vote_account.data() != account.data()
|
||||||
|
{
|
||||||
|
error!(
|
||||||
|
"vote account mismatch: {}, {:?}, {:?}",
|
||||||
|
pubkey, vote_account, account
|
||||||
|
);
|
||||||
|
return Err(Error::VoteAccountMismatch(*pubkey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Assert that all valid vote-accounts referenced in
|
||||||
|
// stake delegations are already cached.
|
||||||
|
let voter_pubkeys: HashSet<Pubkey> = stakes
|
||||||
|
.stake_delegations
|
||||||
|
.values()
|
||||||
|
.map(|delegation| delegation.voter_pubkey)
|
||||||
|
.filter(|voter_pubkey| stakes.vote_accounts.get(voter_pubkey).is_none())
|
||||||
|
.collect();
|
||||||
|
for pubkey in voter_pubkeys {
|
||||||
|
let account = match get_account(&pubkey) {
|
||||||
|
None => continue,
|
||||||
|
Some(account) => account,
|
||||||
|
};
|
||||||
|
if VoteState::is_correct_size_and_initialized(account.data())
|
||||||
|
&& VoteAccount::try_from(account.clone()).is_ok()
|
||||||
|
{
|
||||||
|
error!("vote account not cached: {}, {:?}", pubkey, account);
|
||||||
|
return Err(Error::VoteAccountNotCached(pubkey));
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
vote_accounts: stakes.vote_accounts.clone(),
|
vote_accounts: stakes.vote_accounts.clone(),
|
||||||
stake_delegations: stake_delegations.collect::<Result<_, _>>()?,
|
stake_delegations: stake_delegations.collect::<Result<_, _>>()?,
|
||||||
|
|
Loading…
Reference in New Issue