From 3853b5d53659e97948847b929e4978cac6982293 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:38:47 -0400 Subject: [PATCH] v2.0: replay: do not refresh votes for hot spare validators (backport of #2770) (#2779) replay: do not refresh votes for hot spare validators (#2770) (cherry picked from commit 726a14f0f270d45c314f47575d4fe982ef03f070) Co-authored-by: Ashwin Sekar --- core/src/consensus.rs | 6 ++++++ core/src/replay_stage.rs | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/core/src/consensus.rs b/core/src/consensus.rs index cd1201429fec11..e16fe2a4439924 100644 --- a/core/src/consensus.rs +++ b/core/src/consensus.rs @@ -230,6 +230,8 @@ pub(crate) enum BlockhashStatus { Uninitialized, /// Non voting validator NonVoting, + /// Hot spare validator + HotSpare, /// Successfully generated vote tx with blockhash Blockhash(Hash), } @@ -587,6 +589,10 @@ impl Tower { self.last_vote_tx_blockhash = BlockhashStatus::NonVoting; } + pub(crate) fn mark_last_vote_tx_blockhash_hot_spare(&mut self) { + self.last_vote_tx_blockhash = BlockhashStatus::HotSpare; + } + pub fn last_voted_slot_in_bank(bank: &Bank, vote_account_pubkey: &Pubkey) -> Option { let vote_account = bank.get_vote_account(vote_account_pubkey)?; let vote_state = vote_account.vote_state(); diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs index 05d593c7a1c416..d9cbd0d5633fe9 100644 --- a/core/src/replay_stage.rs +++ b/core/src/replay_stage.rs @@ -135,7 +135,11 @@ enum ConfirmationType { enum GenerateVoteTxResult { // non voting validator, not eligible for refresh + // until authorized keypair is overriden NonVoting, + // hot spare validator, not eligble for refresh + // until set identity is invoked + HotSpare, // failed generation, eligible for refresh Failed, Tx(Transaction), @@ -145,6 +149,10 @@ impl GenerateVoteTxResult { fn is_non_voting(&self) -> bool { matches!(self, Self::NonVoting) } + + fn is_hot_spare(&self) -> bool { + matches!(self, Self::HotSpare) + } } #[derive(PartialEq, Eq, Debug)] @@ -2532,7 +2540,7 @@ impl ReplayStage { vote_state.node_pubkey, node_keypair.pubkey() ); - return GenerateVoteTxResult::Failed; + return GenerateVoteTxResult::HotSpare; } let Some(authorized_voter_pubkey) = vote_state.get_authorized_voter(bank.epoch()) else { @@ -2627,9 +2635,9 @@ impl ReplayStage { // If we are a non voting validator or have an incorrect setup preventing us from // generating vote txs, no need to refresh let last_vote_tx_blockhash = match tower.last_vote_tx_blockhash() { - // Since the checks in vote generation are deterministic, if we were non voting + // Since the checks in vote generation are deterministic, if we were non voting or hot spare // on the original vote, the refresh will also fail. No reason to refresh. - BlockhashStatus::NonVoting => return, + BlockhashStatus::NonVoting | BlockhashStatus::HotSpare => return, // In this case we have not voted since restart, it is unclear if we are non voting. // Attempt to refresh. BlockhashStatus::Uninitialized => None, @@ -2692,6 +2700,8 @@ impl ReplayStage { last_vote_refresh_time.last_refresh_time = Instant::now(); } else if vote_tx_result.is_non_voting() { tower.mark_last_vote_tx_blockhash_non_voting(); + } else if vote_tx_result.is_hot_spare() { + tower.mark_last_vote_tx_blockhash_hot_spare(); } }