From 384f52a607c06e07f0d88e6e95c4dbbfa6159330 Mon Sep 17 00:00:00 2001 From: sakridge Date: Mon, 3 Feb 2020 13:44:34 -0800 Subject: [PATCH] Fix consensus threshold when new root is created (#8093) When a new root is created, the oldest slot is popped off but when the logic checks for identical slots, it assumes that any difference means a slot was popped off the front. --- core/src/consensus.rs | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/core/src/consensus.rs b/core/src/consensus.rs index 16b16f7e8d..ac52bc9549 100644 --- a/core/src/consensus.rs +++ b/core/src/consensus.rs @@ -327,21 +327,16 @@ impl Tower { fork_stake.stake, total_staked ); - for (new_lockout, original_lockout) in - lockouts.votes.iter().zip(self.lockouts.votes.iter()) - { - if new_lockout.slot == original_lockout.slot { - if new_lockout.confirmation_count <= self.threshold_depth as u32 { - break; + if vote.confirmation_count as usize > self.threshold_depth { + for old_vote in &self.lockouts.votes { + if old_vote.slot == vote.slot + && old_vote.confirmation_count == vote.confirmation_count + { + return true; } - if new_lockout.confirmation_count != original_lockout.confirmation_count { - return lockout > self.threshold_size; - } - } else { - break; } } - true + lockout > self.threshold_size } else { false } @@ -556,6 +551,24 @@ mod test { assert!(tower.check_vote_stake_threshold(0, &stakes, 2)); } + #[test] + fn test_check_vote_threshold_no_skip_lockout_with_new_root() { + solana_logger::setup(); + let mut tower = Tower::new_for_tests(4, 0.67); + let mut stakes = HashMap::new(); + for i in 0..(MAX_LOCKOUT_HISTORY as u64 + 1) { + stakes.insert( + i, + StakeLockout { + stake: 1, + lockout: 8, + }, + ); + tower.record_vote(i, Hash::default()); + } + assert!(!tower.check_vote_stake_threshold(MAX_LOCKOUT_HISTORY as u64 + 1, &stakes, 2)); + } + #[test] fn test_is_slot_confirmed_not_enough_stake_failure() { let tower = Tower::new_for_tests(1, 0.67);