From 572c0af6999d0af2aa701fe11ebc6ebf6322183f Mon Sep 17 00:00:00 2001 From: Trent Nelson Date: Fri, 17 Sep 2021 00:41:53 -0600 Subject: [PATCH] runtime: remove inactive delegation from stakes cache --- runtime/src/bank.rs | 7 +++++ runtime/src/stakes.rs | 68 +++++++++++++++++++++++------------------- sdk/src/feature_set.rs | 5 ++++ 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index d6d6f0e4db4ac2..f3005dc6ede895 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -4061,6 +4061,7 @@ impl Bank { account, self.stake_program_v2_enabled(), self.check_init_vote_data_enabled(), + self.stakes_remove_delegation_if_inactive_enabled(), ); } } @@ -4640,6 +4641,7 @@ impl Bank { account, self.stake_program_v2_enabled(), self.check_init_vote_data_enabled(), + self.stakes_remove_delegation_if_inactive_enabled(), ) { // TODO: one of the indices is redundant. overwritten_vote_accounts.push(OverwrittenVoteAccount { @@ -4881,6 +4883,11 @@ impl Bank { .is_active(&feature_set::merge_nonce_error_into_system_error::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 // time for transaction processing pub fn should_bank_still_be_processing_txs( diff --git a/runtime/src/stakes.rs b/runtime/src/stakes.rs index fcb39a5b0c08d9..6fda4ecb788a30 100644 --- a/runtime/src/stakes.rs +++ b/runtime/src/stakes.rs @@ -121,6 +121,7 @@ impl Stakes { account: &AccountSharedData, fix_stake_deactivate: bool, check_vote_init: bool, + remove_delegation_on_inactive: bool, ) -> Option { if solana_vote_program::check_id(&account.owner) { // unconditionally remove existing at first; there is no dependent calculated state for @@ -187,7 +188,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 // so that given `pubkey` can be used for any owner in the future, while not // affecting Stakes. @@ -306,8 +313,8 @@ pub mod tests { let ((vote_pubkey, vote_account), (stake_pubkey, mut stake_account)) = create_staked_node_accounts(10); - stakes.store(&vote_pubkey, &vote_account, true, true); - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); let stake = StakeState::stake_from(&stake_account).unwrap(); { let vote_accounts = stakes.vote_accounts(); @@ -319,7 +326,7 @@ pub mod tests { } stake_account.lamports = 42; - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); assert!(vote_accounts.get(&vote_pubkey).is_some()); @@ -331,7 +338,7 @@ pub mod tests { // activate more let (_stake_pubkey, mut stake_account) = create_stake_account(42, &vote_pubkey); - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); let stake = StakeState::stake_from(&stake_account).unwrap(); { let vote_accounts = stakes.vote_accounts(); @@ -343,7 +350,7 @@ pub mod tests { } stake_account.lamports = 0; - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); assert!(vote_accounts.get(&vote_pubkey).is_some()); @@ -361,14 +368,14 @@ pub mod tests { let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) = create_staked_node_accounts(10); - stakes.store(&vote_pubkey, &vote_account, true, true); - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); let ((vote11_pubkey, vote11_account), (stake11_pubkey, stake11_account)) = create_staked_node_accounts(20); - stakes.store(&vote11_pubkey, &vote11_account, true, true); - stakes.store(&stake11_pubkey, &stake11_account, true, true); + stakes.store(&vote11_pubkey, &vote11_account, true, true, true); + stakes.store(&stake11_pubkey, &stake11_account, true, true, true); let vote11_node_pubkey = VoteState::from(&vote11_account).unwrap().node_pubkey; @@ -385,8 +392,8 @@ pub mod tests { let ((vote_pubkey, mut vote_account), (stake_pubkey, stake_account)) = create_staked_node_accounts(10); - stakes.store(&vote_pubkey, &vote_account, true, true); - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -395,7 +402,7 @@ pub mod tests { } vote_account.lamports = 0; - stakes.store(&vote_pubkey, &vote_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -403,7 +410,7 @@ pub mod tests { } vote_account.lamports = 1; - stakes.store(&vote_pubkey, &vote_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -414,7 +421,7 @@ pub mod tests { // Vote account too big let cache_data = vote_account.data().to_vec(); vote_account.data.push(0); - stakes.store(&vote_pubkey, &vote_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -425,7 +432,7 @@ pub mod tests { let default_vote_state = VoteState::default(); let versioned = VoteStateVersions::new_current(default_vote_state); VoteState::to(&versioned, &mut vote_account).unwrap(); - stakes.store(&vote_pubkey, &vote_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -433,7 +440,7 @@ pub mod tests { } vote_account.set_data(cache_data); - stakes.store(&vote_pubkey, &vote_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -455,11 +462,11 @@ pub mod tests { let ((vote_pubkey2, vote_account2), (_stake_pubkey2, stake_account2)) = create_staked_node_accounts(10); - stakes.store(&vote_pubkey, &vote_account, true, true); - stakes.store(&vote_pubkey2, &vote_account2, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); + stakes.store(&vote_pubkey2, &vote_account2, true, true, true); // delegates to vote_pubkey - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); let stake = StakeState::stake_from(&stake_account).unwrap(); @@ -475,7 +482,7 @@ pub mod tests { } // delegates to vote_pubkey2 - stakes.store(&stake_pubkey, &stake_account2, true, true); + stakes.store(&stake_pubkey, &stake_account2, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -500,11 +507,11 @@ pub mod tests { let (stake_pubkey2, stake_account2) = create_stake_account(10, &vote_pubkey); - stakes.store(&vote_pubkey, &vote_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); // delegates to vote_pubkey - stakes.store(&stake_pubkey, &stake_account, true, true); - stakes.store(&stake_pubkey2, &stake_account2, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); + stakes.store(&stake_pubkey2, &stake_account2, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -519,8 +526,8 @@ pub mod tests { let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) = create_staked_node_accounts(10); - stakes.store(&vote_pubkey, &vote_account, true, true); - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); let stake = StakeState::stake_from(&stake_account).unwrap(); { @@ -550,8 +557,8 @@ pub mod tests { let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) = create_staked_node_accounts(10); - stakes.store(&vote_pubkey, &vote_account, true, true); - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); { let vote_accounts = stakes.vote_accounts(); @@ -565,6 +572,7 @@ pub mod tests { &AccountSharedData::new(1, 0, &solana_stake_program::id()), true, true, + true, ); { let vote_accounts = stakes.vote_accounts(); @@ -594,8 +602,8 @@ pub mod tests { let genesis_epoch = 0; let ((vote_pubkey, vote_account), (stake_pubkey, stake_account)) = create_warming_staked_node_accounts(10, genesis_epoch); - stakes.store(&vote_pubkey, &vote_account, true, true); - stakes.store(&stake_pubkey, &stake_account, true, true); + stakes.store(&vote_pubkey, &vote_account, true, true, true); + stakes.store(&stake_pubkey, &stake_account, true, true, true); assert_eq!(stakes.vote_balance_and_staked(), 11); assert_eq!(stakes.vote_balance_and_warmed_staked(), 1); diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index 56c1a57bc63612..5fe8748840cf2e 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -170,6 +170,10 @@ pub mod demote_program_write_locks { solana_sdk::declare_id!("3E3jV7v9VcdJL8iYZUMax9DiDno8j7EWUVbhm9RtShj2"); } +pub mod stakes_remove_delegation_if_inactive { + solana_sdk::declare_id!("HFpdDDNQjvcXnXKec697HDDsyk6tFoWS2o8fkxuhQZpL"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -211,6 +215,7 @@ lazy_static! { (merge_nonce_error_into_system_error::id(), "merge NonceError into SystemError"), (spl_token_v2_set_authority_fix::id(), "spl-token set_authority fix"), (demote_program_write_locks::id(), "demote program write locks to readonly #19593"), + (stakes_remove_delegation_if_inactive::id(), "remove delegations from stakes cache when inactive"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter()