runtime: remove inactive delegation from stakes cache

This commit is contained in:
Trent Nelson
2021-09-17 00:41:53 -06:00
parent f51ee23837
commit 7b4638aa0b
3 changed files with 50 additions and 30 deletions

View File

@ -4212,6 +4212,7 @@ impl Bank {
pubkey, pubkey,
account, account,
self.check_init_vote_data_enabled(), self.check_init_vote_data_enabled(),
self.stakes_remove_delegation_if_inactive_enabled(),
); );
} }
} }
@ -4879,6 +4880,7 @@ impl Bank {
pubkey, pubkey,
account, account,
self.check_init_vote_data_enabled(), self.check_init_vote_data_enabled(),
self.stakes_remove_delegation_if_inactive_enabled(),
) { ) {
// TODO: one of the indices is redundant. // TODO: one of the indices is redundant.
overwritten_vote_accounts.push(OverwrittenVoteAccount { overwritten_vote_accounts.push(OverwrittenVoteAccount {
@ -5128,6 +5130,11 @@ impl Bank {
.is_active(&feature_set::demote_program_write_locks::id()) .is_active(&feature_set::demote_program_write_locks::id())
} }
pub fn stakes_remove_delegation_if_inactive_enabled(&self) -> bool {
self.feature_set
.is_active(&feature_set::stakes_remove_delegation_if_inactive::id())
}
// Check if the wallclock time from bank creation to now has exceeded the allotted // Check if the wallclock time from bank creation to now has exceeded the allotted
// time for transaction processing // time for transaction processing
pub fn should_bank_still_be_processing_txs( pub fn should_bank_still_be_processing_txs(

View File

@ -121,6 +121,7 @@ impl Stakes {
pubkey: &Pubkey, pubkey: &Pubkey,
account: &AccountSharedData, account: &AccountSharedData,
check_vote_init: bool, check_vote_init: bool,
remove_delegation_on_inactive: bool,
) -> Option<ArcVoteAccount> { ) -> Option<ArcVoteAccount> {
if solana_vote_program::check_id(account.owner()) { if solana_vote_program::check_id(account.owner()) {
// unconditionally remove existing at first; there is no dependent calculated state for // unconditionally remove existing at first; there is no dependent calculated state for
@ -176,7 +177,13 @@ impl Stakes {
} }
} }
if account.lamports() == 0 { let remove_delegation = if remove_delegation_on_inactive {
delegation.is_none()
} else {
account.lamports() == 0
};
if remove_delegation {
// when account is removed (lamports == 0), remove it from Stakes as well // when account is removed (lamports == 0), remove it from Stakes as well
// so that given `pubkey` can be used for any owner in the future, while not // so that given `pubkey` can be used for any owner in the future, while not
// affecting Stakes. // affecting Stakes.
@ -295,8 +302,8 @@ pub mod tests {
let ((vote_pubkey, vote_account), (stake_pubkey, mut stake_account)) = let ((vote_pubkey, vote_account), (stake_pubkey, mut stake_account)) =
create_staked_node_accounts(10); create_staked_node_accounts(10);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
let stake = stake_state::stake_from(&stake_account).unwrap(); let stake = stake_state::stake_from(&stake_account).unwrap();
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -308,7 +315,7 @@ pub mod tests {
} }
stake_account.set_lamports(42); stake_account.set_lamports(42);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
assert!(vote_accounts.get(&vote_pubkey).is_some()); assert!(vote_accounts.get(&vote_pubkey).is_some());
@ -320,7 +327,7 @@ pub mod tests {
// activate more // activate more
let (_stake_pubkey, mut stake_account) = create_stake_account(42, &vote_pubkey); let (_stake_pubkey, mut stake_account) = create_stake_account(42, &vote_pubkey);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
let stake = stake_state::stake_from(&stake_account).unwrap(); let stake = stake_state::stake_from(&stake_account).unwrap();
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -332,7 +339,7 @@ pub mod tests {
} }
stake_account.set_lamports(0); stake_account.set_lamports(0);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
assert!(vote_accounts.get(&vote_pubkey).is_some()); assert!(vote_accounts.get(&vote_pubkey).is_some());
@ -350,14 +357,14 @@ pub mod tests {
let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) = let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) =
create_staked_node_accounts(10); create_staked_node_accounts(10);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
let ((vote11_pubkey, vote11_account), (stake11_pubkey, stake11_account)) = let ((vote11_pubkey, vote11_account), (stake11_pubkey, stake11_account)) =
create_staked_node_accounts(20); create_staked_node_accounts(20);
stakes.store(&vote11_pubkey, &vote11_account, true); stakes.store(&vote11_pubkey, &vote11_account, true, true);
stakes.store(&stake11_pubkey, &stake11_account, true); stakes.store(&stake11_pubkey, &stake11_account, true, true);
let vote11_node_pubkey = VoteState::from(&vote11_account).unwrap().node_pubkey; let vote11_node_pubkey = VoteState::from(&vote11_account).unwrap().node_pubkey;
@ -374,8 +381,8 @@ pub mod tests {
let ((vote_pubkey, mut vote_account), (stake_pubkey, stake_account)) = let ((vote_pubkey, mut vote_account), (stake_pubkey, stake_account)) =
create_staked_node_accounts(10); create_staked_node_accounts(10);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -384,7 +391,7 @@ pub mod tests {
} }
vote_account.set_lamports(0); vote_account.set_lamports(0);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -392,7 +399,7 @@ pub mod tests {
} }
vote_account.set_lamports(1); vote_account.set_lamports(1);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -405,7 +412,7 @@ pub mod tests {
let mut pushed = vote_account.data().to_vec(); let mut pushed = vote_account.data().to_vec();
pushed.push(0); pushed.push(0);
vote_account.set_data(pushed); vote_account.set_data(pushed);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -416,7 +423,7 @@ pub mod tests {
let default_vote_state = VoteState::default(); let default_vote_state = VoteState::default();
let versioned = VoteStateVersions::new_current(default_vote_state); let versioned = VoteStateVersions::new_current(default_vote_state);
VoteState::to(&versioned, &mut vote_account).unwrap(); VoteState::to(&versioned, &mut vote_account).unwrap();
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -424,7 +431,7 @@ pub mod tests {
} }
vote_account.set_data(cache_data); vote_account.set_data(cache_data);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -446,11 +453,11 @@ pub mod tests {
let ((vote_pubkey2, vote_account2), (_stake_pubkey2, stake_account2)) = let ((vote_pubkey2, vote_account2), (_stake_pubkey2, stake_account2)) =
create_staked_node_accounts(10); create_staked_node_accounts(10);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
stakes.store(&vote_pubkey2, &vote_account2, true); stakes.store(&vote_pubkey2, &vote_account2, true, true);
// delegates to vote_pubkey // delegates to vote_pubkey
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
let stake = stake_state::stake_from(&stake_account).unwrap(); let stake = stake_state::stake_from(&stake_account).unwrap();
@ -466,7 +473,7 @@ pub mod tests {
} }
// delegates to vote_pubkey2 // delegates to vote_pubkey2
stakes.store(&stake_pubkey, &stake_account2, true); stakes.store(&stake_pubkey, &stake_account2, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -491,11 +498,11 @@ pub mod tests {
let (stake_pubkey2, stake_account2) = create_stake_account(10, &vote_pubkey); let (stake_pubkey2, stake_account2) = create_stake_account(10, &vote_pubkey);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
// delegates to vote_pubkey // delegates to vote_pubkey
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
stakes.store(&stake_pubkey2, &stake_account2, true); stakes.store(&stake_pubkey2, &stake_account2, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -510,8 +517,8 @@ pub mod tests {
let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) = let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) =
create_staked_node_accounts(10); create_staked_node_accounts(10);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
let stake = stake_state::stake_from(&stake_account).unwrap(); let stake = stake_state::stake_from(&stake_account).unwrap();
{ {
@ -541,8 +548,8 @@ pub mod tests {
let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) = let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) =
create_staked_node_accounts(10); create_staked_node_accounts(10);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -555,6 +562,7 @@ pub mod tests {
&stake_pubkey, &stake_pubkey,
&AccountSharedData::new(1, 0, &stake::program::id()), &AccountSharedData::new(1, 0, &stake::program::id()),
true, true,
true,
); );
{ {
let vote_accounts = stakes.vote_accounts(); let vote_accounts = stakes.vote_accounts();
@ -584,8 +592,8 @@ pub mod tests {
let genesis_epoch = 0; let genesis_epoch = 0;
let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) = let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) =
create_warming_staked_node_accounts(10, genesis_epoch); create_warming_staked_node_accounts(10, genesis_epoch);
stakes.store(&vote_pubkey, &vote_account, true); stakes.store(&vote_pubkey, &vote_account, true, true);
stakes.store(&stake_pubkey, &stake_account, true); stakes.store(&stake_pubkey, &stake_account, true, true);
assert_eq!(stakes.vote_balance_and_staked(), 11); assert_eq!(stakes.vote_balance_and_staked(), 11);
assert_eq!(stakes.vote_balance_and_warmed_staked(), 1); assert_eq!(stakes.vote_balance_and_warmed_staked(), 1);

View File

@ -207,6 +207,10 @@ pub mod reduce_required_deploy_balance {
solana_sdk::declare_id!("EBeznQDjcPG8491sFsKZYBi5S5jTVXMpAKNDJMQPS2kq"); solana_sdk::declare_id!("EBeznQDjcPG8491sFsKZYBi5S5jTVXMpAKNDJMQPS2kq");
} }
pub mod stakes_remove_delegation_if_inactive {
solana_sdk::declare_id!("HFpdDDNQjvcXnXKec697HDDsyk6tFoWS2o8fkxuhQZpL");
}
lazy_static! { lazy_static! {
/// Map of feature identifiers to user-visible description /// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [ pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
@ -259,6 +263,7 @@ lazy_static! {
(check_seed_length::id(), "Check program address seed lengths"), (check_seed_length::id(), "Check program address seed lengths"),
(fix_write_privs::id(), "fix native invoke write privileges"), (fix_write_privs::id(), "fix native invoke write privileges"),
(reduce_required_deploy_balance::id(), "reduce required payer balance for program deploys"), (reduce_required_deploy_balance::id(), "reduce required payer balance for program deploys"),
(stakes_remove_delegation_if_inactive::id(), "remove delegations from stakes cache when inactive"),
/*************** ADD NEW FEATURES HERE ***************/ /*************** ADD NEW FEATURES HERE ***************/
] ]
.iter() .iter()