Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 767d24e

Browse files
mergify[bot]AshwinSekar
authored andcommitted
v1.18: consensus: make shallow threshold checks log only (backport of #1506) (#1546)
consensus: make shallow threshold checks log only (#1506) * consensus: make shallow threshold checks log only * pr feedback: comment, make check more readable (cherry picked from commit 6859d65) Co-authored-by: Ashwin Sekar <[email protected]>
1 parent ece3f9d commit 767d24e

File tree

3 files changed

+44
-25
lines changed

3 files changed

+44
-25
lines changed

core/src/consensus.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ impl TowerVersions {
214214
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, AbiExample)]
215215
pub struct Tower {
216216
pub node_pubkey: Pubkey,
217-
threshold_depth: usize,
217+
pub(crate) threshold_depth: usize,
218218
threshold_size: f64,
219219
pub(crate) vote_state: VoteState,
220220
last_vote: VoteTransaction,
@@ -1145,18 +1145,24 @@ impl Tower {
11451145
slot: Slot,
11461146
voted_stakes: &VotedStakes,
11471147
total_stake: Stake,
1148-
) -> ThresholdDecision {
1148+
) -> Vec<ThresholdDecision> {
1149+
let mut threshold_decisions = vec![];
11491150
// Generate the vote state assuming this vote is included.
11501151
let mut vote_state = self.vote_state.clone();
11511152
process_slot_vote_unchecked(&mut vote_state, slot);
11521153

11531154
// Assemble all the vote thresholds and depths to check.
11541155
let vote_thresholds_and_depths = vec![
1156+
// The following two checks are log only and are currently being used for experimentation
1157+
// purposes. We wish to impose a shallow threshold check to prevent the frequent 8 deep
1158+
// lockouts seen multiple times a day. We check both the 4th and 5th deep here to collect
1159+
// metrics to determine the right depth and threshold percentage to set in the future.
11551160
(VOTE_THRESHOLD_DEPTH_SHALLOW, SWITCH_FORK_THRESHOLD),
1161+
(VOTE_THRESHOLD_DEPTH_SHALLOW + 1, SWITCH_FORK_THRESHOLD),
11561162
(self.threshold_depth, self.threshold_size),
11571163
];
11581164

1159-
// Check one by one. If any threshold fails, return failure.
1165+
// Check one by one and add any failures to be returned
11601166
for (threshold_depth, threshold_size) in vote_thresholds_and_depths {
11611167
if let ThresholdDecision::FailedThreshold(vote_depth, stake) =
11621168
Self::check_vote_stake_threshold(
@@ -1169,10 +1175,10 @@ impl Tower {
11691175
total_stake,
11701176
)
11711177
{
1172-
return ThresholdDecision::FailedThreshold(vote_depth, stake);
1178+
threshold_decisions.push(ThresholdDecision::FailedThreshold(vote_depth, stake));
11731179
}
11741180
}
1175-
ThresholdDecision::PassedThreshold
1181+
threshold_decisions
11761182
}
11771183

11781184
/// Update lockouts for all the ancestors
@@ -2381,7 +2387,7 @@ pub mod test {
23812387
fn test_check_vote_threshold_without_votes() {
23822388
let tower = Tower::new_for_tests(1, 0.67);
23832389
let stakes = vec![(0, 1)].into_iter().collect();
2384-
assert!(tower.check_vote_stake_thresholds(0, &stakes, 2).passed());
2390+
assert!(tower.check_vote_stake_thresholds(0, &stakes, 2).is_empty());
23852391
}
23862392

23872393
#[test]
@@ -2395,7 +2401,7 @@ pub mod test {
23952401
}
23962402
assert!(!tower
23972403
.check_vote_stake_thresholds(MAX_LOCKOUT_HISTORY as u64 + 1, &stakes, 2)
2398-
.passed());
2404+
.is_empty());
23992405
}
24002406

24012407
#[test]
@@ -2531,28 +2537,32 @@ pub mod test {
25312537
let mut tower = Tower::new_for_tests(1, 0.67);
25322538
let stakes = vec![(0, 1)].into_iter().collect();
25332539
tower.record_vote(0, Hash::default());
2534-
assert!(!tower.check_vote_stake_thresholds(1, &stakes, 2).passed());
2540+
assert!(!tower.check_vote_stake_thresholds(1, &stakes, 2).is_empty());
25352541
}
25362542
#[test]
25372543
fn test_check_vote_threshold_above_threshold() {
25382544
let mut tower = Tower::new_for_tests(1, 0.67);
25392545
let stakes = vec![(0, 2)].into_iter().collect();
25402546
tower.record_vote(0, Hash::default());
2541-
assert!(tower.check_vote_stake_thresholds(1, &stakes, 2).passed());
2547+
assert!(tower.check_vote_stake_thresholds(1, &stakes, 2).is_empty());
25422548
}
25432549

25442550
#[test]
25452551
fn test_check_vote_thresholds_above_thresholds() {
25462552
let mut tower = Tower::new_for_tests(VOTE_THRESHOLD_DEPTH, 0.67);
2547-
let stakes = vec![(0, 3), (VOTE_THRESHOLD_DEPTH_SHALLOW as u64, 2)]
2548-
.into_iter()
2549-
.collect();
2553+
let stakes = vec![
2554+
(0, 3),
2555+
(VOTE_THRESHOLD_DEPTH_SHALLOW as u64, 2),
2556+
((VOTE_THRESHOLD_DEPTH_SHALLOW as u64) - 1, 2),
2557+
]
2558+
.into_iter()
2559+
.collect();
25502560
for slot in 0..VOTE_THRESHOLD_DEPTH {
25512561
tower.record_vote(slot as Slot, Hash::default());
25522562
}
25532563
assert!(tower
25542564
.check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 4)
2555-
.passed());
2565+
.is_empty());
25562566
}
25572567

