Cleanup select_vote_and_reset_forks() (#33421)
This commit is contained in:
parent
bdc4cbba47
commit
ec2e1241a1
|
@ -3440,8 +3440,17 @@ impl ReplayStage {
|
||||||
// 3) The best "selected" bank is on a different fork,
|
// 3) The best "selected" bank is on a different fork,
|
||||||
// switch_threshold succeeds
|
// switch_threshold succeeds
|
||||||
let mut failure_reasons = vec![];
|
let mut failure_reasons = vec![];
|
||||||
let selected_fork = {
|
struct CandidateVoteAndResetBanks<'a> {
|
||||||
let switch_fork_decision = tower.check_switch_threshold(
|
// A bank that the validator will vote on given it passes all
|
||||||
|
// remaining vote checks
|
||||||
|
candidate_vote_bank: Option<&'a Arc<Bank>>,
|
||||||
|
// A bank that the validator will reset its PoH to regardless
|
||||||
|
// of voting behavior
|
||||||
|
reset_bank: Option<&'a Arc<Bank>>,
|
||||||
|
switch_fork_decision: SwitchForkDecision,
|
||||||
|
}
|
||||||
|
let candidate_vote_and_reset_banks = {
|
||||||
|
let switch_fork_decision: SwitchForkDecision = tower.check_switch_threshold(
|
||||||
heaviest_bank.slot(),
|
heaviest_bank.slot(),
|
||||||
ancestors,
|
ancestors,
|
||||||
descendants,
|
descendants,
|
||||||
|
@ -3456,9 +3465,8 @@ impl ReplayStage {
|
||||||
|
|
||||||
match switch_fork_decision {
|
match switch_fork_decision {
|
||||||
SwitchForkDecision::FailedSwitchThreshold(switch_proof_stake, total_stake) => {
|
SwitchForkDecision::FailedSwitchThreshold(switch_proof_stake, total_stake) => {
|
||||||
let reset_bank = heaviest_bank_on_same_voted_fork;
|
|
||||||
let final_switch_fork_decision = Self::select_forks_failed_switch_threshold(
|
let final_switch_fork_decision = Self::select_forks_failed_switch_threshold(
|
||||||
reset_bank.map(|bank| bank.as_ref()),
|
heaviest_bank_on_same_voted_fork.map(|bank| bank.as_ref()),
|
||||||
progress,
|
progress,
|
||||||
tower,
|
tower,
|
||||||
heaviest_bank.slot(),
|
heaviest_bank.slot(),
|
||||||
|
@ -3467,7 +3475,22 @@ impl ReplayStage {
|
||||||
total_stake,
|
total_stake,
|
||||||
switch_fork_decision,
|
switch_fork_decision,
|
||||||
);
|
);
|
||||||
reset_bank.map(|b| (b, final_switch_fork_decision))
|
let candidate_vote_bank = if final_switch_fork_decision.can_vote() {
|
||||||
|
// The only time we would still vote despite `!switch_fork_decision.can_vote()`
|
||||||
|
// is if we switched the vote candidate to `heaviest_bank_on_same_voted_fork`
|
||||||
|
// because we needed to refresh the vote to the tip of our last voted fork.
|
||||||
|
heaviest_bank_on_same_voted_fork
|
||||||
|
} else {
|
||||||
|
// Otherwise, we should just return the original vote candidate, the heaviest bank
|
||||||
|
// for logging purposes, namely to check if there are any additional voting failures
|
||||||
|
// besides the switch threshold
|
||||||
|
Some(heaviest_bank)
|
||||||
|
};
|
||||||
|
CandidateVoteAndResetBanks {
|
||||||
|
candidate_vote_bank,
|
||||||
|
reset_bank: heaviest_bank_on_same_voted_fork,
|
||||||
|
switch_fork_decision: final_switch_fork_decision,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SwitchForkDecision::FailedSwitchDuplicateRollback(latest_duplicate_ancestor) => {
|
SwitchForkDecision::FailedSwitchDuplicateRollback(latest_duplicate_ancestor) => {
|
||||||
// If we can't switch and our last vote was on an unconfirmed, duplicate slot,
|
// If we can't switch and our last vote was on an unconfirmed, duplicate slot,
|
||||||
|
@ -3517,13 +3540,29 @@ impl ReplayStage {
|
||||||
0, // In this case we never actually performed the switch check, 0 for now
|
0, // In this case we never actually performed the switch check, 0 for now
|
||||||
0,
|
0,
|
||||||
));
|
));
|
||||||
reset_bank.map(|b| (b, switch_fork_decision))
|
CandidateVoteAndResetBanks {
|
||||||
|
candidate_vote_bank: None,
|
||||||
|
reset_bank,
|
||||||
|
switch_fork_decision,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => Some((heaviest_bank, switch_fork_decision)),
|
_ => CandidateVoteAndResetBanks {
|
||||||
|
candidate_vote_bank: Some(heaviest_bank),
|
||||||
|
reset_bank: Some(heaviest_bank),
|
||||||
|
switch_fork_decision,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some((bank, switch_fork_decision)) = selected_fork {
|
let CandidateVoteAndResetBanks {
|
||||||
|
candidate_vote_bank,
|
||||||
|
reset_bank,
|
||||||
|
switch_fork_decision,
|
||||||
|
} = candidate_vote_and_reset_banks;
|
||||||
|
|
||||||
|
if let Some(candidate_vote_bank) = candidate_vote_bank {
|
||||||
|
// If there's a bank to potentially vote on, then make the remaining
|
||||||
|
// checks
|
||||||
let (
|
let (
|
||||||
is_locked_out,
|
is_locked_out,
|
||||||
vote_threshold,
|
vote_threshold,
|
||||||
|
@ -3533,8 +3572,10 @@ impl ReplayStage {
|
||||||
total_threshold_stake,
|
total_threshold_stake,
|
||||||
total_epoch_stake,
|
total_epoch_stake,
|
||||||
) = {
|
) = {
|
||||||
let fork_stats = progress.get_fork_stats(bank.slot()).unwrap();
|
let fork_stats = progress.get_fork_stats(candidate_vote_bank.slot()).unwrap();
|
||||||
let propagated_stats = &progress.get_propagated_stats(bank.slot()).unwrap();
|
let propagated_stats = &progress
|
||||||
|
.get_propagated_stats(candidate_vote_bank.slot())
|
||||||
|
.unwrap();
|
||||||
(
|
(
|
||||||
fork_stats.is_locked_out,
|
fork_stats.is_locked_out,
|
||||||
fork_stats.vote_threshold,
|
fork_stats.vote_threshold,
|
||||||
|
@ -3548,22 +3589,22 @@ impl ReplayStage {
|
||||||
|
|
||||||
let propagation_confirmed = is_leader_slot
|
let propagation_confirmed = is_leader_slot
|
||||||
|| progress
|
|| progress
|
||||||
.get_leader_propagation_slot_must_exist(bank.slot())
|
.get_leader_propagation_slot_must_exist(candidate_vote_bank.slot())
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
if is_locked_out {
|
if is_locked_out {
|
||||||
failure_reasons.push(HeaviestForkFailures::LockedOut(bank.slot()));
|
failure_reasons.push(HeaviestForkFailures::LockedOut(candidate_vote_bank.slot()));
|
||||||
}
|
}
|
||||||
if let ThresholdDecision::FailedThreshold(fork_stake) = vote_threshold {
|
if let ThresholdDecision::FailedThreshold(fork_stake) = vote_threshold {
|
||||||
failure_reasons.push(HeaviestForkFailures::FailedThreshold(
|
failure_reasons.push(HeaviestForkFailures::FailedThreshold(
|
||||||
bank.slot(),
|
candidate_vote_bank.slot(),
|
||||||
fork_stake,
|
fork_stake,
|
||||||
total_threshold_stake,
|
total_threshold_stake,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if !propagation_confirmed {
|
if !propagation_confirmed {
|
||||||
failure_reasons.push(HeaviestForkFailures::NoPropagatedConfirmation(
|
failure_reasons.push(HeaviestForkFailures::NoPropagatedConfirmation(
|
||||||
bank.slot(),
|
candidate_vote_bank.slot(),
|
||||||
propagated_stake,
|
propagated_stake,
|
||||||
total_epoch_stake,
|
total_epoch_stake,
|
||||||
));
|
));
|
||||||
|
@ -3574,19 +3615,25 @@ impl ReplayStage {
|
||||||
&& propagation_confirmed
|
&& propagation_confirmed
|
||||||
&& switch_fork_decision.can_vote()
|
&& switch_fork_decision.can_vote()
|
||||||
{
|
{
|
||||||
info!("voting: {} {}", bank.slot(), fork_weight);
|
info!("voting: {} {}", candidate_vote_bank.slot(), fork_weight);
|
||||||
SelectVoteAndResetForkResult {
|
SelectVoteAndResetForkResult {
|
||||||
vote_bank: Some((bank.clone(), switch_fork_decision)),
|
vote_bank: Some((candidate_vote_bank.clone(), switch_fork_decision)),
|
||||||
reset_bank: Some(bank.clone()),
|
reset_bank: Some(candidate_vote_bank.clone()),
|
||||||
heaviest_fork_failures: failure_reasons,
|
heaviest_fork_failures: failure_reasons,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SelectVoteAndResetForkResult {
|
SelectVoteAndResetForkResult {
|
||||||
vote_bank: None,
|
vote_bank: None,
|
||||||
reset_bank: Some(bank.clone()),
|
reset_bank: reset_bank.cloned(),
|
||||||
heaviest_fork_failures: failure_reasons,
|
heaviest_fork_failures: failure_reasons,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if reset_bank.is_some() {
|
||||||
|
SelectVoteAndResetForkResult {
|
||||||
|
vote_bank: None,
|
||||||
|
reset_bank: reset_bank.cloned(),
|
||||||
|
heaviest_fork_failures: failure_reasons,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SelectVoteAndResetForkResult {
|
SelectVoteAndResetForkResult {
|
||||||
vote_bank: None,
|
vote_bank: None,
|
||||||
|
@ -8147,7 +8194,10 @@ pub(crate) mod tests {
|
||||||
assert_eq!(reset_fork, Some(6));
|
assert_eq!(reset_fork, Some(6));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
failures,
|
failures,
|
||||||
vec![HeaviestForkFailures::FailedSwitchThreshold(4, 0, 30000),]
|
vec![
|
||||||
|
HeaviestForkFailures::FailedSwitchThreshold(4, 0, 30000),
|
||||||
|
HeaviestForkFailures::LockedOut(4)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
let (vote_fork, reset_fork, failures) = run_compute_and_select_forks(
|
let (vote_fork, reset_fork, failures) = run_compute_and_select_forks(
|
||||||
|
@ -8163,7 +8213,10 @@ pub(crate) mod tests {
|
||||||
assert_eq!(reset_fork, Some(6));
|
assert_eq!(reset_fork, Some(6));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
failures,
|
failures,
|
||||||
vec![HeaviestForkFailures::FailedSwitchThreshold(4, 0, 30000),]
|
vec![
|
||||||
|
HeaviestForkFailures::FailedSwitchThreshold(4, 0, 30000),
|
||||||
|
HeaviestForkFailures::LockedOut(4)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue