Skip to main content

solana_core/
consensus.rs

1pub mod fork_choice;
2pub mod heaviest_subtree_fork_choice;
3pub(crate) mod latest_validator_votes_for_frozen_banks;
4pub mod progress_map;
5mod tower1_14_11;
6mod tower1_7_14;
7pub mod tower_storage;
8pub(crate) mod tower_vote_state;
9pub mod tree_diff;
10pub mod vote_stake_tracker;
11
12use {
13    self::{
14        heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice,
15        latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks,
16        progress_map::{LockoutIntervals, ProgressMap},
17        tower_storage::{SavedTower, SavedTowerVersions, TowerStorage},
18        tower_vote_state::TowerVoteState,
19        tower1_7_14::Tower1_7_14,
20        tower1_14_11::Tower1_14_11,
21    },
22    crate::{consensus::progress_map::LockoutInterval, replay_stage::DUPLICATE_THRESHOLD},
23    agave_votor_messages::{fraction::Fraction, migration::GENESIS_VOTE_THRESHOLD},
24    chrono::prelude::*,
25    solana_clock::{Slot, UnixTimestamp},
26    solana_hash::Hash,
27    solana_instruction::Instruction,
28    solana_keypair::Keypair,
29    solana_ledger::{
30        ancestor_iterator::AncestorIterator,
31        blockstore::{self, Blockstore},
32    },
33    solana_pubkey::Pubkey,
34    solana_runtime::{bank::Bank, bank_forks::BankForks, commitment::VOTE_THRESHOLD_SIZE},
35    solana_slot_history::{Check, SlotHistory},
36    solana_vote::{vote_account::VoteAccountsHashMap, vote_transaction::VoteTransaction},
37    solana_vote_program::{
38        vote_error::VoteError,
39        vote_instruction,
40        vote_state::{BlockTimestamp, Lockout, TowerSync, Vote, VoteState1_14_11, VoteStateUpdate},
41    },
42    std::{
43        cmp::Ordering,
44        collections::{HashMap, HashSet},
45        num::NonZeroU64,
46        ops::Deref,
47    },
48    thiserror::Error,
49};
50
51#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
52pub enum ThresholdDecision {
53    #[default]
54    PassedThreshold,
55    FailedThreshold(/* vote depth */ u64, /* Observed stake */ u64),
56}
57
58impl ThresholdDecision {
59    pub fn passed(&self) -> bool {
60        matches!(self, Self::PassedThreshold)
61    }
62}
63
64#[cfg_attr(feature = "frozen-abi", derive(AbiExample, StableAbi, StableAbiSample))]
65#[derive(PartialEq, Eq, Clone, Debug)]
66pub enum SwitchForkDecision {
67    SwitchProof(Hash),
68    SameFork,
69    FailedSwitchThreshold(
70        /* Switch proof stake */ u64,
71        /* Total stake */ u64,
72    ),
73    FailedSwitchDuplicateRollback(Slot),
74}
75
76impl SwitchForkDecision {
77    pub fn to_vote_instruction(
78        &self,
79        vote: VoteTransaction,
80        vote_account_pubkey: &Pubkey,
81        authorized_voter_pubkey: &Pubkey,
82    ) -> Option<Instruction> {
83        match (self, vote) {
84            (SwitchForkDecision::FailedSwitchThreshold(_, total_stake), _) => {
85                assert_ne!(*total_stake, 0);
86                None
87            }
88            (SwitchForkDecision::FailedSwitchDuplicateRollback(_), _) => None,
89            (SwitchForkDecision::SameFork, VoteTransaction::Vote(v)) => Some(
90                vote_instruction::vote(vote_account_pubkey, authorized_voter_pubkey, v),
91            ),
92            (SwitchForkDecision::SameFork, VoteTransaction::VoteStateUpdate(v)) => {
93                Some(vote_instruction::update_vote_state(
94                    vote_account_pubkey,
95                    authorized_voter_pubkey,
96                    v,
97                ))
98            }
99            (SwitchForkDecision::SameFork, VoteTransaction::TowerSync(t)) => Some(
100                vote_instruction::tower_sync(vote_account_pubkey, authorized_voter_pubkey, t),
101            ),
102            (SwitchForkDecision::SwitchProof(switch_proof_hash), VoteTransaction::Vote(v)) => {
103                Some(vote_instruction::vote_switch(
104                    vote_account_pubkey,
105                    authorized_voter_pubkey,
106                    v,
107                    *switch_proof_hash,
108                ))
109            }
110            (
111                SwitchForkDecision::SwitchProof(switch_proof_hash),
112                VoteTransaction::VoteStateUpdate(v),
113            ) => Some(vote_instruction::update_vote_state_switch(
114                vote_account_pubkey,
115                authorized_voter_pubkey,
116                v,
117                *switch_proof_hash,
118            )),
119            (SwitchForkDecision::SwitchProof(switch_proof_hash), VoteTransaction::TowerSync(t)) => {
120                Some(vote_instruction::tower_sync_switch(
121                    vote_account_pubkey,
122                    authorized_voter_pubkey,
123                    t,
124                    *switch_proof_hash,
125                ))
126            }
127            (SwitchForkDecision::SameFork, VoteTransaction::CompactVoteStateUpdate(v)) => {
128                Some(vote_instruction::compact_update_vote_state(
129                    vote_account_pubkey,
130                    authorized_voter_pubkey,
131                    v,
132                ))
133            }
134            (
135                SwitchForkDecision::SwitchProof(switch_proof_hash),
136                VoteTransaction::CompactVoteStateUpdate(v),
137            ) => Some(vote_instruction::compact_update_vote_state_switch(
138                vote_account_pubkey,
139                authorized_voter_pubkey,
140                v,
141                *switch_proof_hash,
142            )),
143        }
144    }
145
146    pub fn can_vote(&self) -> bool {
147        match self {
148            SwitchForkDecision::FailedSwitchThreshold(_, _) => false,
149            SwitchForkDecision::FailedSwitchDuplicateRollback(_) => false,
150            SwitchForkDecision::SameFork => true,
151            SwitchForkDecision::SwitchProof(_) => true,
152        }
153    }
154}
155
156const VOTE_THRESHOLD_DEPTH_SHALLOW: usize = 4;
157pub const VOTE_THRESHOLD_DEPTH: usize = 8;
158pub const SWITCH_FORK_THRESHOLD: f64 = 0.38;
159
160pub type Result<T> = std::result::Result<T, TowerError>;
161
162pub type Stake = u64;
163pub type VotedStakes = HashMap<Slot, Stake, ahash::RandomState>;
164pub type PubkeyVotes = Vec<(Pubkey, Slot)>;
165
166pub(crate) struct ComputedBankState {
167    pub voted_stakes: VotedStakes,
168    pub total_stake: Stake,
169    pub fork_stake: Stake,
170
171    /// For Alpenglow migration - a block in `N` is super OC when there is at least
172    /// 82% of stake voting for `N` in `N + 1`
173    pub parent_is_super_oc: bool,
174
175    /// Flat list of intervals of lockouts of the form {voter, start, end}
176    /// ([`crate::consensus::progress_map::LockoutInterval`]).
177    pub lockout_intervals: LockoutIntervals,
178    pub my_latest_landed_vote: Option<Slot>,
179}
180
181#[derive(Debug, PartialEq, Clone)]
182#[allow(clippy::large_enum_variant)]
183pub enum TowerVersions {
184    V1_7_14(Tower1_7_14),
185    V1_14_11(Tower1_14_11),
186    Current(Tower),
187}
188
189impl TowerVersions {
190    pub fn new_current(tower: Tower) -> Self {
191        Self::Current(tower)
192    }
193
194    pub fn convert_to_current(self) -> Tower {
195        match self {
196            TowerVersions::V1_7_14(tower) => tower.into(),
197            TowerVersions::V1_14_11(tower) => tower.into(),
198            TowerVersions::Current(tower) => tower,
199        }
200    }
201}
202
203#[cfg_attr(feature = "frozen-abi", derive(AbiExample, StableAbi, StableAbiSample))]
204#[derive(PartialEq, Eq, Debug, Default, Clone, Copy)]
205pub(crate) enum BlockhashStatus {
206    /// No vote since restart
207    #[default]
208    Uninitialized,
209    /// Non voting validator
210    NonVoting,
211    /// Hot spare validator
212    HotSpare,
213    /// Successfully generated vote tx with blockhash
214    Blockhash(Hash),
215}
216
217#[derive(Clone, Debug, PartialEq)]
218pub struct Tower {
219    pub node_pubkey: Pubkey,
220    pub(crate) threshold_depth: usize,
221    threshold_size: f64,
222    pub(crate) vote_state: TowerVoteState,
223    last_vote: VoteTransaction,
224    // The blockhash used in the last vote transaction, may or may not equal the
225    // blockhash of the voted block itself, depending if the vote slot was refreshed.
226    // For instance, a vote for slot 5, may be refreshed/resubmitted for inclusion in
227    //  block 10, in  which case `last_vote_tx_blockhash` equals the blockhash of 10, not 5.
228    // For non voting validators this is NonVoting
229    last_vote_tx_blockhash: BlockhashStatus,
230    last_timestamp: BlockTimestamp,
231    // Restored last voted slot which cannot be found in SlotHistory at replayed root
232    // (This is a special field for slashing-free validator restart with edge cases).
233    // This could be emptied after some time; but left intact indefinitely for easier
234    // implementation
235    // Further, stray slot can be stale or not. `Stale` here means whether given
236    // bank_forks (=~ ledger) lacks the slot or not.
237    stray_restored_slot: Option<Slot>,
238    pub last_switch_threshold_check: Option<(Slot, SwitchForkDecision)>,
239}
240
241impl Default for Tower {
242    fn default() -> Self {
243        let mut tower = Self {
244            node_pubkey: Pubkey::default(),
245            threshold_depth: VOTE_THRESHOLD_DEPTH,
246            threshold_size: VOTE_THRESHOLD_SIZE,
247            vote_state: TowerVoteState::default(),
248            last_vote: VoteTransaction::from(TowerSync::default()),
249            last_timestamp: BlockTimestamp::default(),
250            last_vote_tx_blockhash: BlockhashStatus::default(),
251            stray_restored_slot: Option::default(),
252            last_switch_threshold_check: Option::default(),
253        };
254        // VoteState::root_slot is ensured to be Some in Tower
255        tower.vote_state.root_slot = Some(Slot::default());
256        tower
257    }
258}
259
260// Tower1_14_11 is the persisted data format for the Tower,
261// decoupling it from VoteState::Current.
262impl From<Tower> for Tower1_14_11 {
263    fn from(tower: Tower) -> Self {
264        Self {
265            node_pubkey: tower.node_pubkey,
266            threshold_depth: tower.threshold_depth,
267            threshold_size: tower.threshold_size,
268            vote_state: VoteState1_14_11::from(tower.vote_state),
269            last_vote: tower.last_vote,
270            last_vote_tx_blockhash: tower.last_vote_tx_blockhash,
271            last_timestamp: tower.last_timestamp,
272            stray_restored_slot: tower.stray_restored_slot,
273            last_switch_threshold_check: tower.last_switch_threshold_check,
274        }
275    }
276}
277
278// Tower1_14_11 is the persisted data format for the Tower,
279// decoupling it from VoteState::Current.
280impl From<Tower1_14_11> for Tower {
281    fn from(tower: Tower1_14_11) -> Self {
282        Self {
283            node_pubkey: tower.node_pubkey,
284            threshold_depth: tower.threshold_depth,
285            threshold_size: tower.threshold_size,
286            vote_state: TowerVoteState::from(tower.vote_state),
287            last_vote: tower.last_vote,
288            last_vote_tx_blockhash: tower.last_vote_tx_blockhash,
289            last_timestamp: tower.last_timestamp,
290            stray_restored_slot: tower.stray_restored_slot,
291            last_switch_threshold_check: tower.last_switch_threshold_check,
292        }
293    }
294}
295
296impl From<Tower1_7_14> for Tower {
297    fn from(tower: Tower1_7_14) -> Self {
298        let box_last_vote = VoteTransaction::from(tower.last_vote.clone());
299
300        Self {
301            node_pubkey: tower.node_pubkey,
302            threshold_depth: tower.threshold_depth,
303            threshold_size: tower.threshold_size,
304            vote_state: TowerVoteState::from(tower.vote_state),
305            last_vote: box_last_vote,
306            last_vote_tx_blockhash: tower.last_vote_tx_blockhash,
307            last_timestamp: tower.last_timestamp,
308            stray_restored_slot: tower.stray_restored_slot,
309            last_switch_threshold_check: tower.last_switch_threshold_check,
310        }
311    }
312}
313
314impl Tower {
315    pub fn new(
316        node_pubkey: &Pubkey,
317        vote_account_pubkey: &Pubkey,
318        root: Slot,
319        bank: &Bank,
320    ) -> Self {
321        let mut tower = Tower {
322            node_pubkey: *node_pubkey,
323            ..Tower::default()
324        };
325        tower.initialize_lockouts_from_bank(vote_account_pubkey, root, bank);
326        tower
327    }
328
329    #[cfg(test)]
330    pub fn new_for_tests(threshold_depth: usize, threshold_size: f64) -> Self {
331        Self {
332            threshold_depth,
333            threshold_size,
334            ..Tower::default()
335        }
336    }
337
338    #[cfg(test)]
339    pub fn new_random(node_pubkey: Pubkey) -> Self {
340        use {
341            rand::Rng,
342            solana_vote_program::vote_state::{LandedVote, VoteStateV4},
343        };
344
345        let mut rng = rand::rng();
346        let root_slot = rng.random();
347        let votes = (1..32)
348            .map(|x| LandedVote {
349                latency: 0,
350                lockout: Lockout::new_with_confirmation_count(
351                    u64::from(x).saturating_add(root_slot),
352                    32_u32.saturating_sub(x),
353                ),
354            })
355            .collect();
356        let vote_state = VoteStateV4 {
357            node_pubkey,
358            root_slot: Some(root_slot),
359            votes,
360            ..VoteStateV4::default()
361        };
362        let last_vote = TowerSync::from(
363            vote_state
364                .votes
365                .iter()
366                .map(|lv| (lv.slot(), lv.confirmation_count()))
367                .collect::<Vec<_>>(),
368        );
369        Self {
370            node_pubkey,
371            vote_state: TowerVoteState::from(vote_state),
372            last_vote: VoteTransaction::from(last_vote),
373            ..Tower::default()
374        }
375    }
376
377    pub fn new_from_bankforks(
378        bank_forks: &BankForks,
379        node_pubkey: &Pubkey,
380        vote_account: &Pubkey,
381    ) -> Self {
382        let root_bank = bank_forks.root_bank();
383        let frozen_banks: Vec<_> = bank_forks
384            .frozen_banks()
385            .map(|(_slot, bank)| bank)
386            .collect();
387        let (_progress, heaviest_subtree_fork_choice) =
388            crate::replay_stage::ReplayStage::initialize_progress_and_fork_choice(
389                root_bank.deref(),
390                frozen_banks,
391                node_pubkey,
392                vote_account,
393                vec![],
394            );
395        let root = root_bank.slot();
396
397        let (best_slot, best_hash) = heaviest_subtree_fork_choice.best_overall_slot();
398        let heaviest_bank = bank_forks
399            .get_with_checked_hash((best_slot, best_hash))
400            .expect(
401                "The best overall slot must be one of `frozen_banks` which all exist in bank_forks",
402            );
403
404        Self::new(node_pubkey, vote_account, root, &heaviest_bank)
405    }
406
407    pub(crate) fn collect_vote_lockouts(
408        vote_account_pubkey: &Pubkey,
409        bank_slot: Slot,
410        parent_slot: Slot,
411        root_slot: Slot,
412        vote_accounts: &VoteAccountsHashMap,
413        ancestors: &HashMap<Slot, HashSet<Slot>>,
414        get_frozen_hash: impl Fn(Slot) -> Option<Hash>,
415        latest_validator_votes_for_frozen_banks: &mut LatestValidatorVotesForFrozenBanks,
416        vote_slots: &mut HashSet<Slot, ahash::RandomState>,
417    ) -> ComputedBankState {
418        let total_slots = bank_slot.saturating_sub(root_slot) as usize;
419        vote_slots.reserve(total_slots);
420        let mut voted_stakes =
421            HashMap::with_capacity_and_hasher(total_slots, ahash::RandomState::default());
422        let mut super_oc_stake = 0;
423        let mut total_stake = 0;
424
425        let total_votes = vote_accounts
426            .values()
427            .filter(|(voted_stake, _)| *voted_stake != 0)
428            .map(|(_, account)| account.vote_state_view().votes_len())
429            .sum();
430        // Flat list of intervals of lockouts of the form {voter, start, end}.
431        let mut lockout_intervals = LockoutIntervals::with_capacity(total_votes);
432        let mut my_latest_landed_vote = None;
433        for (&key, (voted_stake, account)) in vote_accounts.iter() {
434            let voted_stake = *voted_stake;
435            if voted_stake == 0 {
436                continue;
437            }
438            trace!("{vote_account_pubkey} {key} with stake {voted_stake}");
439            let mut vote_state = TowerVoteState::from(account.vote_state_view());
440            lockout_intervals.extend(vote_state.votes.iter().map(|v| LockoutInterval {
441                start: v.slot(),
442                end: v.last_locked_out_slot(),
443                voter: key,
444            }));
445
446            if key == *vote_account_pubkey {
447                my_latest_landed_vote = vote_state.nth_recent_lockout(0).map(|l| l.slot());
448                debug!("vote state {vote_state:?}");
449                debug!(
450                    "observed slot {}",
451                    vote_state
452                        .nth_recent_lockout(0)
453                        .map(|l| l.slot())
454                        .unwrap_or(0) as i64
455                );
456                debug!("observed root {}", vote_state.root_slot.unwrap_or(0) as i64);
457                datapoint_info!(
458                    "tower-observed",
459                    (
460                        "slot",
461                        vote_state
462                            .nth_recent_lockout(0)
463                            .map(|l| l.slot())
464                            .unwrap_or(0),
465                        i64
466                    ),
467                    ("root", vote_state.root_slot.unwrap_or(0), i64)
468                );
469            }
470            let start_root = vote_state.root_slot;
471
472            if let Some(last_landed_voted_slot) = vote_state.last_voted_slot() {
473                // Add the last vote to update the `heaviest_subtree_fork_choice`
474                latest_validator_votes_for_frozen_banks.check_add_vote(
475                    key,
476                    last_landed_voted_slot,
477                    get_frozen_hash(last_landed_voted_slot),
478                    true,
479                );
480
481                // For migration - a block is super OC there are 82% of votes for slot N in N + 1
482                if last_landed_voted_slot == parent_slot {
483                    super_oc_stake += voted_stake;
484                }
485            }
486
487            vote_state.process_next_vote_slot(bank_slot);
488
489            // Only record vote slots greater than the fork root. Votes earlier
490            // than the fork root will not have entries in `ancestors` and are ignored by
491            // `populate_ancestor_voted_stakes`, and there can be no landed votes
492            // >= `bank_slot`. Bounding here prevents unnecessary range expansion
493            // in the dense maps and keeps behavior identical.
494            for slot in vote_state.votes.iter().filter_map(|v| {
495                let slot = v.slot();
496                (slot > root_slot).then_some(slot)
497            }) {
498                vote_slots.insert(slot);
499            }
500
501            if start_root != vote_state.root_slot
502                && let Some(root) = start_root
503            {
504                // The account's prior root can be older than this fork's root; clamp to
505                // the same range for the same reason as above.
506                if root > root_slot {
507                    trace!("ROOT: {root}");
508                    vote_slots.insert(root);
509                }
510            }
511            if let Some(root) = vote_state.root_slot {
512                // Likewise, only include the (new) root if it lies within the range this
513                // bank will ever query in `ancestors`.
514                if root > root_slot {
515                    vote_slots.insert(root);
516                }
517            }
518
519            // The last vote in the vote stack is a simulated vote on bank_slot, which
520            // we added to the vote stack earlier in this function by calling process_vote().
521            // We don't want to update the ancestors stakes of this vote b/c it does not
522            // represent an actual vote by the validator.
523
524            // Note: It should not be possible for any vote state in this bank to have
525            // a vote for a slot >= bank_slot, so we are guaranteed that the last vote in
526            // this vote stack is the simulated vote, so this fetch should be sufficient
527            // to find the last unsimulated vote.
528            assert_eq!(
529                vote_state.nth_recent_lockout(0).map(|l| l.slot()),
530                Some(bank_slot)
531            );
532            if let Some(vote) = vote_state.nth_recent_lockout(1) {
533                // Update all the parents of this last vote with the stake of this vote account
534                Self::update_ancestor_voted_stakes(
535                    &mut voted_stakes,
536                    vote.slot(),
537                    voted_stake,
538                    ancestors,
539                );
540            }
541            total_stake += voted_stake;
542        }
543
544        debug_assert!(total_stake > 0);
545        let parent_is_super_oc = bank_slot == parent_slot + 1
546            && Fraction::new(super_oc_stake, NonZeroU64::new(total_stake).unwrap())
547                > GENESIS_VOTE_THRESHOLD;
548
549        // TODO: populate_ancestor_voted_stakes only adds zeros. Comment why
550        // that is necessary (if so).
551        Self::populate_ancestor_voted_stakes(
552            &mut voted_stakes,
553            vote_slots.iter().copied(),
554            ancestors,
555        );
556
557        // As commented above, since the votes at current bank_slot are
558        // simulated votes, the voted_stake for `bank_slot` is not populated.
559        // Therefore, we use the voted_stake for the parent of bank_slot as the
560        // `fork_stake` instead.
561        let fork_stake = ancestors
562            .get(&bank_slot)
563            .and_then(|ancestors| {
564                ancestors
565                    .iter()
566                    .max()
567                    .and_then(|parent| voted_stakes.get(parent))
568                    .copied()
569            })
570            .unwrap_or(0);
571
572        vote_slots.clear();
573
574        ComputedBankState {
575            voted_stakes,
576            total_stake,
577            fork_stake,
578            parent_is_super_oc,
579            lockout_intervals,
580            my_latest_landed_vote,
581        }
582    }
583
584    #[cfg(test)]
585    fn is_slot_confirmed(
586        &self,
587        slot: Slot,
588        voted_stakes: &VotedStakes,
589        total_stake: Stake,
590    ) -> bool {
591        voted_stakes
592            .get(&slot)
593            .map(|stake| (*stake as f64 / total_stake as f64) > self.threshold_size)
594            .unwrap_or(false)
595    }
596
597    pub(crate) fn is_slot_duplicate_confirmed(
598        &self,
599        slot: Slot,
600        voted_stakes: &VotedStakes,
601        total_stake: Stake,
602    ) -> bool {
603        voted_stakes
604            .get(&slot)
605            .map(|stake| (*stake as f64 / total_stake as f64) > DUPLICATE_THRESHOLD)
606            .unwrap_or(false)
607    }
608
609    pub fn tower_slots(&self) -> Vec<Slot> {
610        self.vote_state.tower()
611    }
612
613    pub(crate) fn last_vote_tx_blockhash(&self) -> BlockhashStatus {
614        self.last_vote_tx_blockhash
615    }
616
617    pub fn refresh_last_vote_timestamp(&mut self, heaviest_slot_on_same_fork: Slot) {
618        let timestamp = if let Some(last_vote_timestamp) = self.last_vote.timestamp() {
619            // To avoid a refreshed vote tx getting caught in deduplication filters,
620            // we need to update timestamp. Increment by smallest amount to avoid skewing
621            // the Timestamp Oracle.
622            last_vote_timestamp.saturating_add(1)
623        } else {
624            // If the previous vote did not send a timestamp due to clock error,
625            // use the last good timestamp + 1
626            datapoint_info!(
627                "refresh-timestamp-missing",
628                ("heaviest-slot", heaviest_slot_on_same_fork, i64),
629                ("last-timestamp", self.last_timestamp.timestamp, i64),
630                ("last-slot", self.last_timestamp.slot, i64),
631            );
632            self.last_timestamp.timestamp.saturating_add(1)
633        };
634
635        if let Some(last_voted_slot) = self.last_vote.last_voted_slot() {
636            if heaviest_slot_on_same_fork <= last_voted_slot {
637                warn!(
638                    "Trying to refresh timestamp for vote on {last_voted_slot} using smaller \
639                     heaviest bank {heaviest_slot_on_same_fork}"
640                );
641                return;
642            }
643            self.last_timestamp = BlockTimestamp {
644                slot: last_voted_slot,
645                timestamp,
646            };
647            self.last_vote.set_timestamp(Some(timestamp));
648        } else {
649            warn!(
650                "Trying to refresh timestamp for last vote on heaviest bank on same fork \
651                 {heaviest_slot_on_same_fork}, but there is no vote to refresh"
652            );
653        }
654    }
655
656    pub fn refresh_last_vote_tx_blockhash(&mut self, new_vote_tx_blockhash: Hash) {
657        self.last_vote_tx_blockhash = BlockhashStatus::Blockhash(new_vote_tx_blockhash);
658    }
659
660    pub(crate) fn mark_last_vote_tx_blockhash_non_voting(&mut self) {
661        self.last_vote_tx_blockhash = BlockhashStatus::NonVoting;
662    }
663
664    pub(crate) fn mark_last_vote_tx_blockhash_hot_spare(&mut self) {
665        self.last_vote_tx_blockhash = BlockhashStatus::HotSpare;
666    }
667
668    pub fn last_voted_slot_in_bank(bank: &Bank, vote_account_pubkey: &Pubkey) -> Option<Slot> {
669        let vote_account = bank.get_vote_account(vote_account_pubkey)?;
670        vote_account.vote_state_view().last_voted_slot()
671    }
672
673    pub fn record_bank_vote(&mut self, bank: &Bank) -> Option<Slot> {
674        // Returns the new root if one is made after applying a vote for the given bank to
675        // `self.vote_state`
676        let block_id = bank.block_id().unwrap_or_else(|| {
677            // This can only happen for our leader bank
678            // Note: since the new shred format is yet to be rolled out to all clusters,
679            // this can also happen for non-leader banks. Once rolled out we can assert
680            // here that this is our leader bank.
681            Hash::default()
682        });
683        self.record_bank_vote_and_update_lockouts(bank.slot(), bank.hash(), block_id)
684    }
685
686    /// If we've recently updated the vote state by applying a new vote
687    /// or syncing from a bank, generate the proper last_vote.
688    pub(crate) fn update_last_vote_from_vote_state(&mut self, vote_hash: Hash, block_id: Hash) {
689        let mut new_vote = VoteTransaction::from(TowerSync::new(
690            self.vote_state.votes.clone(),
691            self.vote_state.root_slot,
692            vote_hash,
693            block_id,
694        ));
695
696        new_vote.set_timestamp(self.maybe_timestamp(self.last_voted_slot().unwrap_or_default()));
697        self.last_vote = new_vote;
698    }
699
700    fn record_bank_vote_and_update_lockouts(
701        &mut self,
702        vote_slot: Slot,
703        vote_hash: Hash,
704        block_id: Hash,
705    ) -> Option<Slot> {
706        if let Some(last_voted_slot) = self.vote_state.last_voted_slot()
707            && vote_slot <= last_voted_slot
708        {
709            panic!(
710                "Error while recording vote {} {} in local tower {:?}",
711                vote_slot,
712                vote_hash,
713                VoteError::VoteTooOld
714            );
715        }
716
717        trace!("{} record_vote for {}", self.node_pubkey, vote_slot);
718        let old_root = self.root();
719
720        self.vote_state.process_next_vote_slot(vote_slot);
721        self.update_last_vote_from_vote_state(vote_hash, block_id);
722
723        let new_root = self.root();
724
725        datapoint_info!(
726            "tower-vote",
727            ("latest", vote_slot, i64),
728            ("root", new_root, i64)
729        );
730        if old_root != new_root {
731            Some(new_root)
732        } else {
733            None
734        }
735    }
736
737    #[cfg(feature = "dev-context-only-utils")]
738    pub fn record_vote(&mut self, slot: Slot, hash: Hash) -> Option<Slot> {
739        self.record_bank_vote_and_update_lockouts(slot, hash, Hash::default())
740    }
741
742    #[cfg(feature = "dev-context-only-utils")]
743    pub fn increase_lockout(&mut self, confirmation_count_increase: u32) {
744        for vote in self.vote_state.votes.iter_mut() {
745            vote.increase_confirmation_count(confirmation_count_increase);
746        }
747    }
748
749    pub fn last_voted_slot(&self) -> Option<Slot> {
750        if self.last_vote.is_empty() {
751            None
752        } else {
753            Some(self.last_vote.slot(self.last_vote.len() - 1))
754        }
755    }
756
757    pub fn last_voted_slot_hash(&self) -> Option<(Slot, Hash)> {
758        Some((self.last_voted_slot()?, self.last_vote.hash()))
759    }
760
761    pub fn stray_restored_slot(&self) -> Option<Slot> {
762        self.stray_restored_slot
763    }
764
765    pub fn last_vote(&self) -> VoteTransaction {
766        self.last_vote.clone()
767    }
768
769    fn maybe_timestamp(&mut self, current_slot: Slot) -> Option<UnixTimestamp> {
770        if current_slot > self.last_timestamp.slot
771            || self.last_timestamp.slot == 0 && current_slot == self.last_timestamp.slot
772        {
773            let timestamp = Utc::now().timestamp();
774            if timestamp >= self.last_timestamp.timestamp {
775                self.last_timestamp = BlockTimestamp {
776                    slot: current_slot,
777                    timestamp,
778                };
779                return Some(timestamp);
780            } else {
781                datapoint_info!(
782                    "backwards-timestamp",
783                    ("slot", current_slot, i64),
784                    ("timestamp", timestamp, i64),
785                    ("last-timestamp", self.last_timestamp.timestamp, i64),
786                )
787            }
788        }
789        None
790    }
791
792    // root may be forcibly set by arbitrary replay root slot, for example from a root
793    // after replaying a snapshot.
794    // Also, tower.root() couldn't be None; initialize_lockouts() ensures that.
795    // Conceptually, every tower must have been constructed from a concrete starting point,
796    // which establishes the origin of trust (i.e. root) whether booting from genesis (slot 0) or
797    // snapshot (slot N). In other words, there should be no possibility a Tower doesn't have
798    // root, unlike young vote accounts.
799    pub fn root(&self) -> Slot {
800        self.vote_state.root_slot.unwrap()
801    }
802
803    // a slot is recent if it's newer than the last vote we have. If we haven't voted yet
804    // but have a root (hard forks situation) then compare it to the root
805    pub fn is_recent(&self, slot: Slot) -> bool {
806        if let Some(last_voted_slot) = self.vote_state.last_voted_slot() {
807            if slot <= last_voted_slot {
808                return false;
809            }
810        } else if let Some(root) = self.vote_state.root_slot
811            && slot <= root
812        {
813            return false;
814        }
815        true
816    }
817
818    pub fn has_voted(&self, slot: Slot) -> bool {
819        for vote in &self.vote_state.votes {
820            if slot == vote.slot() {
821                return true;
822            }
823        }
824        false
825    }
826
827    pub fn is_locked_out(&self, slot: Slot, ancestors: &HashSet<Slot>) -> bool {
828        if !self.is_recent(slot) {
829            return true;
830        }
831
832        // Check if a slot is locked out by simulating adding a vote for that
833        // slot to the current lockouts to pop any expired votes. If any of the
834        // remaining voted slots are on a different fork from the checked slot,
835        // it's still locked out.
836        let mut vote_state = self.vote_state.clone();
837        vote_state.process_next_vote_slot(slot);
838        for vote in &vote_state.votes {
839            if slot != vote.slot() && !ancestors.contains(&vote.slot()) {
840                return true;
841            }
842        }
843
844        if let Some(root_slot) = vote_state.root_slot
845            && slot != root_slot
846        {
847            // This case should never happen because bank forks purges all
848            // non-descendants of the root every time root is set
849            assert!(
850                ancestors.contains(&root_slot),
851                "ancestors: {ancestors:?}, slot: {slot} root: {root_slot}"
852            );
853        }
854
855        false
856    }
857
858    /// Checks if a vote for `candidate_slot` is usable in a switching proof
859    /// from `last_voted_slot` to `switch_slot`.
860    /// We assume `candidate_slot` is not an ancestor of `last_voted_slot`.
861    ///
862    /// Returns None if `candidate_slot` or `switch_slot` is not present in `ancestors`
863    fn is_valid_switching_proof_vote(
864        &self,
865        candidate_slot: Slot,
866        last_voted_slot: Slot,
867        switch_slot: Slot,
868        ancestors: &HashMap<Slot, HashSet<Slot>>,
869        last_vote_ancestors: &HashSet<Slot>,
870    ) -> Option<bool> {
871        trace!(
872            "Checking if {candidate_slot} is a valid switching proof vote from {last_voted_slot} \
873             to {switch_slot}"
874        );
875        // Ignore if the `candidate_slot` is a descendant of the `last_voted_slot`, since we do not
876        // want to count votes on the same fork.
877        if Self::is_descendant_slot(candidate_slot, last_voted_slot, ancestors)? {
878            return Some(false);
879        }
880
881        if last_vote_ancestors.is_empty() {
882            // If `last_vote_ancestors` is empty, this means we must have a last vote that is stray. If the `last_voted_slot`
883            // is stray, it must be descended from some earlier root than the latest root (the anchor at startup).
884            // The above check also guarantees that the candidate slot is not a descendant of this stray last vote.
885            //
886            // This gives us a fork graph:
887            //     / ------------- stray `last_voted_slot`
888            // old root
889            //     \- latest root (anchor) - ... - candidate slot
890            //                                \- switch slot
891            //
892            // Thus the common acnestor of `last_voted_slot` and `candidate_slot` is `old_root`, which the `switch_slot`
893            // descends from. Thus it is safe to use `candidate_slot` in the switching proof.
894            //
895            // Note: the calling function should have already panicked if we do not have ancestors and the last vote is not stray.
896            assert!(self.is_stray_last_vote());
897            return Some(true);
898        }
899
900        // Only consider forks that split at the common_ancestor of `switch_slot` and `last_voted_slot` or earlier.
901        // This is to prevent situations like this from being included in the switching proof:
902        //
903        //         /-- `last_voted_slot`
904        //     /--Y
905        //    X    \-- `candidate_slot`
906        //     \-- `switch_slot`
907        //
908        // The common ancestor of `last_voted_slot` and `switch_slot` is `X`. Votes for the `candidate_slot`
909        // should not count towards the switch proof since `candidate_slot` is "on the same fork" as `last_voted_slot`
910        // in relation to `switch_slot`.
911        // However these candidate slots should be allowed:
912        //
913        //             /-- Y -- `last_voted_slot`
914        //    V - W - X
915        //        \    \-- `candidate_slot` -- `switch_slot`
916        //         \    \-- `candidate_slot`
917        //          \-- `candidate_slot`
918        //
919        // As the `candidate_slot`s forked off from `X` or earlier.
920        //
921        // To differentiate, we check the common ancestor of `last_voted_slot` and `candidate_slot`.
922        // If the `switch_slot` descends from this ancestor, then the vote for `candidate_slot` can be included.
923        Self::greatest_common_ancestor(ancestors, candidate_slot, last_voted_slot)
924            .and_then(|ancestor| Self::is_descendant_slot(switch_slot, ancestor, ancestors))
925    }
926
927    /// Checks if `maybe_descendant` is a descendant of `slot`.
928    ///
929    /// Returns None if `maybe_descendant` is not present in `ancestors`
930    fn is_descendant_slot(
931        maybe_descendant: Slot,
932        slot: Slot,
933        ancestors: &HashMap<Slot, HashSet<u64>>,
934    ) -> Option<bool> {
935        ancestors
936            .get(&maybe_descendant)
937            .map(|candidate_slot_ancestors| candidate_slot_ancestors.contains(&slot))
938    }
939
940    /// Returns `Some(gca)` where `gca` is the greatest (by slot number)
941    /// common ancestor of both `slot_a` and `slot_b`.
942    ///
943    /// Returns `None` if:
944    /// * `slot_a` is not in `ancestors`
945    /// * `slot_b` is not in `ancestors`
946    /// * There is no common ancestor of slot_a and slot_b in `ancestors`
947    fn greatest_common_ancestor(
948        ancestors: &HashMap<Slot, HashSet<Slot>>,
949        slot_a: Slot,
950        slot_b: Slot,
951    ) -> Option<Slot> {
952        (ancestors.get(&slot_a)?)
953            .intersection(ancestors.get(&slot_b)?)
954            .max()
955            .copied()
956    }
957
958    #[allow(clippy::too_many_arguments)]
959    fn make_check_switch_threshold_decision(
960        &self,
961        switch_slot: Slot,
962        ancestors: &HashMap<Slot, HashSet<u64>>,
963        descendants: &HashMap<Slot, HashSet<u64>>,
964        progress: &ProgressMap,
965        total_stake: u64,
966        epoch_vote_accounts: &VoteAccountsHashMap,
967        latest_validator_votes_for_frozen_banks: &LatestValidatorVotesForFrozenBanks,
968        heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice,
969    ) -> SwitchForkDecision {
970        let Some((last_voted_slot, last_voted_hash)) = self.last_voted_slot_hash() else {
971            return SwitchForkDecision::SameFork;
972        };
973        let root = self.root();
974        let empty_ancestors = HashSet::default();
975        let empty_ancestors_due_to_minor_unsynced_ledger = || {
976            // This condition (stale stray last vote) shouldn't occur under normal validator
977            // operation, indicating something unusual happened.
978            // This condition could be introduced by manual ledger mishandling,
979            // validator SEGV, OS/HW crash, or plain No Free Space FS error.
980
981            // However, returning empty ancestors as a fallback here shouldn't result in
982            // slashing by itself (Note that we couldn't fully preclude any kind of slashing if
983            // the failure was OS or HW level).
984
985            // Firstly, lockout is ensured elsewhere.
986
987            // Also, there is no risk of optimistic conf. violation. Although empty ancestors
988            // could result in incorrect (= more than actual) locked_out_stake and
989            // false-positive SwitchProof later in this function, there should be no such a
990            // heavier fork candidate, first of all, if the last vote (or any of its
991            // unavailable ancestors) were already optimistically confirmed.
992            // The only exception is that other validator is already violating it...
993            if self.is_first_switch_check() && switch_slot < last_voted_slot {
994                // `switch < last` is needed not to warn! this message just because of using
995                // newer snapshots on validator restart
996                let message = format!(
997                    "bank_forks doesn't have corresponding data for the stray restored last \
998                     vote({last_voted_slot}), meaning some inconsistency between saved tower and \
999                     ledger."
1000                );
1001                warn!("{message}");
1002                datapoint_warn!("tower_warn", ("warn", message, String));
1003            }
1004            &empty_ancestors
1005        };
1006
1007        let suspended_decision_due_to_major_unsynced_ledger = || {
1008            // This peculiar corner handling is needed mainly for a tower which is newer than
1009            // blockstore. (Yeah, we tolerate it for ease of maintaining validator by operators)
1010            // This condition could be introduced by manual ledger mishandling,
1011            // validator SEGV, OS/HW crash, or plain No Free Space FS error.
1012
1013            // When we're in this clause, it basically means validator is badly running
1014            // with a future tower while replaying past slots, especially problematic is
1015            // last_voted_slot.
1016            // So, don't re-vote on it by returning pseudo FailedSwitchThreshold, otherwise
1017            // there would be slashing because of double vote on one of last_vote_ancestors.
1018            // (Well, needless to say, re-creating the duplicate block must be handled properly
1019            // at the banking stage: https://github.com/solana-labs/solana/issues/8232)
1020            //
1021            // To be specific, the replay stage is tricked into a false perception where
1022            // last_vote_ancestors is AVAILABLE for descendant-of-`switch_slot`,  stale, and
1023            // stray slots (which should always be empty_ancestors).
1024            //
1025            // This is covered by test_future_tower_* in local_cluster
1026            SwitchForkDecision::FailedSwitchThreshold(0, total_stake)
1027        };
1028
1029        let rollback_due_to_duplicate_ancestor = |latest_duplicate_ancestor| {
1030            SwitchForkDecision::FailedSwitchDuplicateRollback(latest_duplicate_ancestor)
1031        };
1032
1033        // `heaviest_subtree_fork_choice` entries are not cleaned by duplicate block purging/rollback logic,
1034        // so this is safe to check here. We return here if the last voted slot was rolled back/purged due to
1035        // being a duplicate because `ancestors`/`descendants`/`progress` structures may be missing this slot due
1036        // to duplicate purging. This would cause many of the `unwrap()` checks below to fail.
1037        //
1038        // TODO: Handle if the last vote is on a dupe, and then we restart. The dupe won't be in
1039        // heaviest_subtree_fork_choice, so `heaviest_subtree_fork_choice.latest_invalid_ancestor()` will return
1040        // None, but the last vote will be persisted in tower.
1041        let switch_hash = progress
1042            .get_hash(switch_slot)
1043            .expect("Slot we're trying to switch to must exist AND be frozen in progress map");
1044        if let Some(latest_duplicate_ancestor) = heaviest_subtree_fork_choice
1045            .latest_invalid_ancestor(&(last_voted_slot, last_voted_hash))
1046        {
1047            // We're rolling back because one of the ancestors of the last vote was a duplicate. In this
1048            // case, it's acceptable if the switch candidate is one of ancestors of the previous vote,
1049            // just fail the switch check because there's no point in voting on an ancestor. ReplayStage
1050            // should then have a special case continue building an alternate fork from this ancestor, NOT
1051            // the `last_voted_slot`. This is in contrast to usual SwitchFailure where ReplayStage continues to build blocks
1052            // on latest vote. See `ReplayStage::select_vote_and_reset_forks()` for more details.
1053            if heaviest_subtree_fork_choice.is_strict_ancestor(
1054                &(switch_slot, switch_hash),
1055                &(last_voted_slot, last_voted_hash),
1056            ) {
1057                return rollback_due_to_duplicate_ancestor(latest_duplicate_ancestor);
1058            } else if progress
1059                .get_hash(last_voted_slot)
1060                .map(|current_slot_hash| current_slot_hash != last_voted_hash)
1061                .unwrap_or(true)
1062            {
1063                // Our last vote slot was purged because it was on a duplicate fork, don't continue below
1064                // where checks may panic. We allow a freebie vote here without checking the switch
1065                // threshold as it is trivially satisfied:
1066                // - Freebie can only occur because our last vote block was dumped & repaired
1067                // - Dump & repair only triggers due to another version reaching duplicate confirmation (52%)
1068                // - 52% > 38% so the switching threshold is implicitely satisifed
1069                info!(
1070                    "Allowing switch vote on {:?} because last vote {:?} was rolled back",
1071                    (switch_slot, switch_hash),
1072                    (last_voted_slot, last_voted_hash)
1073                );
1074                return SwitchForkDecision::SwitchProof(Hash::default());
1075            }
1076        }
1077
1078        let last_vote_ancestors = ancestors.get(&last_voted_slot).unwrap_or_else(|| {
1079            if self.is_stray_last_vote() {
1080                // Unless last vote is stray and stale, ancestors.get(last_voted_slot) must
1081                // return Some(_), justifying to panic! here.
1082                // Also, adjust_lockouts_after_replay() correctly makes last_voted_slot None,
1083                // if all saved votes are ancestors of replayed_root_slot. So this code shouldn't be
1084                // touched in that case as well.
1085                // In other words, except being stray, all other slots have been voted on while
1086                // this validator has been running, so we must be able to fetch ancestors for
1087                // all of them.
1088                empty_ancestors_due_to_minor_unsynced_ledger()
1089            } else {
1090                panic!("no ancestors found with slot: {last_voted_slot}");
1091            }
1092        });
1093
1094        let switch_slot_ancestors = ancestors.get(&switch_slot).unwrap();
1095
1096        if switch_slot == last_voted_slot || switch_slot_ancestors.contains(&last_voted_slot) {
1097            // If the `switch_slot is a descendant of the last vote,
1098            // no switching proof is necessary
1099            return SwitchForkDecision::SameFork;
1100        }
1101
1102        if last_vote_ancestors.contains(&switch_slot) {
1103            if self.is_stray_last_vote() {
1104                return suspended_decision_due_to_major_unsynced_ledger();
1105            } else {
1106                panic!(
1107                    "Should never consider switching to ancestor ({switch_slot}) of last vote: \
1108                     {last_voted_slot}, ancestors({last_vote_ancestors:?})",
1109                );
1110            }
1111        }
1112
1113        // By this point, we know the `switch_slot` is on a different fork
1114        // (is neither an ancestor nor descendant of `last_vote`), so a
1115        // switching proof is necessary
1116        let switch_proof = Hash::default();
1117        let mut locked_out_stake = 0;
1118        let mut locked_out_vote_accounts = HashSet::new();
1119        for (candidate_slot, descendants) in descendants.iter() {
1120            // 1) Don't consider any banks that haven't been frozen yet
1121            //    because the needed stats are unavailable
1122            // 2) Only consider lockouts at the latest `frozen` bank
1123            //    on each fork, as that bank will contain all the
1124            //    lockout intervals for ancestors on that fork as well.
1125            // 3) Don't consider lockouts on the `last_vote` itself
1126            // 4) Don't consider lockouts on any descendants of
1127            //    `last_vote`
1128            // 5) Don't consider any banks before the root because
1129            //    all lockouts must be ancestors of `last_vote`
1130            if !progress
1131                .get_fork_stats(*candidate_slot)
1132                .map(|stats| stats.computed)
1133                .unwrap_or(false)
1134                || {
1135                    // If any of the descendants have the `computed` flag set, then there must be a more
1136                    // recent frozen bank on this fork to use, so we can ignore this one. Otherwise,
1137                    // even if this bank has descendants, if they have not yet been frozen / stats computed,
1138                    // then use this bank as a representative for the fork.
1139                    descendants.iter().any(|d| {
1140                        progress
1141                            .get_fork_stats(*d)
1142                            .map(|stats| stats.computed)
1143                            .unwrap_or(false)
1144                    })
1145                }
1146                || *candidate_slot == last_voted_slot
1147                || *candidate_slot <= root
1148                || {
1149                    !self
1150                        .is_valid_switching_proof_vote(
1151                            *candidate_slot,
1152                            last_voted_slot,
1153                            switch_slot,
1154                            ancestors,
1155                            last_vote_ancestors,
1156                        )
1157                        .expect(
1158                            "candidate_slot and switch_slot exist in descendants map, so they \
1159                             must exist in ancestors map",
1160                        )
1161                }
1162            {
1163                continue;
1164            }
1165
1166            // By the time we reach here, any ancestors of the `last_vote`,
1167            // should have been filtered out, as they all have a descendant,
1168            // namely the `last_vote` itself.
1169            assert!(!last_vote_ancestors.contains(candidate_slot));
1170
1171            // Evaluate which vote accounts in the bank are locked out
1172            // in the interval candidate_slot..last_vote, which means
1173            // finding any lockout intervals in the `lockout_intervals` tree
1174            // for this bank that contain `last_vote`.
1175            let lockout_intervals = &progress
1176                .get(candidate_slot)
1177                .unwrap()
1178                .fork_stats
1179                .lockout_intervals;
1180            // Find any locked out intervals for vote accounts in this bank with
1181            // `lockout_interval_end` >= `last_vote`, which implies that the most recent tower slot is locked out
1182            // at `last_vote` on another fork. We also consider the remaining tower slots, however these older slots
1183            // could be from before the fork so we must filter by their ancestry.
1184            for LockoutInterval {
1185                start: lockout_interval_start,
1186                voter: vote_account_pubkey,
1187                ..
1188            } in lockout_intervals
1189                .iter()
1190                .filter(|interval| interval.end >= last_voted_slot)
1191            {
1192                if locked_out_vote_accounts.contains(vote_account_pubkey) {
1193                    continue;
1194                }
1195
1196                // Only count lockouts on slots that are:
1197                // 1) Not ancestors of `last_vote`, meaning being on different fork
1198                // 2) Not from before the current root as we can't determine if
1199                // anything before the root was an ancestor of `last_vote` or not
1200                if !last_vote_ancestors.contains(lockout_interval_start) && {
1201                    // Given a `lockout_interval_start` < root that appears in a
1202                    // bank for a `candidate_slot`, it must be that `lockout_interval_start`
1203                    // is an ancestor of the current root, because `candidate_slot` is a
1204                    // descendant of the current root
1205                    *lockout_interval_start > root
1206                } {
1207                    let stake = epoch_vote_accounts
1208                        .get(vote_account_pubkey)
1209                        .map(|(stake, _)| *stake)
1210                        .unwrap_or(0);
1211                    locked_out_stake += stake;
1212                    if (locked_out_stake as f64 / total_stake as f64) > SWITCH_FORK_THRESHOLD {
1213                        return SwitchForkDecision::SwitchProof(switch_proof);
1214                    }
1215                    locked_out_vote_accounts.insert(vote_account_pubkey);
1216                }
1217            }
1218        }
1219
1220        // Check the latest votes for potentially gossip votes that haven't landed yet
1221        for (
1222            vote_account_pubkey,
1223            (candidate_latest_frozen_vote, _candidate_latest_frozen_vote_hash),
1224        ) in latest_validator_votes_for_frozen_banks.max_gossip_frozen_votes()
1225        {
1226            if locked_out_vote_accounts.contains(&vote_account_pubkey) {
1227                continue;
1228            }
1229
1230            if *candidate_latest_frozen_vote > last_voted_slot && {
1231                // Because `candidate_latest_frozen_vote` is the last vote made by some validator
1232                // in the cluster for a frozen bank `B` observed through gossip, we may have cleared
1233                // that frozen bank `B` because we `set_root(root)` for a `root` on a different fork,
1234                // like so:
1235                //
1236                //    |----------X ------candidate_latest_frozen_vote (frozen)
1237                // old root
1238                //    |----------new root ----last_voted_slot
1239                //
1240                // In most cases, because `last_voted_slot` must be a descendant of `root`, then
1241                // if `candidate_latest_frozen_vote` is not found in the ancestors/descendants map (recall these
1242                // directly reflect the state of BankForks), this implies that `B` was pruned from BankForks
1243                // because it was on a different fork than `last_voted_slot`, and thus this vote for `candidate_latest_frozen_vote`
1244                // should be safe to count towards the switching proof:
1245                //
1246                // However, there is also the possibility that `last_voted_slot` is a stray, in which
1247                // case we cannot make this conclusion as we do not know the ancestors/descendants
1248                // of strays. Hence we err on the side of caution here and ignore this vote. This
1249                // is ok because validators voting on different unrooted forks should eventually vote
1250                // on some descendant of the root, at which time they can be included in switching proofs.
1251                self.is_valid_switching_proof_vote(
1252                    *candidate_latest_frozen_vote,
1253                    last_voted_slot,
1254                    switch_slot,
1255                    ancestors,
1256                    last_vote_ancestors,
1257                )
1258                .unwrap_or(false)
1259            } {
1260                let stake = epoch_vote_accounts
1261                    .get(vote_account_pubkey)
1262                    .map(|(stake, _)| *stake)
1263                    .unwrap_or(0);
1264                locked_out_stake += stake;
1265                if (locked_out_stake as f64 / total_stake as f64) > SWITCH_FORK_THRESHOLD {
1266                    return SwitchForkDecision::SwitchProof(switch_proof);
1267                }
1268                locked_out_vote_accounts.insert(vote_account_pubkey);
1269            }
1270        }
1271
1272        // We have not detected sufficient lockout past the last voted slot to generate
1273        // a switching proof
1274        SwitchForkDecision::FailedSwitchThreshold(locked_out_stake, total_stake)
1275    }
1276
1277    #[allow(clippy::too_many_arguments)]
1278    pub(crate) fn check_switch_threshold(
1279        &mut self,
1280        switch_slot: Slot,
1281        ancestors: &HashMap<Slot, HashSet<u64>>,
1282        descendants: &HashMap<Slot, HashSet<u64>>,
1283        progress: &ProgressMap,
1284        total_stake: u64,
1285        epoch_vote_accounts: &VoteAccountsHashMap,
1286        latest_validator_votes_for_frozen_banks: &LatestValidatorVotesForFrozenBanks,
1287        heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice,
1288    ) -> SwitchForkDecision {
1289        let decision = self.make_check_switch_threshold_decision(
1290            switch_slot,
1291            ancestors,
1292            descendants,
1293            progress,
1294            total_stake,
1295            epoch_vote_accounts,
1296            latest_validator_votes_for_frozen_banks,
1297            heaviest_subtree_fork_choice,
1298        );
1299        let new_check = Some((switch_slot, decision.clone()));
1300        if new_check != self.last_switch_threshold_check {
1301            trace!("new switch threshold check: slot {switch_slot}: {decision:?}",);
1302            self.last_switch_threshold_check = new_check;
1303        }
1304        decision
1305    }
1306
1307    fn is_first_switch_check(&self) -> bool {
1308        self.last_switch_threshold_check.is_none()
1309    }
1310
1311    // Optimistically skip the stake check if casting a vote would not increase
1312    // the lockout at this threshold. This is because if you bounce back to
1313    // voting on the main fork after not voting for a while, your latest vote
1314    // might pop off a lot of the votes in the tower. The stake from these votes
1315    // would have rolled up to earlier votes in the tower, which presumably
1316    // could have helped us pass the threshold check. Worst case, we'll just
1317    // recheck later without having increased lockouts.
1318    fn optimistically_bypass_vote_stake_threshold_check<'a>(
1319        tower_before_applying_vote: impl Iterator<Item = &'a Lockout>,
1320        threshold_vote: &Lockout,
1321    ) -> bool {
1322        for old_vote in tower_before_applying_vote {
1323            if old_vote.slot() == threshold_vote.slot()
1324                && old_vote.confirmation_count() == threshold_vote.confirmation_count()
1325            {
1326                return true;
1327            }
1328        }
1329        false
1330    }
1331
1332    /// Checks a single vote threshold for `slot`
1333    fn check_vote_stake_threshold<'a>(
1334        threshold_vote: Option<&Lockout>,
1335        tower_before_applying_vote: impl Iterator<Item = &'a Lockout>,
1336        threshold_depth: usize,
1337        threshold_size: f64,
1338        slot: Slot,
1339        voted_stakes: &VotedStakes,
1340        total_stake: u64,
1341    ) -> ThresholdDecision {
1342        let Some(threshold_vote) = threshold_vote else {
1343            // Tower isn't that deep.
1344            return ThresholdDecision::PassedThreshold;
1345        };
1346        let Some(fork_stake) = voted_stakes.get(&threshold_vote.slot()) else {
1347            // We haven't seen any votes on this fork yet, so no stake
1348            return ThresholdDecision::FailedThreshold(threshold_depth as u64, 0);
1349        };
1350
1351        let lockout = *fork_stake as f64 / total_stake as f64;
1352        trace!(
1353            "fork_stake slot: {}, threshold_vote slot: {}, lockout: {} fork_stake: {} \
1354             total_stake: {}",
1355            slot,
1356            threshold_vote.slot(),
1357            lockout,
1358            fork_stake,
1359            total_stake
1360        );
1361        if Self::optimistically_bypass_vote_stake_threshold_check(
1362            tower_before_applying_vote,
1363            threshold_vote,
1364        ) || lockout > threshold_size
1365        {
1366            return ThresholdDecision::PassedThreshold;
1367        }
1368        ThresholdDecision::FailedThreshold(threshold_depth as u64, *fork_stake)
1369    }
1370
1371    /// Performs vote threshold checks for `slot`
1372    pub fn check_vote_stake_thresholds(
1373        &self,
1374        slot: Slot,
1375        voted_stakes: &VotedStakes,
1376        total_stake: Stake,
1377    ) -> Vec<ThresholdDecision> {
1378        let mut threshold_decisions = vec![];
1379        // Generate the vote state assuming this vote is included.
1380        let mut vote_state = self.vote_state.clone();
1381        vote_state.process_next_vote_slot(slot);
1382
1383        // Assemble all the vote thresholds and depths to check.
1384        let vote_thresholds_and_depths = vec![
1385            // The following two checks are log only and are currently being used for experimentation
1386            // purposes. We wish to impose a shallow threshold check to prevent the frequent 8 deep
1387            // lockouts seen multiple times a day. We check both the 4th and 5th deep here to collect
1388            // metrics to determine the right depth and threshold percentage to set in the future.
1389            (VOTE_THRESHOLD_DEPTH_SHALLOW, SWITCH_FORK_THRESHOLD),
1390            (VOTE_THRESHOLD_DEPTH_SHALLOW + 1, SWITCH_FORK_THRESHOLD),
1391            (self.threshold_depth, self.threshold_size),
1392        ];
1393
1394        // Check one by one and add any failures to be returned
1395        for (threshold_depth, threshold_size) in vote_thresholds_and_depths {
1396            if let ThresholdDecision::FailedThreshold(vote_depth, stake) =
1397                Self::check_vote_stake_threshold(
1398                    vote_state.nth_recent_lockout(threshold_depth),
1399                    self.vote_state.votes.iter(),
1400                    threshold_depth,
1401                    threshold_size,
1402                    slot,
1403                    voted_stakes,
1404                    total_stake,
1405                )
1406            {
1407                threshold_decisions.push(ThresholdDecision::FailedThreshold(vote_depth, stake));
1408            }
1409        }
1410        threshold_decisions
1411    }
1412
1413    /// Update lockouts for all the ancestors
1414    pub(crate) fn populate_ancestor_voted_stakes(
1415        voted_stakes: &mut VotedStakes,
1416        vote_slots: impl IntoIterator<Item = Slot>,
1417        ancestors: &HashMap<Slot, HashSet<Slot>>,
1418    ) {
1419        // If there's no ancestors, that means this slot must be from before the current root,
1420        // in which case the lockouts won't be calculated in bank_weight anyways, so ignore
1421        // this slot
1422        for vote_slot in vote_slots {
1423            if let Some(slot_ancestors) = ancestors.get(&vote_slot) {
1424                voted_stakes.entry(vote_slot).or_default();
1425                for slot in slot_ancestors {
1426                    voted_stakes.entry(*slot).or_default();
1427                }
1428            }
1429        }
1430    }
1431
1432    /// Update stake for all the ancestors.
1433    /// Note, stake is the same for all the ancestor.
1434    fn update_ancestor_voted_stakes(
1435        voted_stakes: &mut VotedStakes,
1436        voted_slot: Slot,
1437        voted_stake: u64,
1438        ancestors: &HashMap<Slot, HashSet<Slot>>,
1439    ) {
1440        // If there's no ancestors, that means this slot must be from
1441        // before the current root, so ignore this slot
1442        if let Some(vote_slot_ancestors) = ancestors.get(&voted_slot) {
1443            *voted_stakes.entry(voted_slot).or_default() += voted_stake;
1444            for slot in vote_slot_ancestors {
1445                *voted_stakes.entry(*slot).or_default() += voted_stake;
1446            }
1447        }
1448    }
1449
1450    fn voted_slots(&self) -> Vec<Slot> {
1451        self.vote_state
1452            .votes
1453            .iter()
1454            .map(|lockout| lockout.slot())
1455            .collect()
1456    }
1457
1458    pub fn is_stray_last_vote(&self) -> bool {
1459        self.stray_restored_slot.is_some() && self.stray_restored_slot == self.last_voted_slot()
1460    }
1461
1462    // The tower root can be older/newer if the validator booted from a newer/older snapshot, so
1463    // tower lockouts may need adjustment
1464    pub fn adjust_lockouts_after_replay(
1465        mut self,
1466        replayed_root: Slot,
1467        slot_history: &SlotHistory,
1468    ) -> Result<Self> {
1469        // sanity assertions for roots
1470        let tower_root = self.root();
1471        info!(
1472            "adjusting lockouts (after replay up to {}): {:?} tower root: {} replayed root: {}",
1473            replayed_root,
1474            self.voted_slots(),
1475            tower_root,
1476            replayed_root,
1477        );
1478        assert_eq!(slot_history.check(replayed_root), Check::Found);
1479
1480        assert!(
1481            self.last_vote == VoteTransaction::from(VoteStateUpdate::default())
1482                && self.vote_state.votes.is_empty()
1483                || self.last_vote == VoteTransaction::from(TowerSync::default())
1484                    && self.vote_state.votes.is_empty()
1485                || !self.vote_state.votes.is_empty(),
1486            "last vote: {:?} vote_state.votes: {:?}",
1487            self.last_vote,
1488            self.vote_state.votes
1489        );
1490
1491        if let Some(last_voted_slot) = self.last_voted_slot() {
1492            if tower_root <= replayed_root {
1493                // Normally, we goes into this clause with possible help of
1494                // reconcile_blockstore_roots_with_external_source()
1495                if slot_history.check(last_voted_slot) == Check::TooOld {
1496                    // We could try hard to anchor with other older votes, but opt to simplify the
1497                    // following logic
1498                    return Err(TowerError::TooOldTower(
1499                        last_voted_slot,
1500                        slot_history.oldest(),
1501                    ));
1502                }
1503
1504                self.adjust_lockouts_with_slot_history(slot_history)?;
1505                self.initialize_root(replayed_root);
1506            } else {
1507                // This should never occur under normal operation.
1508                // While this validator's voting is suspended this way,
1509                // suspended_decision_due_to_major_unsynced_ledger() will be also touched.
1510                let message = format!(
1511                    "For some reason, we're REPROCESSING slots which has already been voted and \
1512                     ROOTED by us; VOTING will be SUSPENDED UNTIL {last_voted_slot}!",
1513                );
1514                error!("{message}");
1515                datapoint_error!("tower_error", ("error", message, String));
1516
1517                // Let's pass-through adjust_lockouts_with_slot_history just for sanitization,
1518                // using a synthesized SlotHistory.
1519
1520                let mut warped_slot_history = (*slot_history).clone();
1521                // Blockstore doesn't have the tower_root slot because of
1522                // (replayed_root < tower_root) in this else clause, meaning the tower is from
1523                // the future from the view of blockstore.
1524                // Pretend the blockstore has the future tower_root to anchor exactly with that
1525                // slot by adding tower_root to a slot history. The added slot will be newer
1526                // than all slots in the slot history (remember tower_root > replayed_root),
1527                // satisfying the slot history invariant.
1528                // Thus, the whole process will be safe as well because tower_root exists
1529                // within both tower and slot history, guaranteeing the success of adjustment
1530                // and retaining all of future votes correctly while sanitizing.
1531                warped_slot_history.add(tower_root);
1532
1533                self.adjust_lockouts_with_slot_history(&warped_slot_history)?;
1534                // don't update root; future tower's root should be kept across validator
1535                // restarts to continue to show the scary messages at restarts until the next
1536                // voting.
1537            }
1538        } else {
1539            // This else clause is for newly created tower.
1540            // initialize_lockouts_from_bank() should ensure the following invariant,
1541            // otherwise we're screwing something up.
1542            assert_eq!(tower_root, replayed_root);
1543        }
1544
1545        Ok(self)
1546    }
1547
1548    fn adjust_lockouts_with_slot_history(&mut self, slot_history: &SlotHistory) -> Result<()> {
1549        let tower_root = self.root();
1550        // retained slots will be consisted only from divergent slots
1551        let mut retain_flags_for_each_vote_in_reverse: Vec<_> =
1552            Vec::with_capacity(self.vote_state.votes.len());
1553
1554        let mut still_in_future = true;
1555        let mut past_outside_history = false;
1556        let mut checked_slot = None;
1557        let mut anchored_slot = None;
1558
1559        let mut slots_in_tower = vec![tower_root];
1560        slots_in_tower.extend(self.voted_slots());
1561
1562        // iterate over votes + root (if any) in the newest => oldest order
1563        // bail out early if bad condition is found
1564        for slot_in_tower in slots_in_tower.iter().rev() {
1565            let check = slot_history.check(*slot_in_tower);
1566
1567            if anchored_slot.is_none() && check == Check::Found {
1568                anchored_slot = Some(*slot_in_tower);
1569            } else if anchored_slot.is_some() && check == Check::NotFound {
1570                // this can't happen unless we're fed with bogus snapshot
1571                return Err(TowerError::FatallyInconsistent("diverged ancestor?"));
1572            }
1573
1574            if still_in_future && check != Check::Future {
1575                still_in_future = false;
1576            } else if !still_in_future && check == Check::Future {
1577                // really odd cases: bad ordered votes?
1578                return Err(TowerError::FatallyInconsistent("time warped?"));
1579            }
1580            if !past_outside_history && check == Check::TooOld {
1581                past_outside_history = true;
1582            } else if past_outside_history && check != Check::TooOld {
1583                // really odd cases: bad ordered votes?
1584                return Err(TowerError::FatallyInconsistent(
1585                    "not too old once after got too old?",
1586                ));
1587            }
1588
1589            if let Some(checked_slot) = checked_slot {
1590                // This is really special, only if tower is initialized and contains
1591                // a vote for the root, the root slot can repeat only once
1592                let voting_for_root =
1593                    *slot_in_tower == checked_slot && *slot_in_tower == tower_root;
1594
1595                if !voting_for_root {
1596                    // Unless we're voting since genesis, slots_in_tower must always be older than last checked_slot
1597                    // including all vote slot and the root slot.
1598                    assert!(
1599                        *slot_in_tower < checked_slot,
1600                        "slot_in_tower({}) < checked_slot({})",
1601                        *slot_in_tower,
1602                        checked_slot
1603                    );
1604                }
1605            }
1606
1607            checked_slot = Some(*slot_in_tower);
1608
1609            retain_flags_for_each_vote_in_reverse.push(anchored_slot.is_none());
1610        }
1611
1612        // Check for errors if not anchored
1613        info!("adjusted tower's anchored slot: {anchored_slot:?}");
1614        if anchored_slot.is_none() {
1615            // this error really shouldn't happen unless ledger/tower is corrupted
1616            return Err(TowerError::FatallyInconsistent(
1617                "no common slot for rooted tower",
1618            ));
1619        }
1620
1621        assert_eq!(
1622            slots_in_tower.len(),
1623            retain_flags_for_each_vote_in_reverse.len()
1624        );
1625        // pop for the tower root
1626        retain_flags_for_each_vote_in_reverse.pop();
1627        let mut retain_flags_for_each_vote =
1628            retain_flags_for_each_vote_in_reverse.into_iter().rev();
1629
1630        let original_votes_len = self.vote_state.votes.len();
1631        self.initialize_lockouts(move |_| retain_flags_for_each_vote.next().unwrap());
1632
1633        if self.vote_state.votes.is_empty() {
1634            info!("All restored votes were behind; resetting root_slot and last_vote in tower!");
1635            // we might not have banks for those votes so just reset.
1636            // That's because the votes may well past replayed_root
1637            self.last_vote = VoteTransaction::from(Vote::default());
1638        } else {
1639            info!(
1640                "{} restored votes (out of {}) were on different fork or are upcoming votes on \
1641                 unrooted slots: {:?}!",
1642                self.voted_slots().len(),
1643                original_votes_len,
1644                self.voted_slots()
1645            );
1646
1647            assert_eq!(self.last_voted_slot(), self.voted_slots().last().copied());
1648            self.stray_restored_slot = self.last_vote.last_voted_slot()
1649        }
1650
1651        Ok(())
1652    }
1653
1654    fn initialize_lockouts_from_bank(
1655        &mut self,
1656        vote_account_pubkey: &Pubkey,
1657        root: Slot,
1658        bank: &Bank,
1659    ) {
1660        if let Some(vote_account) = bank.get_vote_account(vote_account_pubkey) {
1661            self.vote_state = TowerVoteState::from(vote_account.vote_state_view());
1662            self.initialize_root(root);
1663            self.initialize_lockouts(|v| v.slot() > root);
1664        } else {
1665            self.initialize_root(root);
1666            info!(
1667                "vote account({}) not found in bank (slot={})",
1668                vote_account_pubkey,
1669                bank.slot()
1670            );
1671        }
1672    }
1673
1674    fn initialize_lockouts<F: FnMut(&Lockout) -> bool>(&mut self, should_retain: F) {
1675        self.vote_state.votes.retain(should_retain);
1676    }
1677
1678    // Updating root is needed to correctly restore from newly-saved tower for the next
1679    // boot
1680    fn initialize_root(&mut self, root: Slot) {
1681        self.vote_state.root_slot = Some(root);
1682    }
1683
1684    pub fn save(&self, tower_storage: &dyn TowerStorage, node_keypair: &Keypair) -> Result<()> {
1685        let saved_tower = SavedTower::new(self, node_keypair)?;
1686        tower_storage.store(&SavedTowerVersions::from(saved_tower))?;
1687        Ok(())
1688    }
1689
1690    pub fn restore(tower_storage: &dyn TowerStorage, node_pubkey: &Pubkey) -> Result<Self> {
1691        tower_storage.load(node_pubkey)
1692    }
1693}
1694
1695#[derive(Error, Debug)]
1696pub enum TowerError {
1697    #[error("IO Error: {0}")]
1698    IoError(#[from] std::io::Error),
1699
1700    #[error("Serialization Error: {0}")]
1701    SerializeError(#[from] bincode::Error),
1702
1703    #[error("The signature on the saved tower is invalid")]
1704    InvalidSignature,
1705
1706    #[error("The tower does not match this validator: {0}")]
1707    WrongTower(String),
1708
1709    #[error(
1710        "The tower is too old: newest slot in tower ({0}) << oldest slot in available history \
1711         ({1})"
1712    )]
1713    TooOldTower(Slot, Slot),
1714
1715    #[error("The tower is fatally inconsistent with blockstore: {0}")]
1716    FatallyInconsistent(&'static str),
1717
1718    #[error("The tower is useless because of new hard fork: {0}")]
1719    HardFork(Slot),
1720}
1721
1722impl TowerError {
1723    pub fn is_file_missing(&self) -> bool {
1724        if let TowerError::IoError(io_err) = &self {
1725            io_err.kind() == std::io::ErrorKind::NotFound
1726        } else {
1727            false
1728        }
1729    }
1730    pub fn is_too_old(&self) -> bool {
1731        matches!(self, TowerError::TooOldTower(_, _))
1732    }
1733}
1734
1735#[derive(Debug)]
1736pub enum ExternalRootSource {
1737    Tower(Slot),
1738    VoteHistory(Slot),
1739    HardFork(Slot),
1740}
1741
1742impl ExternalRootSource {
1743    fn root(&self) -> Slot {
1744        match self {
1745            ExternalRootSource::Tower(slot) => *slot,
1746            ExternalRootSource::VoteHistory(slot) => *slot,
1747            ExternalRootSource::HardFork(slot) => *slot,
1748        }
1749    }
1750}
1751
1752// Given an untimely crash, tower may have roots that are not reflected in blockstore,
1753// or the reverse of this.
1754// That's because we don't impose any ordering guarantee or any kind of write barriers
1755// between tower (plain old POSIX fs calls) and blockstore (through RocksDB), when
1756// `ReplayState::handle_votable_bank()` saves tower before setting blockstore roots.
1757pub fn reconcile_blockstore_roots_with_external_source(
1758    external_source: ExternalRootSource,
1759    blockstore: &Blockstore,
1760    // blockstore.max_root() might have been updated already.
1761    // so take a &mut param both to input (and output iff we update root)
1762    last_blockstore_root: &mut Slot,
1763) -> blockstore::Result<()> {
1764    let external_root = external_source.root();
1765    if *last_blockstore_root < external_root {
1766        // Ensure external_root itself to exist and be marked as rooted in the blockstore
1767        // in addition to its ancestors.
1768        let new_roots: Vec<_> = AncestorIterator::new_inclusive(external_root, blockstore)
1769            .take_while(|current| match current.cmp(last_blockstore_root) {
1770                Ordering::Greater => true,
1771                Ordering::Equal => false,
1772                Ordering::Less => panic!(
1773                    "last_blockstore_root({last_blockstore_root}) is skipped while traversing \
1774                     blockstore (currently at {current}) from external root \
1775                     ({external_source:?})!?",
1776                ),
1777            })
1778            .collect();
1779        if !new_roots.is_empty() {
1780            info!(
1781                "Reconciling slots as root based on external root: {new_roots:?} (external: \
1782                 {external_source:?}, blockstore: {last_blockstore_root})"
1783            );
1784
1785            // Unfortunately, we can't supply duplicate-confirmed hashes,
1786            // because it can't be guaranteed to be able to replay these slots
1787            // under this code-path's limited condition (i.e.  those shreds
1788            // might not be available, etc...) also correctly overcoming this
1789            // limitation is hard...
1790            blockstore.mark_slots_as_if_rooted_normally_at_startup(
1791                new_roots.into_iter().map(|root| (root, None)).collect(),
1792                false,
1793            )?;
1794
1795            // Update the caller-managed state of last root in blockstore.
1796            // Repeated calls of this function should result in a no-op for
1797            // the range of `new_roots`.
1798            *last_blockstore_root = blockstore.max_root();
1799        } else {
1800            // This indicates we're in bad state; but still don't panic here.
1801            // That's because we might have a chance of recovering properly with
1802            // newer snapshot.
1803            warn!(
1804                "Couldn't find any ancestor slots from external source ({external_source:?}) \
1805                 towards blockstore root ({last_blockstore_root}); blockstore pruned or only \
1806                 tower moved into new ledger or just hard fork?",
1807            );
1808        }
1809    }
1810    Ok(())
1811}
1812
1813#[cfg(test)]
1814pub mod test {
1815    use {
1816        super::*,
1817        crate::{
1818            consensus::{
1819                fork_choice::ForkChoice, heaviest_subtree_fork_choice::SlotHashKey,
1820                tower_storage::FileTowerStorage,
1821            },
1822            replay_stage::HeaviestForkFailures,
1823            vote_simulator::VoteSimulator,
1824        },
1825        itertools::Itertools,
1826        solana_account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
1827        solana_clock::Slot,
1828        solana_hash::Hash,
1829        solana_ledger::{blockstore::make_slot_entries, get_tmp_ledger_path_auto_delete},
1830        solana_pubkey::Pubkey,
1831        solana_runtime::bank::Bank,
1832        solana_signer::Signer,
1833        solana_slot_history::SlotHistory,
1834        solana_vote::vote_account::VoteAccount,
1835        solana_vote_program::vote_state::{
1836            MAX_LOCKOUT_HISTORY, Vote, VoteStateV4, VoteStateVersions, handler::VoteStateHandler,
1837            process_slot_vote_unchecked,
1838        },
1839        std::{
1840            collections::{HashMap, VecDeque},
1841            fs::{OpenOptions, remove_file},
1842            io::{Read, Seek, SeekFrom, Write},
1843            path::PathBuf,
1844            sync::Arc,
1845        },
1846        tempfile::TempDir,
1847        trees::tr,
1848    };
1849
1850    fn gen_stakes(stake_votes: &[(u64, &[u64])]) -> VoteAccountsHashMap {
1851        stake_votes
1852            .iter()
1853            .map(|(lamports, votes)| {
1854                let mut account = AccountSharedData::from(Account {
1855                    data: vec![0; VoteStateV4::size_of()],
1856                    lamports: *lamports,
1857                    owner: solana_vote_program::id(),
1858                    ..Account::default()
1859                });
1860                let mut vote_state = VoteStateHandler::new_v4(VoteStateV4::default());
1861                for slot in *votes {
1862                    process_slot_vote_unchecked(&mut vote_state, *slot);
1863                }
1864                VoteStateV4::serialize(
1865                    &VoteStateVersions::new_v4(vote_state.unwrap_v4()),
1866                    account.data_as_mut_slice(),
1867                )
1868                .expect("serialize state");
1869                (
1870                    solana_pubkey::new_rand(),
1871                    (*lamports, VoteAccount::try_from(account).unwrap()),
1872                )
1873            })
1874            .collect()
1875    }
1876
1877    #[test]
1878    fn test_to_vote_instruction() {
1879        let vote = Vote::default();
1880        let mut decision = SwitchForkDecision::FailedSwitchThreshold(0, 1);
1881        assert!(
1882            decision
1883                .to_vote_instruction(
1884                    VoteTransaction::from(vote.clone()),
1885                    &Pubkey::default(),
1886                    &Pubkey::default()
1887                )
1888                .is_none()
1889        );
1890
1891        decision = SwitchForkDecision::FailedSwitchDuplicateRollback(0);
1892        assert!(
1893            decision
1894                .to_vote_instruction(
1895                    VoteTransaction::from(vote.clone()),
1896                    &Pubkey::default(),
1897                    &Pubkey::default()
1898                )
1899                .is_none()
1900        );
1901
1902        decision = SwitchForkDecision::SameFork;
1903        assert_eq!(
1904            decision.to_vote_instruction(
1905                VoteTransaction::from(vote.clone()),
1906                &Pubkey::default(),
1907                &Pubkey::default()
1908            ),
1909            Some(vote_instruction::vote(
1910                &Pubkey::default(),
1911                &Pubkey::default(),
1912                vote.clone(),
1913            ))
1914        );
1915
1916        decision = SwitchForkDecision::SwitchProof(Hash::default());
1917        assert_eq!(
1918            decision.to_vote_instruction(
1919                VoteTransaction::from(vote.clone()),
1920                &Pubkey::default(),
1921                &Pubkey::default()
1922            ),
1923            Some(vote_instruction::vote_switch(
1924                &Pubkey::default(),
1925                &Pubkey::default(),
1926                vote,
1927                Hash::default()
1928            ))
1929        );
1930    }
1931
1932    #[test]
1933    fn test_simple_votes() {
1934        // Init state
1935        let mut vote_simulator = VoteSimulator::new(1);
1936        let node_pubkey = vote_simulator.node_pubkeys[0];
1937        let mut tower = Tower::default();
1938
1939        // Create the tree of banks
1940        let forks = tr(0) / (tr(1) / (tr(2) / (tr(3) / (tr(4) / tr(5)))));
1941
1942        // Set the voting behavior
1943        let mut cluster_votes = HashMap::new();
1944        let votes = vec![1, 2, 3, 4, 5];
1945        cluster_votes.insert(node_pubkey, votes.clone());
1946        vote_simulator.fill_bank_forks(forks, &cluster_votes, true);
1947
1948        // Simulate the votes
1949        for vote in votes {
1950            assert!(
1951                vote_simulator
1952                    .simulate_vote(vote, &node_pubkey, &mut tower,)
1953                    .is_empty()
1954            );
1955        }
1956
1957        for i in 1..5 {
1958            assert_eq!(tower.vote_state.votes[i - 1].slot() as usize, i);
1959            assert_eq!(
1960                tower.vote_state.votes[i - 1].confirmation_count() as usize,
1961                6 - i
1962            );
1963        }
1964    }
1965
1966    #[test]
1967    fn test_switch_threshold_duplicate_rollback() {
1968        run_test_switch_threshold_duplicate_rollback(false);
1969    }
1970
1971    #[test]
1972    #[should_panic]
1973    fn test_switch_threshold_duplicate_rollback_panic() {
1974        run_test_switch_threshold_duplicate_rollback(true);
1975    }
1976
1977    fn setup_switch_test(num_accounts: usize) -> (Arc<Bank>, VoteSimulator, u64) {
1978        // Init state
1979        assert!(num_accounts > 1);
1980        let mut vote_simulator = VoteSimulator::new(num_accounts);
1981        let bank0 = vote_simulator.bank_forks.read().unwrap().get(0).unwrap();
1982        let total_stake = bank0.total_epoch_stake();
1983        assert_eq!(
1984            total_stake,
1985            vote_simulator.validator_keypairs.len() as u64 * 10_000
1986        );
1987
1988        // Create the tree of banks
1989        let forks = tr(0)
1990            / (tr(1)
1991                / (tr(2)
1992                    // Minor fork 1
1993                    / (tr(10) / (tr(11) / (tr(12) / (tr(13) / (tr(14))))))
1994                    / (tr(43)
1995                        / (tr(44)
1996                            // Minor fork 2
1997                            / (tr(45) / (tr(46) / (tr(47) / (tr(48) / (tr(49) / (tr(50)))))))
1998                            / (tr(110)))
1999                        / tr(112))));
2000
2001        // Fill the BankForks according to the above fork structure
2002        vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
2003        for fork_progress in vote_simulator.progress.values_mut() {
2004            fork_progress.fork_stats.computed = true;
2005        }
2006
2007        (bank0, vote_simulator, total_stake)
2008    }
2009
2010    fn run_test_switch_threshold_duplicate_rollback(should_panic: bool) {
2011        let (bank0, mut vote_simulator, total_stake) = setup_switch_test(2);
2012        let ancestors = vote_simulator.bank_forks.read().unwrap().ancestors();
2013        let descendants = vote_simulator.bank_forks.read().unwrap().descendants();
2014        let mut tower = Tower::default();
2015
2016        // Last vote is 47
2017        tower.record_vote(
2018            47,
2019            vote_simulator
2020                .bank_forks
2021                .read()
2022                .unwrap()
2023                .get(47)
2024                .unwrap()
2025                .hash(),
2026        );
2027
2028        // Trying to switch to an ancestor of last vote should only not panic
2029        // if the current vote has a duplicate ancestor
2030        let ancestor_of_voted_slot = 43;
2031        let duplicate_ancestor1 = 44;
2032        let duplicate_ancestor2 = 45;
2033        vote_simulator
2034            .tbft_structs
2035            .heaviest_subtree_fork_choice
2036            .mark_fork_invalid_candidate(&(
2037                duplicate_ancestor1,
2038                vote_simulator
2039                    .bank_forks
2040                    .read()
2041                    .unwrap()
2042                    .get(duplicate_ancestor1)
2043                    .unwrap()
2044                    .hash(),
2045            ));
2046        vote_simulator
2047            .tbft_structs
2048            .heaviest_subtree_fork_choice
2049            .mark_fork_invalid_candidate(&(
2050                duplicate_ancestor2,
2051                vote_simulator
2052                    .bank_forks
2053                    .read()
2054                    .unwrap()
2055                    .get(duplicate_ancestor2)
2056                    .unwrap()
2057                    .hash(),
2058            ));
2059        assert_eq!(
2060            tower.check_switch_threshold(
2061                ancestor_of_voted_slot,
2062                &ancestors,
2063                &descendants,
2064                &vote_simulator.progress,
2065                total_stake,
2066                bank0.epoch_vote_accounts(0).unwrap(),
2067                &vote_simulator.latest_validator_votes_for_frozen_banks,
2068                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2069            ),
2070            SwitchForkDecision::FailedSwitchDuplicateRollback(duplicate_ancestor2)
2071        );
2072        let mut confirm_ancestors = vec![duplicate_ancestor1];
2073        if should_panic {
2074            // Adding the last duplicate ancestor will
2075            // 1) Cause loop below to confirm last ancestor
2076            // 2) Check switch threshold on a vote ancestor when there
2077            // are no duplicates on that fork, which will cause a panic
2078            confirm_ancestors.push(duplicate_ancestor2);
2079        }
2080        for (i, duplicate_ancestor) in confirm_ancestors.into_iter().enumerate() {
2081            vote_simulator
2082                .tbft_structs
2083                .heaviest_subtree_fork_choice
2084                .mark_fork_valid_candidate(&(
2085                    duplicate_ancestor,
2086                    vote_simulator
2087                        .bank_forks
2088                        .read()
2089                        .unwrap()
2090                        .get(duplicate_ancestor)
2091                        .unwrap()
2092                        .hash(),
2093                ));
2094            let res = tower.check_switch_threshold(
2095                ancestor_of_voted_slot,
2096                &ancestors,
2097                &descendants,
2098                &vote_simulator.progress,
2099                total_stake,
2100                bank0.epoch_vote_accounts(0).unwrap(),
2101                &vote_simulator.latest_validator_votes_for_frozen_banks,
2102                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2103            );
2104            if i == 0 {
2105                assert_eq!(
2106                    res,
2107                    SwitchForkDecision::FailedSwitchDuplicateRollback(duplicate_ancestor2)
2108                );
2109            }
2110        }
2111    }
2112
2113    #[test]
2114    fn test_switch_threshold() {
2115        let (bank0, mut vote_simulator, total_stake) = setup_switch_test(2);
2116        let ancestors = vote_simulator.bank_forks.read().unwrap().ancestors();
2117        let mut descendants = vote_simulator.bank_forks.read().unwrap().descendants();
2118        let mut tower = Tower::default();
2119        let other_vote_account = vote_simulator.vote_pubkeys[1];
2120
2121        // Last vote is 47
2122        tower.record_vote(47, Hash::default());
2123
2124        // Trying to switch to a descendant of last vote should always work
2125        assert_eq!(
2126            tower.check_switch_threshold(
2127                48,
2128                &ancestors,
2129                &descendants,
2130                &vote_simulator.progress,
2131                total_stake,
2132                bank0.epoch_vote_accounts(0).unwrap(),
2133                &vote_simulator.latest_validator_votes_for_frozen_banks,
2134                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2135            ),
2136            SwitchForkDecision::SameFork
2137        );
2138
2139        // Trying to switch to another fork at 110 should fail
2140        assert_eq!(
2141            tower.check_switch_threshold(
2142                110,
2143                &ancestors,
2144                &descendants,
2145                &vote_simulator.progress,
2146                total_stake,
2147                bank0.epoch_vote_accounts(0).unwrap(),
2148                &vote_simulator.latest_validator_votes_for_frozen_banks,
2149                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2150            ),
2151            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
2152        );
2153
2154        // Adding another validator lockout on a descendant of last vote should
2155        // not count toward the switch threshold
2156        vote_simulator.simulate_lockout_interval(50, (49, 100), &other_vote_account);
2157        assert_eq!(
2158            tower.check_switch_threshold(
2159                110,
2160                &ancestors,
2161                &descendants,
2162                &vote_simulator.progress,
2163                total_stake,
2164                bank0.epoch_vote_accounts(0).unwrap(),
2165                &vote_simulator.latest_validator_votes_for_frozen_banks,
2166                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2167            ),
2168            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
2169        );
2170
2171        // Adding another validator lockout on an ancestor of last vote should
2172        // not count toward the switch threshold
2173        vote_simulator.simulate_lockout_interval(50, (45, 100), &other_vote_account);
2174        assert_eq!(
2175            tower.check_switch_threshold(
2176                110,
2177                &ancestors,
2178                &descendants,
2179                &vote_simulator.progress,
2180                total_stake,
2181                bank0.epoch_vote_accounts(0).unwrap(),
2182                &vote_simulator.latest_validator_votes_for_frozen_banks,
2183                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2184            ),
2185            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
2186        );
2187
2188        // Adding another validator lockout on a different fork, but the lockout
2189        // doesn't cover the last vote, should not satisfy the switch threshold
2190        vote_simulator.simulate_lockout_interval(14, (12, 46), &other_vote_account);
2191        assert_eq!(
2192            tower.check_switch_threshold(
2193                110,
2194                &ancestors,
2195                &descendants,
2196                &vote_simulator.progress,
2197                total_stake,
2198                bank0.epoch_vote_accounts(0).unwrap(),
2199                &vote_simulator.latest_validator_votes_for_frozen_banks,
2200                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2201            ),
2202            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
2203        );
2204
2205        // Adding another validator lockout on a different fork, and the lockout
2206        // covers the last vote would count towards the switch threshold,
2207        // unless the bank is not the most recent frozen bank on the fork (14 is a
2208        // frozen/computed bank > 13 on the same fork in this case)
2209        vote_simulator.simulate_lockout_interval(13, (12, 47), &other_vote_account);
2210        assert_eq!(
2211            tower.check_switch_threshold(
2212                110,
2213                &ancestors,
2214                &descendants,
2215                &vote_simulator.progress,
2216                total_stake,
2217                bank0.epoch_vote_accounts(0).unwrap(),
2218                &vote_simulator.latest_validator_votes_for_frozen_banks,
2219                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2220            ),
2221            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
2222        );
2223
2224        // Adding another validator lockout on a different fork, and the lockout
2225        // covers the last vote, should satisfy the switch threshold
2226        vote_simulator.simulate_lockout_interval(14, (12, 47), &other_vote_account);
2227        assert_eq!(
2228            tower.check_switch_threshold(
2229                110,
2230                &ancestors,
2231                &descendants,
2232                &vote_simulator.progress,
2233                total_stake,
2234                bank0.epoch_vote_accounts(0).unwrap(),
2235                &vote_simulator.latest_validator_votes_for_frozen_banks,
2236                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2237            ),
2238            SwitchForkDecision::SwitchProof(Hash::default())
2239        );
2240
2241        // Adding another unfrozen descendant of the tip of 14 should not remove
2242        // slot 14 from consideration because it is still the most recent frozen
2243        // bank on its fork
2244        descendants.get_mut(&14).unwrap().insert(10000);
2245        assert_eq!(
2246            tower.check_switch_threshold(
2247                110,
2248                &ancestors,
2249                &descendants,
2250                &vote_simulator.progress,
2251                total_stake,
2252                bank0.epoch_vote_accounts(0).unwrap(),
2253                &vote_simulator.latest_validator_votes_for_frozen_banks,
2254                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2255            ),
2256            SwitchForkDecision::SwitchProof(Hash::default())
2257        );
2258
2259        // If we set a root, then any lockout intervals below the root shouldn't
2260        // count toward the switch threshold. This means the other validator's
2261        // vote lockout no longer counts
2262        tower.vote_state.root_slot = Some(43);
2263        // Refresh ancestors and descendants for new root.
2264        let ancestors = vote_simulator.bank_forks.read().unwrap().ancestors();
2265        let descendants = vote_simulator.bank_forks.read().unwrap().descendants();
2266
2267        assert_eq!(
2268            tower.check_switch_threshold(
2269                110,
2270                &ancestors,
2271                &descendants,
2272                &vote_simulator.progress,
2273                total_stake,
2274                bank0.epoch_vote_accounts(0).unwrap(),
2275                &vote_simulator.latest_validator_votes_for_frozen_banks,
2276                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2277            ),
2278            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
2279        );
2280    }
2281
2282    #[test]
2283    fn test_switch_threshold_use_gossip_votes() {
2284        let num_validators = 2;
2285        let (bank0, mut vote_simulator, total_stake) = setup_switch_test(2);
2286        let ancestors = vote_simulator.bank_forks.read().unwrap().ancestors();
2287        let descendants = vote_simulator.bank_forks.read().unwrap().descendants();
2288        let mut tower = Tower::default();
2289        let other_vote_account = vote_simulator.vote_pubkeys[1];
2290
2291        // Last vote is 47
2292        tower.record_vote(47, Hash::default());
2293
2294        // Trying to switch to another fork at 110 should fail
2295        assert_eq!(
2296            tower.check_switch_threshold(
2297                110,
2298                &ancestors,
2299                &descendants,
2300                &vote_simulator.progress,
2301                total_stake,
2302                bank0.epoch_vote_accounts(0).unwrap(),
2303                &vote_simulator.latest_validator_votes_for_frozen_banks,
2304                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2305            ),
2306            SwitchForkDecision::FailedSwitchThreshold(0, num_validators * 10000)
2307        );
2308
2309        // Adding a vote on the descendant shouldn't count toward the switch threshold
2310        vote_simulator.simulate_lockout_interval(50, (49, 100), &other_vote_account);
2311        assert_eq!(
2312            tower.check_switch_threshold(
2313                110,
2314                &ancestors,
2315                &descendants,
2316                &vote_simulator.progress,
2317                total_stake,
2318                bank0.epoch_vote_accounts(0).unwrap(),
2319                &vote_simulator.latest_validator_votes_for_frozen_banks,
2320                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2321            ),
2322            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
2323        );
2324
2325        // Adding a later vote from gossip that isn't on the same fork should count toward the
2326        // switch threshold
2327        vote_simulator
2328            .latest_validator_votes_for_frozen_banks
2329            .check_add_vote(
2330                other_vote_account,
2331                112,
2332                Some(
2333                    vote_simulator
2334                        .bank_forks
2335                        .read()
2336                        .unwrap()
2337                        .get(112)
2338                        .unwrap()
2339                        .hash(),
2340                ),
2341                false,
2342            );
2343
2344        assert_eq!(
2345            tower.check_switch_threshold(
2346                110,
2347                &ancestors,
2348                &descendants,
2349                &vote_simulator.progress,
2350                total_stake,
2351                bank0.epoch_vote_accounts(0).unwrap(),
2352                &vote_simulator.latest_validator_votes_for_frozen_banks,
2353                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2354            ),
2355            SwitchForkDecision::SwitchProof(Hash::default())
2356        );
2357
2358        // If we now set a root that causes slot 112 to be purged from BankForks, then
2359        // the switch proof will now fail since that validator's vote can no longer be
2360        // included in the switching proof
2361        vote_simulator.set_root(44);
2362        let ancestors = vote_simulator.bank_forks.read().unwrap().ancestors();
2363        let descendants = vote_simulator.bank_forks.read().unwrap().descendants();
2364        assert_eq!(
2365            tower.check_switch_threshold(
2366                110,
2367                &ancestors,
2368                &descendants,
2369                &vote_simulator.progress,
2370                total_stake,
2371                bank0.epoch_vote_accounts(0).unwrap(),
2372                &vote_simulator.latest_validator_votes_for_frozen_banks,
2373                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
2374            ),
2375            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
2376        );
2377    }
2378
2379    #[test]
2380    fn test_switch_threshold_votes() {
2381        // Init state
2382        let mut vote_simulator = VoteSimulator::new(4);
2383        let node_pubkey = vote_simulator.node_pubkeys[0];
2384        let mut tower = Tower::default();
2385        let forks = tr(0)
2386            / (tr(1)
2387                / (tr(2)
2388                    // Minor fork 1
2389                    / (tr(10) / (tr(11) / (tr(12) / (tr(13) / (tr(14))))))
2390                    / (tr(43)
2391                        / (tr(44)
2392                            // Minor fork 2
2393                            / (tr(45) / (tr(46))))
2394                        / (tr(110)))));
2395
2396        // Have two validators, each representing 20% of the stake vote on
2397        // minor fork 2 at slots 46 + 47
2398        let mut cluster_votes: HashMap<Pubkey, Vec<Slot>> = HashMap::new();
2399        cluster_votes.insert(vote_simulator.node_pubkeys[1], vec![46]);
2400        cluster_votes.insert(vote_simulator.node_pubkeys[2], vec![47]);
2401        vote_simulator.fill_bank_forks(forks, &cluster_votes, true);
2402
2403        // Vote on the first minor fork at slot 14, should succeed
2404        assert!(
2405            vote_simulator
2406                .simulate_vote(14, &node_pubkey, &mut tower,)
2407                .is_empty()
2408        );
2409
2410        // The other two validators voted at slots 46, 47, which
2411        // will only both show up in slot 48, at which point
2412        // 2/5 > SWITCH_FORK_THRESHOLD of the stake has voted
2413        // on another fork, so switching should succeed
2414        let votes_to_simulate = (46..=48).collect();
2415        let results = vote_simulator.create_and_vote_new_branch(
2416            45,
2417            48,
2418            &cluster_votes,
2419            &votes_to_simulate,
2420            &node_pubkey,
2421            &mut tower,
2422        );
2423        assert_eq!(
2424            *results.get(&46).unwrap(),
2425            vec![HeaviestForkFailures::FailedSwitchThreshold(46, 0, 40000)]
2426        );
2427        assert_eq!(
2428            *results.get(&47).unwrap(),
2429            vec![HeaviestForkFailures::FailedSwitchThreshold(
2430                47, 10000, 40000
2431            )]
2432        );
2433        assert!(results.get(&48).unwrap().is_empty());
2434    }
2435
2436    #[test]
2437    fn test_double_partition() {
2438        // Init state
2439        let mut vote_simulator = VoteSimulator::new(2);
2440        let node_pubkey = vote_simulator.node_pubkeys[0];
2441        let vote_pubkey = vote_simulator.vote_pubkeys[0];
2442        let mut tower = Tower::default();
2443
2444        let num_slots_to_try = 200;
2445        // Create the tree of banks
2446        let forks = tr(0)
2447            / (tr(1)
2448                / (tr(2)
2449                    / (tr(3)
2450                        / (tr(4)
2451                            / (tr(5)
2452                                / (tr(6)
2453                                    / (tr(7)
2454                                        / (tr(8)
2455                                            / (tr(9)
2456                                                // Minor fork 1
2457                                                / (tr(10) / (tr(11) / (tr(12) / (tr(13) / (tr(14))))))
2458                                                / (tr(43)
2459                                                    / (tr(44)
2460                                                        // Minor fork 2
2461                                                        / (tr(45) / (tr(46) / (tr(47) / (tr(48) / (tr(49) / (tr(50)))))))
2462                                                        / (tr(110) / (tr(110 + 2 * num_slots_to_try))))))))))))));
2463
2464        // Set the successful voting behavior
2465        let mut cluster_votes = HashMap::new();
2466        let mut my_votes: Vec<Slot> = vec![];
2467        let next_unlocked_slot = 110;
2468        // Vote on the first minor fork
2469        my_votes.extend(1..=14);
2470        // Come back to the main fork
2471        my_votes.extend(43..=44);
2472        // Vote on the second minor fork
2473        my_votes.extend(45..=50);
2474        // Vote to come back to main fork
2475        my_votes.push(next_unlocked_slot);
2476        cluster_votes.insert(node_pubkey, my_votes.clone());
2477        // Make the other validator vote fork to pass the threshold checks
2478        let other_votes = my_votes.clone();
2479        cluster_votes.insert(vote_simulator.node_pubkeys[1], other_votes);
2480        vote_simulator.fill_bank_forks(forks, &cluster_votes, true);
2481
2482        // Simulate the votes.
2483        for vote in &my_votes {
2484            // All these votes should be ok
2485            assert!(
2486                vote_simulator
2487                    .simulate_vote(*vote, &node_pubkey, &mut tower,)
2488                    .is_empty()
2489            );
2490        }
2491
2492        info!("local tower: {:#?}", tower.vote_state.votes);
2493        let observed = vote_simulator
2494            .bank_forks
2495            .read()
2496            .unwrap()
2497            .get(next_unlocked_slot)
2498            .unwrap()
2499            .get_vote_account(&vote_pubkey)
2500            .unwrap();
2501        let state = observed.vote_state_view();
2502        info!("observed tower: {:#?}", state.votes_iter().collect_vec());
2503
2504        let num_slots_to_try = 200;
2505        cluster_votes
2506            .get_mut(&vote_simulator.node_pubkeys[1])
2507            .unwrap()
2508            .extend(next_unlocked_slot + 1..next_unlocked_slot + num_slots_to_try);
2509        assert!(vote_simulator.can_progress_on_fork(
2510            &node_pubkey,
2511            &mut tower,
2512            next_unlocked_slot,
2513            num_slots_to_try,
2514            &mut cluster_votes,
2515        ));
2516    }
2517
2518    #[test]
2519    fn test_collect_vote_lockouts_sums() {
2520        //two accounts voting for slot 0 with 1 token staked
2521        let accounts = gen_stakes(&[(1, &[0]), (1, &[0])]);
2522        let account_latest_votes: Vec<(Pubkey, SlotHashKey)> = accounts
2523            .iter()
2524            .sorted_by_key(|(pk, _)| *pk)
2525            .map(|(pubkey, _)| (*pubkey, (0, Hash::default())))
2526            .collect();
2527
2528        let ancestors = vec![(1, vec![0].into_iter().collect()), (0, HashSet::new())]
2529            .into_iter()
2530            .collect();
2531        let mut latest_validator_votes_for_frozen_banks =
2532            LatestValidatorVotesForFrozenBanks::default();
2533        let ComputedBankState {
2534            voted_stakes,
2535            total_stake,
2536            ..
2537        } = Tower::collect_vote_lockouts(
2538            &Pubkey::default(),
2539            1,
2540            0,
2541            0,
2542            &accounts,
2543            &ancestors,
2544            |_| Some(Hash::default()),
2545            &mut latest_validator_votes_for_frozen_banks,
2546            &mut HashSet::default(),
2547        );
2548        assert_eq!(voted_stakes[&0], 2);
2549        assert_eq!(total_stake, 2);
2550        let mut new_votes: Vec<_> = latest_validator_votes_for_frozen_banks
2551            .take_votes_dirty_set(0)
2552            .collect();
2553        new_votes.sort();
2554        assert_eq!(new_votes, account_latest_votes);
2555    }
2556
2557    #[test]
2558    fn test_collect_vote_lockouts_root() {
2559        let votes: Vec<u64> = (0..MAX_LOCKOUT_HISTORY as u64).collect();
2560        //two accounts voting for slots 0..MAX_LOCKOUT_HISTORY with 1 token staked
2561        let accounts = gen_stakes(&[(1, &votes), (1, &votes)]);
2562        let account_latest_votes: Vec<(Pubkey, SlotHashKey)> = accounts
2563            .iter()
2564            .sorted_by_key(|(pk, _)| *pk)
2565            .map(|(pubkey, _)| {
2566                (
2567                    *pubkey,
2568                    ((MAX_LOCKOUT_HISTORY - 1) as Slot, Hash::default()),
2569                )
2570            })
2571            .collect();
2572        let mut tower = Tower::new_for_tests(0, 0.67);
2573        let mut ancestors = HashMap::new();
2574        for i in 0..(MAX_LOCKOUT_HISTORY + 1) {
2575            tower.record_vote(i as u64, Hash::default());
2576            ancestors.insert(i as u64, (0..i as u64).collect());
2577        }
2578        let root = Lockout::new_with_confirmation_count(0, MAX_LOCKOUT_HISTORY as u32);
2579        let expected_bank_stake = 2;
2580        let expected_total_stake = 2;
2581        assert_eq!(tower.vote_state.root_slot, Some(0));
2582        let mut latest_validator_votes_for_frozen_banks =
2583            LatestValidatorVotesForFrozenBanks::default();
2584        let ComputedBankState {
2585            voted_stakes,
2586            fork_stake,
2587            total_stake,
2588            ..
2589        } = Tower::collect_vote_lockouts(
2590            &Pubkey::default(),
2591            MAX_LOCKOUT_HISTORY as u64,
2592            (MAX_LOCKOUT_HISTORY - 1) as Slot,
2593            0,
2594            &accounts,
2595            &ancestors,
2596            |_| Some(Hash::default()),
2597            &mut latest_validator_votes_for_frozen_banks,
2598            &mut HashSet::default(),
2599        );
2600        for i in 0..MAX_LOCKOUT_HISTORY {
2601            assert_eq!(voted_stakes[&(i as u64)], 2);
2602        }
2603
2604        // should be the sum of all voted stake for on the fork
2605        assert_eq!(fork_stake, expected_bank_stake);
2606        assert_eq!(total_stake, expected_total_stake);
2607        let mut new_votes: Vec<_> = latest_validator_votes_for_frozen_banks
2608            .take_votes_dirty_set(root.slot())
2609            .collect();
2610        new_votes.sort();
2611        assert_eq!(new_votes, account_latest_votes);
2612    }
2613
2614    #[test]
2615    fn test_check_vote_threshold_without_votes() {
2616        let tower = Tower::new_for_tests(1, 0.67);
2617        let stakes = vec![(0, 1)].into_iter().collect();
2618        assert!(tower.check_vote_stake_thresholds(0, &stakes, 2).is_empty());
2619    }
2620
2621    #[test]
2622    fn test_check_vote_threshold_no_skip_lockout_with_new_root() {
2623        agave_logger::setup();
2624        let mut tower = Tower::new_for_tests(4, 0.67);
2625        let mut stakes = HashMap::default();
2626        for i in 0..(MAX_LOCKOUT_HISTORY as u64 + 1) {
2627            stakes.insert(i, 1);
2628            tower.record_vote(i, Hash::default());
2629        }
2630        assert!(
2631            !tower
2632                .check_vote_stake_thresholds(MAX_LOCKOUT_HISTORY as u64 + 1, &stakes, 2)
2633                .is_empty()
2634        );
2635    }
2636
2637    #[test]
2638    fn test_is_slot_confirmed_not_enough_stake_failure() {
2639        let tower = Tower::new_for_tests(1, 0.67);
2640        let stakes = vec![(0, 1)].into_iter().collect();
2641        assert!(!tower.is_slot_confirmed(0, &stakes, 2));
2642    }
2643
2644    #[test]
2645    fn test_is_slot_confirmed_unknown_slot() {
2646        let tower = Tower::new_for_tests(1, 0.67);
2647        let stakes = HashMap::default();
2648        assert!(!tower.is_slot_confirmed(0, &stakes, 2));
2649    }
2650
2651    #[test]
2652    fn test_is_slot_confirmed_pass() {
2653        let tower = Tower::new_for_tests(1, 0.67);
2654        let stakes = vec![(0, 2)].into_iter().collect();
2655        assert!(tower.is_slot_confirmed(0, &stakes, 2));
2656    }
2657
2658    #[test]
2659    fn test_is_slot_duplicate_confirmed_not_enough_stake_failure() {
2660        let tower = Tower::new_for_tests(1, 0.67);
2661        let stakes = vec![(0, 52)].into_iter().collect();
2662        assert!(!tower.is_slot_duplicate_confirmed(0, &stakes, 100));
2663    }
2664
2665    #[test]
2666    fn test_is_slot_duplicate_confirmed_unknown_slot() {
2667        let tower = Tower::new_for_tests(1, 0.67);
2668        let stakes = HashMap::default();
2669        assert!(!tower.is_slot_duplicate_confirmed(0, &stakes, 100));
2670    }
2671
2672    #[test]
2673    fn test_is_slot_duplicate_confirmed_pass() {
2674        let tower = Tower::new_for_tests(1, 0.67);
2675        let stakes = vec![(0, 53)].into_iter().collect();
2676        assert!(tower.is_slot_duplicate_confirmed(0, &stakes, 100));
2677    }
2678
2679    #[test]
2680    fn test_is_locked_out_empty() {
2681        let tower = Tower::new_for_tests(0, 0.67);
2682        let ancestors = HashSet::from([0]);
2683        assert!(!tower.is_locked_out(1, &ancestors));
2684    }
2685
2686    #[test]
2687    fn test_is_locked_out_root_slot_child_pass() {
2688        let mut tower = Tower::new_for_tests(0, 0.67);
2689        let ancestors: HashSet<Slot> = vec![0].into_iter().collect();
2690        tower.vote_state.root_slot = Some(0);
2691        assert!(!tower.is_locked_out(1, &ancestors));
2692    }
2693
2694    #[test]
2695    fn test_is_locked_out_root_slot_sibling_fail() {
2696        let mut tower = Tower::new_for_tests(0, 0.67);
2697        let ancestors: HashSet<Slot> = vec![0].into_iter().collect();
2698        tower.vote_state.root_slot = Some(0);
2699        tower.record_vote(1, Hash::default());
2700        assert!(tower.is_locked_out(2, &ancestors));
2701    }
2702
2703    #[test]
2704    fn test_check_already_voted() {
2705        let mut tower = Tower::new_for_tests(0, 0.67);
2706        tower.record_vote(0, Hash::default());
2707        assert!(tower.has_voted(0));
2708        assert!(!tower.has_voted(1));
2709    }
2710
2711    #[test]
2712    fn test_check_recent_slot() {
2713        let mut tower = Tower::new_for_tests(0, 0.67);
2714        assert!(tower.is_recent(1));
2715        assert!(tower.is_recent(32));
2716        for i in 0..64 {
2717            tower.record_vote(i, Hash::default());
2718        }
2719        assert!(!tower.is_recent(0));
2720        assert!(!tower.is_recent(32));
2721        assert!(!tower.is_recent(63));
2722        assert!(tower.is_recent(65));
2723    }
2724
2725    #[test]
2726    fn test_is_locked_out_double_vote() {
2727        let mut tower = Tower::new_for_tests(0, 0.67);
2728        let ancestors: HashSet<Slot> = vec![0].into_iter().collect();
2729        tower.record_vote(0, Hash::default());
2730        tower.record_vote(1, Hash::default());
2731        assert!(tower.is_locked_out(0, &ancestors));
2732    }
2733
2734    #[test]
2735    fn test_is_locked_out_child() {
2736        let mut tower = Tower::new_for_tests(0, 0.67);
2737        let ancestors: HashSet<Slot> = vec![0].into_iter().collect();
2738        tower.record_vote(0, Hash::default());
2739        assert!(!tower.is_locked_out(1, &ancestors));
2740    }
2741
2742    #[test]
2743    fn test_is_locked_out_sibling() {
2744        let mut tower = Tower::new_for_tests(0, 0.67);
2745        let ancestors: HashSet<Slot> = vec![0].into_iter().collect();
2746        tower.record_vote(0, Hash::default());
2747        tower.record_vote(1, Hash::default());
2748        assert!(tower.is_locked_out(2, &ancestors));
2749    }
2750
2751    #[test]
2752    fn test_is_locked_out_last_vote_expired() {
2753        let mut tower = Tower::new_for_tests(0, 0.67);
2754        let ancestors: HashSet<Slot> = vec![0].into_iter().collect();
2755        tower.record_vote(0, Hash::default());
2756        tower.record_vote(1, Hash::default());
2757        assert!(!tower.is_locked_out(4, &ancestors));
2758        tower.record_vote(4, Hash::default());
2759        assert_eq!(tower.vote_state.votes[0].slot(), 0);
2760        assert_eq!(tower.vote_state.votes[0].confirmation_count(), 2);
2761        assert_eq!(tower.vote_state.votes[1].slot(), 4);
2762        assert_eq!(tower.vote_state.votes[1].confirmation_count(), 1);
2763    }
2764
2765    #[test]
2766    fn test_check_vote_threshold_below_threshold() {
2767        let mut tower = Tower::new_for_tests(1, 0.67);
2768        let stakes = vec![(0, 1)].into_iter().collect();
2769        tower.record_vote(0, Hash::default());
2770        assert!(!tower.check_vote_stake_thresholds(1, &stakes, 2).is_empty());
2771    }
2772    #[test]
2773    fn test_check_vote_threshold_above_threshold() {
2774        let mut tower = Tower::new_for_tests(1, 0.67);
2775        let stakes = vec![(0, 2)].into_iter().collect();
2776        tower.record_vote(0, Hash::default());
2777        assert!(tower.check_vote_stake_thresholds(1, &stakes, 2).is_empty());
2778    }
2779
2780    #[test]
2781    fn test_check_vote_thresholds_above_thresholds() {
2782        let mut tower = Tower::new_for_tests(VOTE_THRESHOLD_DEPTH, 0.67);
2783        let stakes = vec![
2784            (0, 3),
2785            (VOTE_THRESHOLD_DEPTH_SHALLOW as u64, 2),
2786            ((VOTE_THRESHOLD_DEPTH_SHALLOW as u64) - 1, 2),
2787        ]
2788        .into_iter()
2789        .collect();
2790        for slot in 0..VOTE_THRESHOLD_DEPTH {
2791            tower.record_vote(slot as Slot, Hash::default());
2792        }
2793        assert!(
2794            tower
2795                .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 4)
2796                .is_empty()
2797        );
2798    }
2799
2800    #[test]
2801    fn test_check_vote_threshold_deep_below_threshold() {
2802        let mut tower = Tower::new_for_tests(VOTE_THRESHOLD_DEPTH, 0.67);
2803        let stakes = vec![(0, 6), (VOTE_THRESHOLD_DEPTH_SHALLOW as u64, 4)]
2804            .into_iter()
2805            .collect();
2806        for slot in 0..VOTE_THRESHOLD_DEPTH {
2807            tower.record_vote(slot as Slot, Hash::default());
2808        }
2809        assert!(
2810            !tower
2811                .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 10)
2812                .is_empty()
2813        );
2814    }
2815
2816    #[test]
2817    fn test_check_vote_threshold_shallow_below_threshold() {
2818        let mut tower = Tower::new_for_tests(VOTE_THRESHOLD_DEPTH, 0.67);
2819        let stakes = vec![(0, 7), (VOTE_THRESHOLD_DEPTH_SHALLOW as u64, 1)]
2820            .into_iter()
2821            .collect();
2822        for slot in 0..VOTE_THRESHOLD_DEPTH {
2823            tower.record_vote(slot as Slot, Hash::default());
2824        }
2825        assert!(
2826            !tower
2827                .check_vote_stake_thresholds(VOTE_THRESHOLD_DEPTH.try_into().unwrap(), &stakes, 10)
2828                .is_empty()
2829        );
2830    }
2831
2832    #[test]
2833    fn test_check_vote_threshold_above_threshold_after_pop() {
2834        let mut tower = Tower::new_for_tests(1, 0.67);
2835        let stakes = vec![(0, 2)].into_iter().collect();
2836        tower.record_vote(0, Hash::default());
2837        tower.record_vote(1, Hash::default());
2838        tower.record_vote(2, Hash::default());
2839        assert!(tower.check_vote_stake_thresholds(6, &stakes, 2).is_empty());
2840    }
2841
2842    #[test]
2843    fn test_check_vote_threshold_above_threshold_no_stake() {
2844        let mut tower = Tower::new_for_tests(1, 0.67);
2845        let stakes = HashMap::default();
2846        tower.record_vote(0, Hash::default());
2847        assert!(!tower.check_vote_stake_thresholds(1, &stakes, 2).is_empty());
2848    }
2849
2850    #[test]
2851    fn test_check_vote_threshold_lockouts_not_updated() {
2852        agave_logger::setup();
2853        let mut tower = Tower::new_for_tests(1, 0.67);
2854        let stakes = vec![(0, 1), (1, 2)].into_iter().collect();
2855        tower.record_vote(0, Hash::default());
2856        tower.record_vote(1, Hash::default());
2857        tower.record_vote(2, Hash::default());
2858        assert!(tower.check_vote_stake_thresholds(6, &stakes, 2).is_empty());
2859    }
2860
2861    #[test]
2862    fn test_stake_is_updated_for_entire_branch() {
2863        let mut voted_stakes = HashMap::default();
2864        let account = AccountSharedData::from(Account {
2865            lamports: 1,
2866            ..Account::default()
2867        });
2868        let set: HashSet<u64> = vec![0u64, 1u64].into_iter().collect();
2869        let ancestors: HashMap<u64, HashSet<u64>> = [(2u64, set)].iter().cloned().collect();
2870        Tower::update_ancestor_voted_stakes(&mut voted_stakes, 2, account.lamports(), &ancestors);
2871        assert_eq!(voted_stakes[&0], 1);
2872        assert_eq!(voted_stakes[&1], 1);
2873        assert_eq!(voted_stakes[&2], 1);
2874    }
2875
2876    #[test]
2877    fn test_check_vote_threshold_forks() {
2878        // Create the ancestor relationships
2879        let ancestors = (0..=(VOTE_THRESHOLD_DEPTH + 1) as u64)
2880            .map(|slot| {
2881                let slot_parents: HashSet<_> = (0..slot).collect();
2882                (slot, slot_parents)
2883            })
2884            .collect();
2885
2886        // Create votes such that
2887        // 1) 3/4 of the stake has voted on slot: VOTE_THRESHOLD_DEPTH - 2, lockout: 2
2888        // 2) 1/4 of the stake has voted on slot: VOTE_THRESHOLD_DEPTH, lockout: 2^9
2889        let total_stake = 4;
2890        let threshold_size = 0.67;
2891        let threshold_stake = (f64::ceil(total_stake as f64 * threshold_size)) as u64;
2892        let tower_votes: Vec<Slot> = (0..VOTE_THRESHOLD_DEPTH as u64).collect();
2893        let accounts = gen_stakes(&[
2894            (threshold_stake, &[(VOTE_THRESHOLD_DEPTH - 2) as u64]),
2895            (total_stake - threshold_stake, &tower_votes[..]),
2896        ]);
2897
2898        // Initialize tower
2899        let mut tower = Tower::new_for_tests(VOTE_THRESHOLD_DEPTH, threshold_size);
2900        let mut vote_slots = HashSet::default();
2901        // CASE 1: Record the first VOTE_THRESHOLD tower votes for fork 2. We want to
2902        // evaluate a vote on slot VOTE_THRESHOLD_DEPTH. The nth most recent vote should be
2903        // for slot 0, which is common to all account vote states, so we should pass the
2904        // threshold check
2905        let vote_to_evaluate = VOTE_THRESHOLD_DEPTH as u64;
2906        for vote in &tower_votes {
2907            tower.record_vote(*vote, Hash::default());
2908        }
2909        let ComputedBankState {
2910            voted_stakes,
2911            total_stake,
2912            ..
2913        } = Tower::collect_vote_lockouts(
2914            &Pubkey::default(),
2915            vote_to_evaluate,
2916            vote_to_evaluate - 1,
2917            0,
2918            &accounts,
2919            &ancestors,
2920            |_| None,
2921            &mut LatestValidatorVotesForFrozenBanks::default(),
2922            &mut vote_slots,
2923        );
2924        assert!(
2925            tower
2926                .check_vote_stake_thresholds(vote_to_evaluate, &voted_stakes, total_stake)
2927                .is_empty()
2928        );
2929
2930        // CASE 2: Now we want to evaluate a vote for slot VOTE_THRESHOLD_DEPTH + 1. This slot
2931        // will expire the vote in one of the vote accounts, so we should have insufficient
2932        // stake to pass the threshold
2933        let vote_to_evaluate = VOTE_THRESHOLD_DEPTH as u64 + 1;
2934        let ComputedBankState {
2935            voted_stakes,
2936            total_stake,
2937            ..
2938        } = Tower::collect_vote_lockouts(
2939            &Pubkey::default(),
2940            vote_to_evaluate,
2941            vote_to_evaluate - 1,
2942            0,
2943            &accounts,
2944            &ancestors,
2945            |_| None,
2946            &mut LatestValidatorVotesForFrozenBanks::default(),
2947            &mut vote_slots,
2948        );
2949        assert!(
2950            !tower
2951                .check_vote_stake_thresholds(vote_to_evaluate, &voted_stakes, total_stake)
2952                .is_empty()
2953        );
2954    }
2955
2956    fn vote_and_check_recent(num_votes: usize) {
2957        let mut tower = Tower::new_for_tests(1, 0.67);
2958        let slots = if num_votes > 0 {
2959            { 0..num_votes }
2960                .map(|i| {
2961                    Lockout::new_with_confirmation_count(i as Slot, (num_votes as u32) - (i as u32))
2962                })
2963                .collect()
2964        } else {
2965            vec![]
2966        };
2967        let mut expected = TowerSync::new(
2968            VecDeque::from(slots),
2969            if num_votes > 0 { Some(0) } else { None },
2970            Hash::default(),
2971            Hash::default(),
2972        );
2973        for i in 0..num_votes {
2974            tower.record_vote(i as u64, Hash::default());
2975        }
2976
2977        expected.timestamp = tower.last_vote.timestamp();
2978        assert_eq!(VoteTransaction::from(expected), tower.last_vote)
2979    }
2980
2981    #[test]
2982    fn test_recent_votes_full() {
2983        vote_and_check_recent(MAX_LOCKOUT_HISTORY)
2984    }
2985
2986    #[test]
2987    fn test_recent_votes_empty() {
2988        vote_and_check_recent(0)
2989    }
2990
2991    #[test]
2992    fn test_recent_votes_exact() {
2993        vote_and_check_recent(5)
2994    }
2995
2996    #[test]
2997    fn test_maybe_timestamp() {
2998        let mut tower = Tower::default();
2999        assert!(tower.maybe_timestamp(0).is_some());
3000        assert!(tower.maybe_timestamp(1).is_some());
3001        assert!(tower.maybe_timestamp(0).is_none()); // Refuse to timestamp an older slot
3002        assert!(tower.maybe_timestamp(1).is_none()); // Refuse to timestamp the same slot twice
3003
3004        tower.last_timestamp.timestamp -= 1; // Move last_timestamp into the past
3005        assert!(tower.maybe_timestamp(2).is_some()); // slot 2 gets a timestamp
3006
3007        tower.last_timestamp.timestamp += 1_000_000; // Move last_timestamp well into the future
3008        assert!(tower.maybe_timestamp(3).is_none()); // slot 3 gets no timestamp
3009    }
3010
3011    #[test]
3012    fn test_refresh_last_vote_timestamp() {
3013        let mut tower = Tower::default();
3014
3015        // Tower has no vote or timestamp
3016        tower.last_vote.set_timestamp(None);
3017        tower.refresh_last_vote_timestamp(5);
3018        assert_eq!(tower.last_vote.timestamp(), None);
3019        assert_eq!(tower.last_timestamp.slot, 0);
3020        assert_eq!(tower.last_timestamp.timestamp, 0);
3021
3022        // Tower has vote no timestamp, but is greater than heaviest_bank
3023        tower.last_vote = VoteTransaction::from(TowerSync::from(vec![(0, 3), (1, 2), (6, 1)]));
3024        assert_eq!(tower.last_vote.timestamp(), None);
3025        tower.refresh_last_vote_timestamp(5);
3026        assert_eq!(tower.last_vote.timestamp(), None);
3027        assert_eq!(tower.last_timestamp.slot, 0);
3028        assert_eq!(tower.last_timestamp.timestamp, 0);
3029
3030        // Tower has vote with no timestamp
3031        tower.last_vote = VoteTransaction::from(TowerSync::from(vec![(0, 3), (1, 2), (2, 1)]));
3032        assert_eq!(tower.last_vote.timestamp(), None);
3033        tower.refresh_last_vote_timestamp(5);
3034        assert_eq!(tower.last_vote.timestamp(), Some(1));
3035        assert_eq!(tower.last_timestamp.slot, 2);
3036        assert_eq!(tower.last_timestamp.timestamp, 1);
3037
3038        // Vote has timestamp
3039        tower.last_vote = VoteTransaction::from(TowerSync::from(vec![(0, 3), (1, 2), (2, 1)]));
3040        tower.refresh_last_vote_timestamp(5);
3041        assert_eq!(tower.last_vote.timestamp(), Some(2));
3042        assert_eq!(tower.last_timestamp.slot, 2);
3043        assert_eq!(tower.last_timestamp.timestamp, 2);
3044    }
3045
3046    fn run_test_load_tower_snapshot<F, G>(
3047        modify_original: F,
3048        modify_serialized: G,
3049    ) -> (Tower, Result<Tower>)
3050    where
3051        F: Fn(&mut Tower, &Pubkey),
3052        G: Fn(&PathBuf),
3053    {
3054        let tower_path = TempDir::new().unwrap();
3055        let identity_keypair = Arc::new(Keypair::new());
3056        let node_pubkey = identity_keypair.pubkey();
3057
3058        // Use values that will not match the default derived from BankForks
3059        let mut tower = Tower::new_for_tests(10, 0.9);
3060
3061        let tower_storage = FileTowerStorage::new(tower_path.path().to_path_buf());
3062
3063        modify_original(&mut tower, &node_pubkey);
3064
3065        tower.save(&tower_storage, &identity_keypair).unwrap();
3066        modify_serialized(&tower_storage.filename(&node_pubkey));
3067        let loaded = Tower::restore(&tower_storage, &node_pubkey);
3068
3069        (tower, loaded)
3070    }
3071
3072    #[test]
3073    fn test_switch_threshold_across_tower_reload() {
3074        agave_logger::setup();
3075        // Init state
3076        let mut vote_simulator = VoteSimulator::new(2);
3077        let other_vote_account = vote_simulator.vote_pubkeys[1];
3078        let bank0 = vote_simulator.bank_forks.read().unwrap().get(0).unwrap();
3079        let total_stake = bank0.total_epoch_stake();
3080        assert_eq!(
3081            total_stake,
3082            vote_simulator.validator_keypairs.len() as u64 * 10_000
3083        );
3084
3085        // Create the tree of banks
3086        let forks = tr(0)
3087            / (tr(1)
3088                / (tr(2)
3089                    / tr(10)
3090                    / (tr(43)
3091                        / (tr(44)
3092                            // Minor fork 2
3093                            / (tr(45) / (tr(46) / (tr(47) / (tr(48) / (tr(49) / (tr(50)))))))
3094                            / (tr(110) / tr(111))))));
3095
3096        // Fill the BankForks according to the above fork structure
3097        vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
3098        for fork_progress in vote_simulator.progress.values_mut() {
3099            fork_progress.fork_stats.computed = true;
3100        }
3101
3102        let ancestors = vote_simulator.bank_forks.read().unwrap().ancestors();
3103        let descendants = vote_simulator.bank_forks.read().unwrap().descendants();
3104        let mut tower = Tower::default();
3105
3106        tower.record_vote(43, Hash::default());
3107        tower.record_vote(44, Hash::default());
3108        tower.record_vote(45, Hash::default());
3109        tower.record_vote(46, Hash::default());
3110        tower.record_vote(47, Hash::default());
3111        tower.record_vote(48, Hash::default());
3112        tower.record_vote(49, Hash::default());
3113
3114        // Trying to switch to a descendant of last vote should always work
3115        assert_eq!(
3116            tower.check_switch_threshold(
3117                50,
3118                &ancestors,
3119                &descendants,
3120                &vote_simulator.progress,
3121                total_stake,
3122                bank0.epoch_vote_accounts(0).unwrap(),
3123                &vote_simulator.latest_validator_votes_for_frozen_banks,
3124                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3125            ),
3126            SwitchForkDecision::SameFork
3127        );
3128
3129        // Trying to switch to another fork at 110 should fail
3130        assert_eq!(
3131            tower.check_switch_threshold(
3132                110,
3133                &ancestors,
3134                &descendants,
3135                &vote_simulator.progress,
3136                total_stake,
3137                bank0.epoch_vote_accounts(0).unwrap(),
3138                &vote_simulator.latest_validator_votes_for_frozen_banks,
3139                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3140            ),
3141            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
3142        );
3143
3144        vote_simulator.simulate_lockout_interval(111, (10, 49), &other_vote_account);
3145
3146        assert_eq!(
3147            tower.check_switch_threshold(
3148                110,
3149                &ancestors,
3150                &descendants,
3151                &vote_simulator.progress,
3152                total_stake,
3153                bank0.epoch_vote_accounts(0).unwrap(),
3154                &vote_simulator.latest_validator_votes_for_frozen_banks,
3155                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3156            ),
3157            SwitchForkDecision::SwitchProof(Hash::default())
3158        );
3159
3160        assert_eq!(tower.voted_slots(), vec![43, 44, 45, 46, 47, 48, 49]);
3161        {
3162            let mut tower = tower.clone();
3163            tower.record_vote(110, Hash::default());
3164            tower.record_vote(111, Hash::default());
3165            assert_eq!(tower.voted_slots(), vec![43, 110, 111]);
3166            assert_eq!(tower.vote_state.root_slot, Some(0));
3167        }
3168
3169        // Prepare simulated validator restart!
3170        let mut vote_simulator = VoteSimulator::new(2);
3171        let other_vote_account = vote_simulator.vote_pubkeys[1];
3172        let bank0 = vote_simulator.bank_forks.read().unwrap().get(0).unwrap();
3173        let total_stake = bank0.total_epoch_stake();
3174        let forks = tr(0)
3175            / (tr(1)
3176                / (tr(2)
3177                    / tr(10)
3178                    / (tr(43)
3179                        / (tr(44)
3180                            // Minor fork 2
3181                            / (tr(45) / (tr(46) / (tr(47) / (tr(48) / (tr(49) / (tr(50)))))))
3182                            / (tr(110) / tr(111))))));
3183        let replayed_root_slot = 44;
3184
3185        // Fill the BankForks according to the above fork structure
3186        vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
3187        for fork_progress in vote_simulator.progress.values_mut() {
3188            fork_progress.fork_stats.computed = true;
3189        }
3190
3191        // prepend tower restart!
3192        let mut slot_history = SlotHistory::default();
3193        vote_simulator.set_root(replayed_root_slot);
3194        let ancestors = vote_simulator.bank_forks.read().unwrap().ancestors();
3195        let descendants = vote_simulator.bank_forks.read().unwrap().descendants();
3196        for slot in &[0, 1, 2, 43, replayed_root_slot] {
3197            slot_history.add(*slot);
3198        }
3199        let mut tower = tower
3200            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3201            .unwrap();
3202
3203        assert_eq!(tower.voted_slots(), vec![45, 46, 47, 48, 49]);
3204
3205        // Trying to switch to another fork at 110 should fail
3206        assert_eq!(
3207            tower.check_switch_threshold(
3208                110,
3209                &ancestors,
3210                &descendants,
3211                &vote_simulator.progress,
3212                total_stake,
3213                bank0.epoch_vote_accounts(0).unwrap(),
3214                &vote_simulator.latest_validator_votes_for_frozen_banks,
3215                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3216            ),
3217            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
3218        );
3219
3220        // Add lockout_interval which should be excluded
3221        vote_simulator.simulate_lockout_interval(111, (45, 50), &other_vote_account);
3222        assert_eq!(
3223            tower.check_switch_threshold(
3224                110,
3225                &ancestors,
3226                &descendants,
3227                &vote_simulator.progress,
3228                total_stake,
3229                bank0.epoch_vote_accounts(0).unwrap(),
3230                &vote_simulator.latest_validator_votes_for_frozen_banks,
3231                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3232            ),
3233            SwitchForkDecision::FailedSwitchThreshold(0, 20000)
3234        );
3235
3236        // Add lockout_interval which should not be excluded
3237        vote_simulator.simulate_lockout_interval(111, (110, 200), &other_vote_account);
3238        assert_eq!(
3239            tower.check_switch_threshold(
3240                110,
3241                &ancestors,
3242                &descendants,
3243                &vote_simulator.progress,
3244                total_stake,
3245                bank0.epoch_vote_accounts(0).unwrap(),
3246                &vote_simulator.latest_validator_votes_for_frozen_banks,
3247                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3248            ),
3249            SwitchForkDecision::SwitchProof(Hash::default())
3250        );
3251
3252        tower.record_vote(110, Hash::default());
3253        tower.record_vote(111, Hash::default());
3254        assert_eq!(tower.voted_slots(), vec![110, 111]);
3255        assert_eq!(tower.vote_state.root_slot, Some(replayed_root_slot));
3256    }
3257
3258    #[test]
3259    fn test_load_tower_ok() {
3260        let (tower, loaded) =
3261            run_test_load_tower_snapshot(|tower, pubkey| tower.node_pubkey = *pubkey, |_| ());
3262        let loaded = loaded.unwrap();
3263        assert_eq!(loaded, tower);
3264        assert_eq!(tower.threshold_depth, 10);
3265        assert!((tower.threshold_size - 0.9_f64).abs() < f64::EPSILON);
3266        assert_eq!(loaded.threshold_depth, 10);
3267        assert!((loaded.threshold_size - 0.9_f64).abs() < f64::EPSILON);
3268    }
3269
3270    #[test]
3271    fn test_load_tower_wrong_identity() {
3272        let identity_keypair = Arc::new(Keypair::new());
3273        let tower = Tower::default();
3274        let tower_storage = FileTowerStorage::default();
3275        assert_matches!(
3276            tower.save(&tower_storage, &identity_keypair),
3277            Err(TowerError::WrongTower(_))
3278        )
3279    }
3280
3281    #[test]
3282    fn test_load_tower_invalid_signature() {
3283        let (_, loaded) = run_test_load_tower_snapshot(
3284            |tower, pubkey| tower.node_pubkey = *pubkey,
3285            |path| {
3286                let mut file = OpenOptions::new()
3287                    .read(true)
3288                    .write(true)
3289                    .open(path)
3290                    .unwrap();
3291                // 4 is the offset into SavedTowerVersions for the signature
3292                assert_eq!(file.seek(SeekFrom::Start(4)).unwrap(), 4);
3293                let mut buf = [0u8];
3294                assert_eq!(file.read(&mut buf).unwrap(), 1);
3295                buf[0] = !buf[0];
3296                assert_eq!(file.seek(SeekFrom::Start(4)).unwrap(), 4);
3297                assert_eq!(file.write(&buf).unwrap(), 1);
3298            },
3299        );
3300        assert_matches!(loaded, Err(TowerError::InvalidSignature))
3301    }
3302
3303    #[test]
3304    fn test_load_tower_deser_failure() {
3305        let (_, loaded) = run_test_load_tower_snapshot(
3306            |tower, pubkey| tower.node_pubkey = *pubkey,
3307            |path| {
3308                OpenOptions::new()
3309                    .write(true)
3310                    .truncate(true)
3311                    .open(path)
3312                    .unwrap_or_else(|_| panic!("Failed to truncate file: {path:?}"));
3313            },
3314        );
3315        assert_matches!(loaded, Err(TowerError::SerializeError(_)))
3316    }
3317
3318    #[test]
3319    fn test_load_tower_missing() {
3320        let (_, loaded) = run_test_load_tower_snapshot(
3321            |tower, pubkey| tower.node_pubkey = *pubkey,
3322            |path| {
3323                remove_file(path).unwrap();
3324            },
3325        );
3326        assert_matches!(loaded, Err(TowerError::IoError(_)))
3327    }
3328
3329    #[test]
3330    fn test_reconcile_blockstore_roots_with_tower_normal() {
3331        agave_logger::setup();
3332        let ledger_path = get_tmp_ledger_path_auto_delete!();
3333        let blockstore = Blockstore::open(ledger_path.path()).unwrap();
3334
3335        let (shreds, _) = make_slot_entries(1, 0, 42);
3336        blockstore.insert_shreds(shreds, None, false).unwrap();
3337        let (shreds, _) = make_slot_entries(3, 1, 42);
3338        blockstore.insert_shreds(shreds, None, false).unwrap();
3339        let (shreds, _) = make_slot_entries(4, 1, 42);
3340        blockstore.insert_shreds(shreds, None, false).unwrap();
3341        assert!(!blockstore.is_root(0));
3342        assert!(!blockstore.is_root(1));
3343        assert!(!blockstore.is_root(3));
3344        assert!(!blockstore.is_root(4));
3345
3346        let mut tower = Tower::default();
3347        tower.vote_state.root_slot = Some(4);
3348        reconcile_blockstore_roots_with_external_source(
3349            ExternalRootSource::Tower(tower.root()),
3350            &blockstore,
3351            &mut blockstore.max_root(),
3352        )
3353        .unwrap();
3354
3355        assert!(!blockstore.is_root(0));
3356        assert!(blockstore.is_root(1));
3357        assert!(!blockstore.is_root(3));
3358        assert!(blockstore.is_root(4));
3359    }
3360
3361    #[test]
3362    #[should_panic(
3363        expected = "last_blockstore_root(3) is skipped while traversing blockstore (currently at \
3364                    1) from external root (Tower(4))!?"
3365    )]
3366    fn test_reconcile_blockstore_roots_with_tower_panic_no_common_root() {
3367        agave_logger::setup();
3368        let ledger_path = get_tmp_ledger_path_auto_delete!();
3369        let blockstore = Blockstore::open(ledger_path.path()).unwrap();
3370
3371        let (shreds, _) = make_slot_entries(1, 0, 42);
3372        blockstore.insert_shreds(shreds, None, false).unwrap();
3373        let (shreds, _) = make_slot_entries(3, 1, 42);
3374        blockstore.insert_shreds(shreds, None, false).unwrap();
3375        let (shreds, _) = make_slot_entries(4, 1, 42);
3376        blockstore.insert_shreds(shreds, None, false).unwrap();
3377        blockstore.set_roots(std::iter::once(&3)).unwrap();
3378        assert!(!blockstore.is_root(0));
3379        assert!(!blockstore.is_root(1));
3380        assert!(blockstore.is_root(3));
3381        assert!(!blockstore.is_root(4));
3382
3383        let mut tower = Tower::default();
3384        tower.vote_state.root_slot = Some(4);
3385        reconcile_blockstore_roots_with_external_source(
3386            ExternalRootSource::Tower(tower.root()),
3387            &blockstore,
3388            &mut blockstore.max_root(),
3389        )
3390        .unwrap();
3391    }
3392
3393    #[test]
3394    fn test_reconcile_blockstore_roots_with_tower_nop_no_parent() {
3395        agave_logger::setup();
3396        let ledger_path = get_tmp_ledger_path_auto_delete!();
3397        let blockstore = Blockstore::open(ledger_path.path()).unwrap();
3398
3399        let (shreds, _) = make_slot_entries(1, 0, 42);
3400        blockstore.insert_shreds(shreds, None, false).unwrap();
3401        let (shreds, _) = make_slot_entries(3, 1, 42);
3402        blockstore.insert_shreds(shreds, None, false).unwrap();
3403        assert!(!blockstore.is_root(0));
3404        assert!(!blockstore.is_root(1));
3405        assert!(!blockstore.is_root(3));
3406
3407        let mut tower = Tower::default();
3408        tower.vote_state.root_slot = Some(4);
3409        assert_eq!(blockstore.max_root(), 0);
3410        reconcile_blockstore_roots_with_external_source(
3411            ExternalRootSource::Tower(tower.root()),
3412            &blockstore,
3413            &mut blockstore.max_root(),
3414        )
3415        .unwrap();
3416        assert_eq!(blockstore.max_root(), 0);
3417    }
3418
3419    #[test]
3420    fn test_adjust_lockouts_after_replay_future_slots() {
3421        agave_logger::setup();
3422        let mut tower = Tower::new_for_tests(10, 0.9);
3423        tower.record_vote(0, Hash::default());
3424        tower.record_vote(1, Hash::default());
3425        tower.record_vote(2, Hash::default());
3426        tower.record_vote(3, Hash::default());
3427
3428        let mut slot_history = SlotHistory::default();
3429        slot_history.add(0);
3430        slot_history.add(1);
3431
3432        let replayed_root_slot = 1;
3433        tower = tower
3434            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3435            .unwrap();
3436
3437        assert_eq!(tower.voted_slots(), vec![2, 3]);
3438        assert_eq!(tower.root(), replayed_root_slot);
3439
3440        tower = tower
3441            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3442            .unwrap();
3443        assert_eq!(tower.voted_slots(), vec![2, 3]);
3444        assert_eq!(tower.root(), replayed_root_slot);
3445    }
3446
3447    #[test]
3448    fn test_adjust_lockouts_after_replay_not_found_slots() {
3449        let mut tower = Tower::new_for_tests(10, 0.9);
3450        tower.record_vote(0, Hash::default());
3451        tower.record_vote(1, Hash::default());
3452        tower.record_vote(2, Hash::default());
3453        tower.record_vote(3, Hash::default());
3454
3455        let mut slot_history = SlotHistory::default();
3456        slot_history.add(0);
3457        slot_history.add(1);
3458        slot_history.add(4);
3459
3460        let replayed_root_slot = 4;
3461        tower = tower
3462            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3463            .unwrap();
3464
3465        assert_eq!(tower.voted_slots(), vec![2, 3]);
3466        assert_eq!(tower.root(), replayed_root_slot);
3467    }
3468
3469    #[test]
3470    fn test_adjust_lockouts_after_replay_all_rooted_with_no_too_old() {
3471        let mut tower = Tower::new_for_tests(10, 0.9);
3472        tower.record_vote(0, Hash::default());
3473        tower.record_vote(1, Hash::default());
3474        tower.record_vote(2, Hash::default());
3475
3476        let mut slot_history = SlotHistory::default();
3477        slot_history.add(0);
3478        slot_history.add(1);
3479        slot_history.add(2);
3480        slot_history.add(3);
3481        slot_history.add(4);
3482        slot_history.add(5);
3483
3484        let replayed_root_slot = 5;
3485        tower = tower
3486            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3487            .unwrap();
3488
3489        assert_eq!(tower.voted_slots(), vec![] as Vec<Slot>);
3490        assert_eq!(tower.root(), replayed_root_slot);
3491        assert_eq!(tower.stray_restored_slot, None);
3492    }
3493
3494    #[test]
3495    fn test_adjust_lockouts_after_replay_all_rooted_with_too_old() {
3496        use solana_slot_history::MAX_ENTRIES;
3497
3498        let mut tower = Tower::new_for_tests(10, 0.9);
3499        tower.record_vote(0, Hash::default());
3500        tower.record_vote(1, Hash::default());
3501        tower.record_vote(2, Hash::default());
3502
3503        let mut slot_history = SlotHistory::default();
3504        slot_history.add(0);
3505        slot_history.add(1);
3506        slot_history.add(2);
3507        slot_history.add(MAX_ENTRIES);
3508
3509        tower = tower
3510            .adjust_lockouts_after_replay(MAX_ENTRIES, &slot_history)
3511            .unwrap();
3512        assert_eq!(tower.voted_slots(), vec![] as Vec<Slot>);
3513        assert_eq!(tower.root(), MAX_ENTRIES);
3514    }
3515
3516    #[test]
3517    fn test_adjust_lockouts_after_replay_anchored_future_slots() {
3518        let mut tower = Tower::new_for_tests(10, 0.9);
3519        tower.record_vote(0, Hash::default());
3520        tower.record_vote(1, Hash::default());
3521        tower.record_vote(2, Hash::default());
3522        tower.record_vote(3, Hash::default());
3523        tower.record_vote(4, Hash::default());
3524
3525        let mut slot_history = SlotHistory::default();
3526        slot_history.add(0);
3527        slot_history.add(1);
3528        slot_history.add(2);
3529
3530        let replayed_root_slot = 2;
3531        tower = tower
3532            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3533            .unwrap();
3534
3535        assert_eq!(tower.voted_slots(), vec![3, 4]);
3536        assert_eq!(tower.root(), replayed_root_slot);
3537    }
3538
3539    #[test]
3540    fn test_adjust_lockouts_after_replay_all_not_found() {
3541        let mut tower = Tower::new_for_tests(10, 0.9);
3542        tower.record_vote(5, Hash::default());
3543        tower.record_vote(6, Hash::default());
3544
3545        let mut slot_history = SlotHistory::default();
3546        slot_history.add(0);
3547        slot_history.add(1);
3548        slot_history.add(2);
3549        slot_history.add(7);
3550
3551        let replayed_root_slot = 7;
3552        tower = tower
3553            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3554            .unwrap();
3555
3556        assert_eq!(tower.voted_slots(), vec![5, 6]);
3557        assert_eq!(tower.root(), replayed_root_slot);
3558    }
3559
3560    #[test]
3561    fn test_adjust_lockouts_after_replay_all_not_found_even_if_rooted() {
3562        let mut tower = Tower::new_for_tests(10, 0.9);
3563        tower.vote_state.root_slot = Some(4);
3564        tower.record_vote(5, Hash::default());
3565        tower.record_vote(6, Hash::default());
3566
3567        let mut slot_history = SlotHistory::default();
3568        slot_history.add(0);
3569        slot_history.add(1);
3570        slot_history.add(2);
3571        slot_history.add(7);
3572
3573        let replayed_root_slot = 7;
3574        let result = tower.adjust_lockouts_after_replay(replayed_root_slot, &slot_history);
3575
3576        assert_eq!(
3577            format!("{}", result.unwrap_err()),
3578            "The tower is fatally inconsistent with blockstore: no common slot for rooted tower"
3579        );
3580    }
3581
3582    #[test]
3583    fn test_adjust_lockouts_after_replay_all_future_votes_only_root_found() {
3584        let mut tower = Tower::new_for_tests(10, 0.9);
3585        tower.vote_state.root_slot = Some(2);
3586        tower.record_vote(3, Hash::default());
3587        tower.record_vote(4, Hash::default());
3588        tower.record_vote(5, Hash::default());
3589
3590        let mut slot_history = SlotHistory::default();
3591        slot_history.add(0);
3592        slot_history.add(1);
3593        slot_history.add(2);
3594
3595        let replayed_root_slot = 2;
3596        tower = tower
3597            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3598            .unwrap();
3599
3600        assert_eq!(tower.voted_slots(), vec![3, 4, 5]);
3601        assert_eq!(tower.root(), replayed_root_slot);
3602    }
3603
3604    #[test]
3605    fn test_adjust_lockouts_after_replay_empty() {
3606        let mut tower = Tower::new_for_tests(10, 0.9);
3607
3608        let mut slot_history = SlotHistory::default();
3609        slot_history.add(0);
3610
3611        let replayed_root_slot = 0;
3612        tower = tower
3613            .adjust_lockouts_after_replay(replayed_root_slot, &slot_history)
3614            .unwrap();
3615
3616        assert_eq!(tower.voted_slots(), vec![] as Vec<Slot>);
3617        assert_eq!(tower.root(), replayed_root_slot);
3618    }
3619
3620    #[test]
3621    fn test_adjust_lockouts_after_replay_too_old_tower() {
3622        use solana_slot_history::MAX_ENTRIES;
3623
3624        let mut tower = Tower::new_for_tests(10, 0.9);
3625        tower.record_vote(0, Hash::default());
3626
3627        let mut slot_history = SlotHistory::default();
3628        slot_history.add(0);
3629        slot_history.add(MAX_ENTRIES);
3630
3631        let result = tower.adjust_lockouts_after_replay(MAX_ENTRIES, &slot_history);
3632        assert_eq!(
3633            format!("{}", result.unwrap_err()),
3634            "The tower is too old: newest slot in tower (0) << oldest slot in available history \
3635             (1)"
3636        );
3637    }
3638
3639    #[test]
3640    fn test_adjust_lockouts_after_replay_time_warped() {
3641        let mut tower = Tower::new_for_tests(10, 0.9);
3642        tower.vote_state.votes.push_back(Lockout::new(1));
3643        tower.vote_state.votes.push_back(Lockout::new(0));
3644        let vote = Vote::new(vec![0], Hash::default());
3645        tower.last_vote = VoteTransaction::from(vote);
3646
3647        let mut slot_history = SlotHistory::default();
3648        slot_history.add(0);
3649
3650        let result = tower.adjust_lockouts_after_replay(0, &slot_history);
3651        assert_eq!(
3652            format!("{}", result.unwrap_err()),
3653            "The tower is fatally inconsistent with blockstore: time warped?"
3654        );
3655    }
3656
3657    #[test]
3658    fn test_adjust_lockouts_after_replay_diverged_ancestor() {
3659        let mut tower = Tower::new_for_tests(10, 0.9);
3660        tower.vote_state.votes.push_back(Lockout::new(1));
3661        tower.vote_state.votes.push_back(Lockout::new(2));
3662        let vote = Vote::new(vec![2], Hash::default());
3663        tower.last_vote = VoteTransaction::from(vote);
3664
3665        let mut slot_history = SlotHistory::default();
3666        slot_history.add(0);
3667        slot_history.add(2);
3668
3669        let result = tower.adjust_lockouts_after_replay(2, &slot_history);
3670        assert_eq!(
3671            format!("{}", result.unwrap_err()),
3672            "The tower is fatally inconsistent with blockstore: diverged ancestor?"
3673        );
3674    }
3675
3676    #[test]
3677    fn test_adjust_lockouts_after_replay_out_of_order() {
3678        use solana_slot_history::MAX_ENTRIES;
3679
3680        let mut tower = Tower::new_for_tests(10, 0.9);
3681        tower
3682            .vote_state
3683            .votes
3684            .push_back(Lockout::new(MAX_ENTRIES - 1));
3685        tower.vote_state.votes.push_back(Lockout::new(0));
3686        tower.vote_state.votes.push_back(Lockout::new(1));
3687        let vote = Vote::new(vec![1], Hash::default());
3688        tower.last_vote = VoteTransaction::from(vote);
3689
3690        let mut slot_history = SlotHistory::default();
3691        slot_history.add(MAX_ENTRIES);
3692
3693        let result = tower.adjust_lockouts_after_replay(MAX_ENTRIES, &slot_history);
3694        assert_eq!(
3695            format!("{}", result.unwrap_err()),
3696            "The tower is fatally inconsistent with blockstore: not too old once after got too \
3697             old?"
3698        );
3699    }
3700
3701    #[test]
3702    #[should_panic(expected = "slot_in_tower(2) < checked_slot(1)")]
3703    fn test_adjust_lockouts_after_replay_reversed_votes() {
3704        let mut tower = Tower::new_for_tests(10, 0.9);
3705        tower.vote_state.votes.push_back(Lockout::new(2));
3706        tower.vote_state.votes.push_back(Lockout::new(1));
3707        let vote = Vote::new(vec![1], Hash::default());
3708        tower.last_vote = VoteTransaction::from(vote);
3709
3710        let mut slot_history = SlotHistory::default();
3711        slot_history.add(0);
3712        slot_history.add(2);
3713
3714        tower
3715            .adjust_lockouts_after_replay(2, &slot_history)
3716            .unwrap();
3717    }
3718
3719    #[test]
3720    #[should_panic(expected = "slot_in_tower(3) < checked_slot(3)")]
3721    fn test_adjust_lockouts_after_replay_repeated_non_root_votes() {
3722        let mut tower = Tower::new_for_tests(10, 0.9);
3723        tower.vote_state.votes.push_back(Lockout::new(2));
3724        tower.vote_state.votes.push_back(Lockout::new(3));
3725        tower.vote_state.votes.push_back(Lockout::new(3));
3726        let vote = Vote::new(vec![3], Hash::default());
3727        tower.last_vote = VoteTransaction::from(vote);
3728
3729        let mut slot_history = SlotHistory::default();
3730        slot_history.add(0);
3731        slot_history.add(2);
3732
3733        tower
3734            .adjust_lockouts_after_replay(2, &slot_history)
3735            .unwrap();
3736    }
3737
3738    #[test]
3739    fn test_adjust_lockouts_after_replay_vote_on_root() {
3740        let mut tower = Tower::new_for_tests(10, 0.9);
3741        tower.vote_state.root_slot = Some(42);
3742        tower.vote_state.votes.push_back(Lockout::new(42));
3743        tower.vote_state.votes.push_back(Lockout::new(43));
3744        tower.vote_state.votes.push_back(Lockout::new(44));
3745        let vote = Vote::new(vec![44], Hash::default());
3746        tower.last_vote = VoteTransaction::from(vote);
3747
3748        let mut slot_history = SlotHistory::default();
3749        slot_history.add(42);
3750
3751        let tower = tower.adjust_lockouts_after_replay(42, &slot_history);
3752        assert_eq!(tower.unwrap().voted_slots(), [43, 44]);
3753    }
3754
3755    #[test]
3756    fn test_adjust_lockouts_after_replay_vote_on_genesis() {
3757        let mut tower = Tower::new_for_tests(10, 0.9);
3758        tower.vote_state.votes.push_back(Lockout::new(0));
3759        let vote = Vote::new(vec![0], Hash::default());
3760        tower.last_vote = VoteTransaction::from(vote);
3761
3762        let mut slot_history = SlotHistory::default();
3763        slot_history.add(0);
3764
3765        assert!(tower.adjust_lockouts_after_replay(0, &slot_history).is_ok());
3766    }
3767
3768    #[test]
3769    fn test_adjust_lockouts_after_replay_future_tower() {
3770        let mut tower = Tower::new_for_tests(10, 0.9);
3771        tower.vote_state.votes.push_back(Lockout::new(13));
3772        tower.vote_state.votes.push_back(Lockout::new(14));
3773        let vote = Vote::new(vec![14], Hash::default());
3774        tower.last_vote = VoteTransaction::from(vote);
3775        tower.initialize_root(12);
3776
3777        let mut slot_history = SlotHistory::default();
3778        slot_history.add(0);
3779        slot_history.add(2);
3780
3781        let tower = tower
3782            .adjust_lockouts_after_replay(2, &slot_history)
3783            .unwrap();
3784        assert_eq!(tower.root(), 12);
3785        assert_eq!(tower.voted_slots(), vec![13, 14]);
3786        assert_eq!(tower.stray_restored_slot, Some(14));
3787    }
3788
3789    #[test]
3790    fn test_default_tower_has_no_stray_last_vote() {
3791        let tower = Tower::default();
3792        assert!(!tower.is_stray_last_vote());
3793    }
3794
3795    #[test]
3796    fn test_switch_threshold_common_ancestor() {
3797        let mut vote_simulator = VoteSimulator::new(2);
3798        let other_vote_account = vote_simulator.vote_pubkeys[1];
3799        let bank0 = vote_simulator.bank_forks.read().unwrap().get(0).unwrap();
3800        let total_stake = bank0.total_epoch_stake();
3801        assert_eq!(
3802            total_stake,
3803            vote_simulator.validator_keypairs.len() as u64 * 10_000
3804        );
3805
3806        // Create the tree of banks
3807        //                                       /- 50
3808        //          /- 51    /- 45 - 46 - 47 - 48 - 49
3809        // 0 - 1 - 2 - 43 - 44
3810        //                   \- 110 - 111 - 112
3811        //                    \- 113
3812        let forks = tr(0)
3813            / (tr(1)
3814                / (tr(2)
3815                    / tr(51)
3816                    / (tr(43)
3817                        / (tr(44)
3818                            / (tr(45) / (tr(46) / (tr(47) / (tr(48) / tr(49) / tr(50)))))
3819                            / tr(113)
3820                            / (tr(110) / tr(111) / tr(112))))));
3821        let switch_slot = 111;
3822
3823        // Fill the BankForks according to the above fork structure
3824        vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
3825        for fork_progress in vote_simulator.progress.values_mut() {
3826            fork_progress.fork_stats.computed = true;
3827        }
3828
3829        let ancestors = vote_simulator.bank_forks.read().unwrap().ancestors();
3830        let descendants = vote_simulator.bank_forks.read().unwrap().descendants();
3831        let mut tower = Tower::default();
3832
3833        tower.record_vote(43, Hash::default());
3834        tower.record_vote(44, Hash::default());
3835        tower.record_vote(45, Hash::default());
3836        tower.record_vote(46, Hash::default());
3837        tower.record_vote(47, Hash::default());
3838        tower.record_vote(48, Hash::default());
3839        tower.record_vote(49, Hash::default());
3840
3841        // Candidate slot 50 should *not* work
3842        vote_simulator.simulate_lockout_interval(50, (10, 49), &other_vote_account);
3843        assert_eq!(
3844            tower.check_switch_threshold(
3845                switch_slot,
3846                &ancestors,
3847                &descendants,
3848                &vote_simulator.progress,
3849                total_stake,
3850                bank0.epoch_vote_accounts(0).unwrap(),
3851                &vote_simulator.latest_validator_votes_for_frozen_banks,
3852                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3853            ),
3854            SwitchForkDecision::FailedSwitchThreshold(0, 20_000)
3855        );
3856        vote_simulator.clear_lockout_intervals(50);
3857
3858        // 51, 111, 112, and 113 are all valid
3859        for candidate_slot in [51, 111, 113] {
3860            vote_simulator.simulate_lockout_interval(candidate_slot, (10, 49), &other_vote_account);
3861            assert_eq!(
3862                tower.check_switch_threshold(
3863                    switch_slot,
3864                    &ancestors,
3865                    &descendants,
3866                    &vote_simulator.progress,
3867                    total_stake,
3868                    bank0.epoch_vote_accounts(0).unwrap(),
3869                    &vote_simulator.latest_validator_votes_for_frozen_banks,
3870                    &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3871                ),
3872                SwitchForkDecision::SwitchProof(Hash::default())
3873            );
3874            vote_simulator.clear_lockout_intervals(candidate_slot);
3875        }
3876
3877        // Same checks for gossip votes
3878        let insert_gossip_vote = |vote_simulator: &mut VoteSimulator, slot| {
3879            vote_simulator
3880                .latest_validator_votes_for_frozen_banks
3881                .check_add_vote(
3882                    other_vote_account,
3883                    slot,
3884                    Some(
3885                        vote_simulator
3886                            .bank_forks
3887                            .read()
3888                            .unwrap()
3889                            .get(slot)
3890                            .unwrap()
3891                            .hash(),
3892                    ),
3893                    false,
3894                );
3895        };
3896
3897        // Candidate slot 50 should *not* work
3898        insert_gossip_vote(&mut vote_simulator, 50);
3899        assert_eq!(
3900            tower.check_switch_threshold(
3901                switch_slot,
3902                &ancestors,
3903                &descendants,
3904                &vote_simulator.progress,
3905                total_stake,
3906                bank0.epoch_vote_accounts(0).unwrap(),
3907                &vote_simulator.latest_validator_votes_for_frozen_banks,
3908                &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3909            ),
3910            SwitchForkDecision::FailedSwitchThreshold(0, 20_000)
3911        );
3912        vote_simulator.latest_validator_votes_for_frozen_banks =
3913            LatestValidatorVotesForFrozenBanks::default();
3914
3915        // 51, 110, 111, 112, and 113 are all valid
3916        // Note: We can use 110 here since gossip votes aren't limited to leaf banks
3917        for candidate_slot in [51, 110, 111, 112, 113] {
3918            insert_gossip_vote(&mut vote_simulator, candidate_slot);
3919            assert_eq!(
3920                tower.check_switch_threshold(
3921                    switch_slot,
3922                    &ancestors,
3923                    &descendants,
3924                    &vote_simulator.progress,
3925                    total_stake,
3926                    bank0.epoch_vote_accounts(0).unwrap(),
3927                    &vote_simulator.latest_validator_votes_for_frozen_banks,
3928                    &vote_simulator.tbft_structs.heaviest_subtree_fork_choice,
3929                ),
3930                SwitchForkDecision::SwitchProof(Hash::default())
3931            );
3932            vote_simulator.latest_validator_votes_for_frozen_banks =
3933                LatestValidatorVotesForFrozenBanks::default();
3934        }
3935    }
3936}