25582568
#[test]
@@ -2566,7 +2576,7 @@ pub mod test {
25662576
}
25672577
assert!(!tower
25682578
.check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 10)
2569-
.passed());
2579+
.is_empty());
25702580
}
25712581

25722582
#[test]
@@ -2580,7 +2590,7 @@ pub mod test {
25802590
}
25812591
assert!(!tower
25822592
.check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 10)
2583-
.passed());
2593+
.is_empty());
25842594
}
25852595

25862596
#[test]
@@ -2590,15 +2600,15 @@ pub mod test {
25902600
tower.record_vote(0, Hash::default());
25912601
tower.record_vote(1, Hash::default());
25922602
tower.record_vote(2, Hash::default());
2593-
assert!(tower.check_vote_stake_thresholds(6, &stakes, 2).passed());
2603+
assert!(tower.check_vote_stake_thresholds(6, &stakes, 2).is_empty());
25942604
}
25952605

25962606
#[test]
25972607
fn test_check_vote_threshold_above_threshold_no_stake() {
25982608
let mut tower = Tower::new_for_tests(1, 0.67);
25992609
let stakes = HashMap::new();
26002610
tower.record_vote(0, Hash::default());
2601-
assert!(!tower.check_vote_stake_thresholds(1, &stakes, 2).passed());
2611+
assert!(!tower.check_vote_stake_thresholds(1, &stakes, 2).is_empty());
26022612
}
26032613

26042614
#[test]
@@ -2609,7 +2619,7 @@ pub mod test {
26092619
tower.record_vote(0, Hash::default());
26102620
tower.record_vote(1, Hash::default());
26112621
tower.record_vote(2, Hash::default());
2612-
assert!(tower.check_vote_stake_thresholds(6, &stakes, 2).passed());
2622+
assert!(tower.check_vote_stake_thresholds(6, &stakes, 2).is_empty());
26132623
}
26142624

26152625
#[test]
@@ -2674,7 +2684,7 @@ pub mod test {
26742684
);
26752685
assert!(tower
26762686
.check_vote_stake_thresholds(vote_to_evaluate, &voted_stakes, total_stake)
2677-
.passed());
2687+
.is_empty());
26782688

26792689
// CASE 2: Now we want to evaluate a vote for slot VOTE_THRESHOLD_DEPTH + 1. This slot
26802690
// will expire the vote in one of the vote accounts, so we should have insufficient
@@ -2694,7 +2704,7 @@ pub mod test {
26942704
);
26952705
assert!(!tower
26962706
.check_vote_stake_thresholds(vote_to_evaluate, &voted_stakes, total_stake)
2697-
.passed());
2707+
.is_empty());
26982708
}
26992709

27002710
fn vote_and_check_recent(num_votes: usize) {

core/src/consensus/progress_map.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ pub struct ForkStats {
299299
pub has_voted: bool,
300300
pub is_recent: bool,
301301
pub is_empty: bool,
302-
pub vote_threshold: ThresholdDecision,
302+
pub vote_threshold: Vec<ThresholdDecision>,
303303
pub is_locked_out: bool,
304304
pub voted_stakes: VotedStakes,
305305
pub is_supermajority_confirmed: bool,

core/src/replay_stage.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3691,7 +3691,7 @@ impl ReplayStage {
36913691
// checks
36923692
let (
36933693
is_locked_out,
3694-
vote_threshold,
3694+
vote_thresholds,
36953695
propagated_stake,
36963696
is_leader_slot,
36973697
fork_weight,
@@ -3704,7 +3704,7 @@ impl ReplayStage {
37043704
.unwrap();
37053705
(
37063706
fork_stats.is_locked_out,
3707-
fork_stats.vote_threshold,
3707+
&fork_stats.vote_threshold,
37083708
propagated_stats.propagated_validators_stake,
37093709
propagated_stats.is_leader_slot,
37103710
fork_stats.fork_weight(),
@@ -3721,13 +3721,22 @@ impl ReplayStage {
37213721
if is_locked_out {
37223722
failure_reasons.push(HeaviestForkFailures::LockedOut(candidate_vote_bank.slot()));
37233723
}
3724-
if let ThresholdDecision::FailedThreshold(vote_depth, fork_stake) = vote_threshold {
3724+
let mut threshold_passed = true;
3725+
for threshold_failure in vote_thresholds {
3726+
let &ThresholdDecision::FailedThreshold(vote_depth, fork_stake) = threshold_failure
3727+
else {
3728+
continue;
3729+
};
37253730
failure_reasons.push(HeaviestForkFailures::FailedThreshold(
37263731
candidate_vote_bank.slot(),
37273732
vote_depth,
37283733
fork_stake,
37293734
total_threshold_stake,
37303735
));
3736+
// Ignore shallow checks for voting purposes
3737+
if (vote_depth as usize) >= tower.threshold_depth {
3738+
threshold_passed = false;
3739+
}
37313740
}
37323741
if !propagation_confirmed {
37333742
failure_reasons.push(HeaviestForkFailures::NoPropagatedConfirmation(
@@ -3738,7 +3747,7 @@ impl ReplayStage {
37383747
}
37393748

37403749
if !is_locked_out
3741-
&& vote_threshold.passed()
3750+
&& threshold_passed
37423751
&& propagation_confirmed
37433752
&& switch_fork_decision.can_vote()
37443753
{

0 commit comments

Comments
 (0)