* Refactor: Rename leader_first_tick_height field
* Refactor: add `PohRecorder::slot_for_tick_height` helper
* Refactor: Add type for poh leader status
(cherry picked from commit 1240217a73)
Co-authored-by: Justin Starry <justin@solana.com>
			
			
This commit is contained in:
		@@ -38,7 +38,7 @@ use {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    solana_measure::measure::Measure,
 | 
					    solana_measure::measure::Measure,
 | 
				
			||||||
    solana_metrics::inc_new_counter_info,
 | 
					    solana_metrics::inc_new_counter_info,
 | 
				
			||||||
    solana_poh::poh_recorder::{PohRecorder, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS},
 | 
					    solana_poh::poh_recorder::{PohLeaderStatus, PohRecorder, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS},
 | 
				
			||||||
    solana_program_runtime::timings::ExecuteTimings,
 | 
					    solana_program_runtime::timings::ExecuteTimings,
 | 
				
			||||||
    solana_rpc::{
 | 
					    solana_rpc::{
 | 
				
			||||||
        optimistically_confirmed_bank_tracker::{BankNotification, BankNotificationSender},
 | 
					        optimistically_confirmed_bank_tracker::{BankNotification, BankNotificationSender},
 | 
				
			||||||
@@ -1395,13 +1395,17 @@ impl ReplayStage {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        assert!(!poh_recorder.lock().unwrap().has_bank());
 | 
					        assert!(!poh_recorder.lock().unwrap().has_bank());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (reached_leader_slot, _grace_ticks, poh_slot, parent_slot) =
 | 
					        let (poh_slot, parent_slot) = match poh_recorder.lock().unwrap().reached_leader_slot() {
 | 
				
			||||||
            poh_recorder.lock().unwrap().reached_leader_slot();
 | 
					            PohLeaderStatus::Reached {
 | 
				
			||||||
 | 
					                poh_slot,
 | 
				
			||||||
 | 
					                parent_slot,
 | 
				
			||||||
 | 
					            } => (poh_slot, parent_slot),
 | 
				
			||||||
 | 
					            PohLeaderStatus::NotReached => {
 | 
				
			||||||
 | 
					                trace!("{} poh_recorder hasn't reached_leader_slot", my_pubkey);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if !reached_leader_slot {
 | 
					 | 
				
			||||||
            trace!("{} poh_recorder hasn't reached_leader_slot", my_pubkey);
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        trace!("{} reached_leader_slot", my_pubkey);
 | 
					        trace!("{} reached_leader_slot", my_pubkey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let parent = bank_forks
 | 
					        let parent = bank_forks
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -193,6 +193,12 @@ pub struct WorkingBank {
 | 
				
			|||||||
    pub max_tick_height: u64,
 | 
					    pub max_tick_height: u64,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, PartialEq)]
 | 
				
			||||||
 | 
					pub enum PohLeaderStatus {
 | 
				
			||||||
 | 
					    NotReached,
 | 
				
			||||||
 | 
					    Reached { poh_slot: Slot, parent_slot: Slot },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct PohRecorder {
 | 
					pub struct PohRecorder {
 | 
				
			||||||
    pub poh: Arc<Mutex<Poh>>,
 | 
					    pub poh: Arc<Mutex<Poh>>,
 | 
				
			||||||
    tick_height: u64,
 | 
					    tick_height: u64,
 | 
				
			||||||
@@ -202,7 +208,7 @@ pub struct PohRecorder {
 | 
				
			|||||||
    tick_cache: Vec<(Entry, u64)>, // cache of entry and its tick_height
 | 
					    tick_cache: Vec<(Entry, u64)>, // cache of entry and its tick_height
 | 
				
			||||||
    working_bank: Option<WorkingBank>,
 | 
					    working_bank: Option<WorkingBank>,
 | 
				
			||||||
    sender: Sender<WorkingBankEntry>,
 | 
					    sender: Sender<WorkingBankEntry>,
 | 
				
			||||||
    leader_first_tick_height: Option<u64>,
 | 
					    leader_first_tick_height_including_grace_ticks: Option<u64>,
 | 
				
			||||||
    leader_last_tick_height: u64, // zero if none
 | 
					    leader_last_tick_height: u64, // zero if none
 | 
				
			||||||
    grace_ticks: u64,
 | 
					    grace_ticks: u64,
 | 
				
			||||||
    id: Pubkey,
 | 
					    id: Pubkey,
 | 
				
			||||||
@@ -238,10 +244,14 @@ impl PohRecorder {
 | 
				
			|||||||
                GRACE_TICKS_FACTOR * MAX_GRACE_SLOTS,
 | 
					                GRACE_TICKS_FACTOR * MAX_GRACE_SLOTS,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            assert_eq!(self.ticks_per_slot, bank.ticks_per_slot());
 | 
					            assert_eq!(self.ticks_per_slot, bank.ticks_per_slot());
 | 
				
			||||||
            let (leader_first_tick_height, leader_last_tick_height, grace_ticks) =
 | 
					            let (
 | 
				
			||||||
                Self::compute_leader_slot_tick_heights(next_leader_slot, self.ticks_per_slot);
 | 
					                leader_first_tick_height_including_grace_ticks,
 | 
				
			||||||
 | 
					                leader_last_tick_height,
 | 
				
			||||||
 | 
					                grace_ticks,
 | 
				
			||||||
 | 
					            ) = Self::compute_leader_slot_tick_heights(next_leader_slot, self.ticks_per_slot);
 | 
				
			||||||
            self.grace_ticks = grace_ticks;
 | 
					            self.grace_ticks = grace_ticks;
 | 
				
			||||||
            self.leader_first_tick_height = leader_first_tick_height;
 | 
					            self.leader_first_tick_height_including_grace_ticks =
 | 
				
			||||||
 | 
					                leader_first_tick_height_including_grace_ticks;
 | 
				
			||||||
            self.leader_last_tick_height = leader_last_tick_height;
 | 
					            self.leader_last_tick_height = leader_last_tick_height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            datapoint_info!(
 | 
					            datapoint_info!(
 | 
				
			||||||
@@ -258,18 +268,27 @@ impl PohRecorder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub fn would_be_leader(&self, within_next_n_ticks: u64) -> bool {
 | 
					    pub fn would_be_leader(&self, within_next_n_ticks: u64) -> bool {
 | 
				
			||||||
        self.has_bank()
 | 
					        self.has_bank()
 | 
				
			||||||
            || self
 | 
					            || self.leader_first_tick_height_including_grace_ticks.map_or(
 | 
				
			||||||
                .leader_first_tick_height
 | 
					                false,
 | 
				
			||||||
                .map_or(false, |leader_first_tick_height| {
 | 
					                |leader_first_tick_height_including_grace_ticks| {
 | 
				
			||||||
                    let ideal_leader_tick_height =
 | 
					                    let ideal_leader_tick_height = leader_first_tick_height_including_grace_ticks
 | 
				
			||||||
                        leader_first_tick_height.saturating_sub(self.grace_ticks);
 | 
					                        .saturating_sub(self.grace_ticks);
 | 
				
			||||||
                    self.tick_height + within_next_n_ticks >= ideal_leader_tick_height
 | 
					                    self.tick_height + within_next_n_ticks >= ideal_leader_tick_height
 | 
				
			||||||
                        && self.tick_height <= self.leader_last_tick_height
 | 
					                        && self.tick_height <= self.leader_last_tick_height
 | 
				
			||||||
                })
 | 
					                },
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Return the slot for a given tick height
 | 
				
			||||||
 | 
					    fn slot_for_tick_height(&self, tick_height: u64) -> Slot {
 | 
				
			||||||
 | 
					        // We need to subtract by one here because, assuming ticks per slot is 64,
 | 
				
			||||||
 | 
					        // tick heights [1..64] correspond to slot 0. The last tick height of a slot
 | 
				
			||||||
 | 
					        // is always a multiple of 64.
 | 
				
			||||||
 | 
					        tick_height.saturating_sub(1) / self.ticks_per_slot
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn leader_after_n_slots(&self, slots: u64) -> Option<Pubkey> {
 | 
					    pub fn leader_after_n_slots(&self, slots: u64) -> Option<Pubkey> {
 | 
				
			||||||
        let current_slot = self.tick_height.saturating_sub(1) / self.ticks_per_slot;
 | 
					        let current_slot = self.slot_for_tick_height(self.tick_height);
 | 
				
			||||||
        self.leader_schedule_cache
 | 
					        self.leader_schedule_cache
 | 
				
			||||||
            .slot_leader_at(current_slot + slots, None)
 | 
					            .slot_leader_at(current_slot + slots, None)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -326,56 +345,57 @@ impl PohRecorder {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn reached_leader_tick(&self, leader_first_tick_height: u64) -> bool {
 | 
					    fn reached_leader_tick(&self, leader_first_tick_height_including_grace_ticks: u64) -> bool {
 | 
				
			||||||
        let target_tick_height = leader_first_tick_height.saturating_sub(1);
 | 
					        let target_tick_height = leader_first_tick_height_including_grace_ticks.saturating_sub(1);
 | 
				
			||||||
        let ideal_target_tick_height = target_tick_height.saturating_sub(self.grace_ticks);
 | 
					        let ideal_target_tick_height = target_tick_height.saturating_sub(self.grace_ticks);
 | 
				
			||||||
        let current_slot = self.tick_height / self.ticks_per_slot;
 | 
					        let next_tick_height = self.tick_height.saturating_add(1);
 | 
				
			||||||
 | 
					        let next_slot = self.slot_for_tick_height(next_tick_height);
 | 
				
			||||||
        // We've approached target_tick_height OR poh was reset to run immediately
 | 
					        // We've approached target_tick_height OR poh was reset to run immediately
 | 
				
			||||||
        // Or, previous leader didn't transmit in any of its leader slots, so ignore grace ticks
 | 
					        // Or, previous leader didn't transmit in any of its leader slots, so ignore grace ticks
 | 
				
			||||||
        self.tick_height >= target_tick_height
 | 
					        self.tick_height >= target_tick_height
 | 
				
			||||||
            || self.start_tick_height + self.grace_ticks == leader_first_tick_height
 | 
					            || self.start_tick_height + self.grace_ticks
 | 
				
			||||||
 | 
					                == leader_first_tick_height_including_grace_ticks
 | 
				
			||||||
            || (self.tick_height >= ideal_target_tick_height
 | 
					            || (self.tick_height >= ideal_target_tick_height
 | 
				
			||||||
                && (self.prev_slot_was_mine(current_slot)
 | 
					                && (self.prev_slot_was_mine(next_slot)
 | 
				
			||||||
                    || !self.is_same_fork_as_previous_leader(current_slot)))
 | 
					                    || !self.is_same_fork_as_previous_leader(next_slot)))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn start_slot(&self) -> Slot {
 | 
					    pub fn start_slot(&self) -> Slot {
 | 
				
			||||||
        self.start_bank.slot()
 | 
					        self.start_bank.slot()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// returns if leader slot has been reached, how many grace ticks were afforded,
 | 
					    /// Returns if the leader slot has been reached along with the current poh
 | 
				
			||||||
    ///   imputed leader_slot and self.start_slot()
 | 
					    /// slot and the parent slot (could be a few slots ago if any previous
 | 
				
			||||||
    /// reached_leader_slot() == true means "ready for a bank"
 | 
					    /// leaders needed to be skipped).
 | 
				
			||||||
    pub fn reached_leader_slot(&self) -> (bool, u64, Slot, Slot) {
 | 
					    pub fn reached_leader_slot(&self) -> PohLeaderStatus {
 | 
				
			||||||
        trace!(
 | 
					        trace!(
 | 
				
			||||||
            "tick_height {}, start_tick_height {}, leader_first_tick_height {:?}, grace_ticks {}, has_bank {}",
 | 
					            "tick_height {}, start_tick_height {}, leader_first_tick_height_including_grace_ticks {:?}, grace_ticks {}, has_bank {}",
 | 
				
			||||||
            self.tick_height,
 | 
					            self.tick_height,
 | 
				
			||||||
            self.start_tick_height,
 | 
					            self.start_tick_height,
 | 
				
			||||||
            self.leader_first_tick_height,
 | 
					            self.leader_first_tick_height_including_grace_ticks,
 | 
				
			||||||
            self.grace_ticks,
 | 
					            self.grace_ticks,
 | 
				
			||||||
            self.has_bank()
 | 
					            self.has_bank()
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let next_tick_height = self.tick_height + 1;
 | 
					        let next_tick_height = self.tick_height + 1;
 | 
				
			||||||
        let next_leader_slot = (next_tick_height - 1) / self.ticks_per_slot;
 | 
					        let next_poh_slot = self.slot_for_tick_height(next_tick_height);
 | 
				
			||||||
        if let Some(leader_first_tick_height) = self.leader_first_tick_height {
 | 
					        if let Some(leader_first_tick_height_including_grace_ticks) =
 | 
				
			||||||
            let target_tick_height = leader_first_tick_height.saturating_sub(1);
 | 
					            self.leader_first_tick_height_including_grace_ticks
 | 
				
			||||||
            if self.reached_leader_tick(leader_first_tick_height) {
 | 
					        {
 | 
				
			||||||
 | 
					            if self.reached_leader_tick(leader_first_tick_height_including_grace_ticks) {
 | 
				
			||||||
                assert!(next_tick_height >= self.start_tick_height);
 | 
					                assert!(next_tick_height >= self.start_tick_height);
 | 
				
			||||||
                let ideal_target_tick_height = target_tick_height.saturating_sub(self.grace_ticks);
 | 
					                let poh_slot = next_poh_slot;
 | 
				
			||||||
 | 
					                let parent_slot = self.start_slot();
 | 
				
			||||||
                return (
 | 
					                return PohLeaderStatus::Reached {
 | 
				
			||||||
                    true,
 | 
					                    poh_slot,
 | 
				
			||||||
                    self.tick_height.saturating_sub(ideal_target_tick_height),
 | 
					                    parent_slot,
 | 
				
			||||||
                    next_leader_slot,
 | 
					                };
 | 
				
			||||||
                    self.start_slot(),
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        (false, 0, next_leader_slot, self.start_slot())
 | 
					        PohLeaderStatus::NotReached
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // returns (leader_first_tick_height, leader_last_tick_height, grace_ticks) given the next
 | 
					    // returns (leader_first_tick_height_including_grace_ticks, leader_last_tick_height, grace_ticks) given the next
 | 
				
			||||||
    //  slot this recorder will lead
 | 
					    //  slot this recorder will lead
 | 
				
			||||||
    fn compute_leader_slot_tick_heights(
 | 
					    fn compute_leader_slot_tick_heights(
 | 
				
			||||||
        next_leader_slot: Option<(Slot, Slot)>,
 | 
					        next_leader_slot: Option<(Slot, Slot)>,
 | 
				
			||||||
@@ -390,8 +410,10 @@ impl PohRecorder {
 | 
				
			|||||||
                    ticks_per_slot * MAX_GRACE_SLOTS,
 | 
					                    ticks_per_slot * MAX_GRACE_SLOTS,
 | 
				
			||||||
                    ticks_per_slot * num_slots / GRACE_TICKS_FACTOR,
 | 
					                    ticks_per_slot * num_slots / GRACE_TICKS_FACTOR,
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
 | 
					                let leader_first_tick_height_including_grace_ticks =
 | 
				
			||||||
 | 
					                    leader_first_tick_height + grace_ticks;
 | 
				
			||||||
                (
 | 
					                (
 | 
				
			||||||
                    Some(leader_first_tick_height + grace_ticks),
 | 
					                    Some(leader_first_tick_height_including_grace_ticks),
 | 
				
			||||||
                    last_tick_height,
 | 
					                    last_tick_height,
 | 
				
			||||||
                    grace_ticks,
 | 
					                    grace_ticks,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
@@ -431,10 +453,11 @@ impl PohRecorder {
 | 
				
			|||||||
        self.tick_height = (self.start_slot() + 1) * self.ticks_per_slot;
 | 
					        self.tick_height = (self.start_slot() + 1) * self.ticks_per_slot;
 | 
				
			||||||
        self.start_tick_height = self.tick_height + 1;
 | 
					        self.start_tick_height = self.tick_height + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (leader_first_tick_height, leader_last_tick_height, grace_ticks) =
 | 
					        let (leader_first_tick_height_including_grace_ticks, leader_last_tick_height, grace_ticks) =
 | 
				
			||||||
            Self::compute_leader_slot_tick_heights(next_leader_slot, self.ticks_per_slot);
 | 
					            Self::compute_leader_slot_tick_heights(next_leader_slot, self.ticks_per_slot);
 | 
				
			||||||
        self.grace_ticks = grace_ticks;
 | 
					        self.grace_ticks = grace_ticks;
 | 
				
			||||||
        self.leader_first_tick_height = leader_first_tick_height;
 | 
					        self.leader_first_tick_height_including_grace_ticks =
 | 
				
			||||||
 | 
					            leader_first_tick_height_including_grace_ticks;
 | 
				
			||||||
        self.leader_last_tick_height = leader_last_tick_height;
 | 
					        self.leader_last_tick_height = leader_last_tick_height;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -537,7 +560,10 @@ impl PohRecorder {
 | 
				
			|||||||
            self.tick_height += 1;
 | 
					            self.tick_height += 1;
 | 
				
			||||||
            trace!("tick_height {}", self.tick_height);
 | 
					            trace!("tick_height {}", self.tick_height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if self.leader_first_tick_height.is_none() {
 | 
					            if self
 | 
				
			||||||
 | 
					                .leader_first_tick_height_including_grace_ticks
 | 
				
			||||||
 | 
					                .is_none()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                self.tick_overhead_us += timing::duration_as_us(&now.elapsed());
 | 
					                self.tick_overhead_us += timing::duration_as_us(&now.elapsed());
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -682,7 +708,7 @@ impl PohRecorder {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
        let (sender, receiver) = channel();
 | 
					        let (sender, receiver) = channel();
 | 
				
			||||||
        let (record_sender, record_receiver) = unbounded();
 | 
					        let (record_sender, record_receiver) = unbounded();
 | 
				
			||||||
        let (leader_first_tick_height, leader_last_tick_height, grace_ticks) =
 | 
					        let (leader_first_tick_height_including_grace_ticks, leader_last_tick_height, grace_ticks) =
 | 
				
			||||||
            Self::compute_leader_slot_tick_heights(next_leader_slot, ticks_per_slot);
 | 
					            Self::compute_leader_slot_tick_heights(next_leader_slot, ticks_per_slot);
 | 
				
			||||||
        (
 | 
					        (
 | 
				
			||||||
            Self {
 | 
					            Self {
 | 
				
			||||||
@@ -694,7 +720,7 @@ impl PohRecorder {
 | 
				
			|||||||
                clear_bank_signal,
 | 
					                clear_bank_signal,
 | 
				
			||||||
                start_bank,
 | 
					                start_bank,
 | 
				
			||||||
                start_tick_height: tick_height + 1,
 | 
					                start_tick_height: tick_height + 1,
 | 
				
			||||||
                leader_first_tick_height,
 | 
					                leader_first_tick_height_including_grace_ticks,
 | 
				
			||||||
                leader_last_tick_height,
 | 
					                leader_last_tick_height,
 | 
				
			||||||
                grace_ticks,
 | 
					                grace_ticks,
 | 
				
			||||||
                id: *id,
 | 
					                id: *id,
 | 
				
			||||||
@@ -1593,12 +1619,18 @@ mod tests {
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test that with no next leader slot, we don't reach the leader slot
 | 
					            // Test that with no next leader slot, we don't reach the leader slot
 | 
				
			||||||
            assert!(!poh_recorder.reached_leader_slot().0);
 | 
					            assert_eq!(
 | 
				
			||||||
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
 | 
					                PohLeaderStatus::NotReached
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test that with no next leader slot in reset(), we don't reach the leader slot
 | 
					            // Test that with no next leader slot in reset(), we don't reach the leader slot
 | 
				
			||||||
            assert_eq!(bank0.slot(), 0);
 | 
					            assert_eq!(bank0.slot(), 0);
 | 
				
			||||||
            poh_recorder.reset(bank0.clone(), None);
 | 
					            poh_recorder.reset(bank0.clone(), None);
 | 
				
			||||||
            assert!(!poh_recorder.reached_leader_slot().0);
 | 
					            assert_eq!(
 | 
				
			||||||
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
 | 
					                PohLeaderStatus::NotReached
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Provide a leader slot one slot down
 | 
					            // Provide a leader slot one slot down
 | 
				
			||||||
            poh_recorder.reset(bank0.clone(), Some((2, 2)));
 | 
					            poh_recorder.reset(bank0.clone(), Some((2, 2)));
 | 
				
			||||||
@@ -1626,17 +1658,22 @@ mod tests {
 | 
				
			|||||||
                .unwrap();
 | 
					                .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test that we don't reach the leader slot because of grace ticks
 | 
					            // Test that we don't reach the leader slot because of grace ticks
 | 
				
			||||||
            assert!(!poh_recorder.reached_leader_slot().0);
 | 
					            assert_eq!(
 | 
				
			||||||
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
 | 
					                PohLeaderStatus::NotReached
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // reset poh now. we should immediately be leader
 | 
					            // reset poh now. we should immediately be leader
 | 
				
			||||||
            let bank1 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 1));
 | 
					            let bank1 = Arc::new(Bank::new_from_parent(&bank0, &Pubkey::default(), 1));
 | 
				
			||||||
            assert_eq!(bank1.slot(), 1);
 | 
					            assert_eq!(bank1.slot(), 1);
 | 
				
			||||||
            poh_recorder.reset(bank1.clone(), Some((2, 2)));
 | 
					            poh_recorder.reset(bank1.clone(), Some((2, 2)));
 | 
				
			||||||
            let (reached_leader_slot, grace_ticks, leader_slot, ..) =
 | 
					            assert_eq!(
 | 
				
			||||||
                poh_recorder.reached_leader_slot();
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
            assert!(reached_leader_slot);
 | 
					                PohLeaderStatus::Reached {
 | 
				
			||||||
            assert_eq!(grace_ticks, 0);
 | 
					                    poh_slot: 2,
 | 
				
			||||||
            assert_eq!(leader_slot, 2);
 | 
					                    parent_slot: 1,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Now test that with grace ticks we can reach leader slot
 | 
					            // Now test that with grace ticks we can reach leader slot
 | 
				
			||||||
            // Set the leader slot one slot down
 | 
					            // Set the leader slot one slot down
 | 
				
			||||||
@@ -1648,7 +1685,10 @@ mod tests {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // We are not the leader yet, as expected
 | 
					            // We are not the leader yet, as expected
 | 
				
			||||||
            assert!(!poh_recorder.reached_leader_slot().0);
 | 
					            assert_eq!(
 | 
				
			||||||
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
 | 
					                PohLeaderStatus::NotReached
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Send the grace ticks
 | 
					            // Send the grace ticks
 | 
				
			||||||
            for _ in 0..bank1.ticks_per_slot() / GRACE_TICKS_FACTOR {
 | 
					            for _ in 0..bank1.ticks_per_slot() / GRACE_TICKS_FACTOR {
 | 
				
			||||||
@@ -1656,11 +1696,14 @@ mod tests {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // We should be the leader now
 | 
					            // We should be the leader now
 | 
				
			||||||
            let (reached_leader_slot, grace_ticks, leader_slot, ..) =
 | 
					            // without sending more ticks, we should be leader now
 | 
				
			||||||
                poh_recorder.reached_leader_slot();
 | 
					            assert_eq!(
 | 
				
			||||||
            assert!(reached_leader_slot);
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
            assert_eq!(grace_ticks, bank1.ticks_per_slot() / GRACE_TICKS_FACTOR);
 | 
					                PohLeaderStatus::Reached {
 | 
				
			||||||
            assert_eq!(leader_slot, 3);
 | 
					                    poh_slot: 3,
 | 
				
			||||||
 | 
					                    parent_slot: 1,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Let's test that correct grace ticks are reported
 | 
					            // Let's test that correct grace ticks are reported
 | 
				
			||||||
            // Set the leader slot one slot down
 | 
					            // Set the leader slot one slot down
 | 
				
			||||||
@@ -1673,17 +1716,22 @@ mod tests {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // We are not the leader yet, as expected
 | 
					            // We are not the leader yet, as expected
 | 
				
			||||||
            assert!(!poh_recorder.reached_leader_slot().0);
 | 
					            assert_eq!(
 | 
				
			||||||
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
 | 
					                PohLeaderStatus::NotReached
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
            let bank3 = Arc::new(Bank::new_from_parent(&bank2, &Pubkey::default(), 3));
 | 
					            let bank3 = Arc::new(Bank::new_from_parent(&bank2, &Pubkey::default(), 3));
 | 
				
			||||||
            assert_eq!(bank3.slot(), 3);
 | 
					            assert_eq!(bank3.slot(), 3);
 | 
				
			||||||
            poh_recorder.reset(bank3.clone(), Some((4, 4)));
 | 
					            poh_recorder.reset(bank3.clone(), Some((4, 4)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // without sending more ticks, we should be leader now
 | 
					            // without sending more ticks, we should be leader now
 | 
				
			||||||
            let (reached_leader_slot, grace_ticks, leader_slot, ..) =
 | 
					            assert_eq!(
 | 
				
			||||||
                poh_recorder.reached_leader_slot();
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
            assert!(reached_leader_slot);
 | 
					                PohLeaderStatus::Reached {
 | 
				
			||||||
            assert_eq!(grace_ticks, 0);
 | 
					                    poh_slot: 4,
 | 
				
			||||||
            assert_eq!(leader_slot, 4);
 | 
					                    parent_slot: 3,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Let's test that if a node overshoots the ticks for its target
 | 
					            // Let's test that if a node overshoots the ticks for its target
 | 
				
			||||||
            // leader slot, reached_leader_slot() will return true, because it's overdue
 | 
					            // leader slot, reached_leader_slot() will return true, because it's overdue
 | 
				
			||||||
@@ -1698,11 +1746,13 @@ mod tests {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // We are overdue to lead
 | 
					            // We are overdue to lead
 | 
				
			||||||
            let (reached_leader_slot, grace_ticks, leader_slot, ..) =
 | 
					            assert_eq!(
 | 
				
			||||||
                poh_recorder.reached_leader_slot();
 | 
					                poh_recorder.reached_leader_slot(),
 | 
				
			||||||
            assert!(reached_leader_slot);
 | 
					                PohLeaderStatus::Reached {
 | 
				
			||||||
            assert_eq!(grace_ticks, overshoot_factor * bank4.ticks_per_slot());
 | 
					                    poh_slot: 9,
 | 
				
			||||||
            assert_eq!(leader_slot, 9);
 | 
					                    parent_slot: 4,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Blockstore::destroy(&ledger_path).unwrap();
 | 
					        Blockstore::destroy(&ledger_path).unwrap();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user