find next leader slot before resetting working bank in Poh recorder
This commit is contained in:
parent
205907d3d7
commit
1824e09d0a
|
@ -18,6 +18,7 @@ use crate::sigverify_stage::VerifiedPackets;
|
|||
use bincode::deserialize;
|
||||
use solana_metrics::counter::Counter;
|
||||
use solana_runtime::bank::{self, Bank};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::timing::{self, duration_as_us, MAX_RECENT_BLOCKHASHES};
|
||||
use solana_sdk::transaction::{Transaction, TransactionError};
|
||||
use std::net::UdpSocket;
|
||||
|
@ -459,6 +460,7 @@ pub fn create_test_recorder(
|
|||
bank.slot(),
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
poh_recorder.set_bank(&bank);
|
||||
|
||||
|
@ -699,6 +701,7 @@ mod tests {
|
|||
bank.slot(),
|
||||
None,
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
let poh_recorder = Arc::new(Mutex::new(poh_recorder));
|
||||
|
||||
|
@ -757,6 +760,7 @@ mod tests {
|
|||
bank.slot(),
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
pubkey,
|
||||
);
|
||||
let poh_recorder = Arc::new(Mutex::new(poh_recorder));
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ impl Fullnode {
|
|||
bank.slot(),
|
||||
leader_schedule_utils::next_leader_slot(&id, bank.slot(), &bank),
|
||||
bank.ticks_per_slot(),
|
||||
id,
|
||||
);
|
||||
let poh_recorder = Arc::new(Mutex::new(poh_recorder));
|
||||
let poh_service = PohService::new(poh_recorder.clone(), &config.tick_config, &exit);
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
//! * recorded entry must be >= WorkingBank::min_tick_height && entry must be < WorkingBank::man_tick_height
|
||||
//!
|
||||
use crate::entry::Entry;
|
||||
use crate::leader_schedule_utils;
|
||||
use crate::poh::Poh;
|
||||
use crate::result::{Error, Result};
|
||||
use solana_runtime::bank::Bank;
|
||||
use solana_sdk::hash::Hash;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::transaction::Transaction;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender, SyncSender};
|
||||
use std::sync::Arc;
|
||||
|
@ -47,11 +49,21 @@ pub struct PohRecorder {
|
|||
sender: Sender<WorkingBankEntries>,
|
||||
start_leader_at_tick: Option<u64>,
|
||||
max_last_leader_grace_ticks: u64,
|
||||
id: Pubkey,
|
||||
}
|
||||
|
||||
impl PohRecorder {
|
||||
pub fn clear_bank(&mut self) {
|
||||
self.working_bank = None;
|
||||
if let Some(bank) = &self.working_bank {
|
||||
let next_leader_slot =
|
||||
leader_schedule_utils::next_leader_slot(&self.id, bank.bank.slot(), &bank.bank);
|
||||
self.start_leader_at_tick = next_leader_slot
|
||||
.map(|slot| {
|
||||
Some(slot * bank.bank.ticks_per_slot() + self.max_last_leader_grace_ticks)
|
||||
})
|
||||
.unwrap_or(None);
|
||||
self.working_bank = None;
|
||||
}
|
||||
if let Some(ref signal) = self.clear_bank_signal {
|
||||
let _ = signal.try_send(true);
|
||||
}
|
||||
|
@ -79,8 +91,6 @@ impl PohRecorder {
|
|||
pub fn reached_leader_tick(&self) -> (bool, u64) {
|
||||
self.start_leader_at_tick
|
||||
.map(|target_tick| {
|
||||
// Either grace period has expired,
|
||||
// or target tick is = grace period (i.e. poh recorder was just reset)
|
||||
debug!(
|
||||
"Current tick {}, start tick {} target {}, grace {}",
|
||||
self.tick_height(),
|
||||
|
@ -92,6 +102,9 @@ impl PohRecorder {
|
|||
let leader_ideal_start_tick =
|
||||
target_tick.saturating_sub(self.max_last_leader_grace_ticks);
|
||||
|
||||
// Is the current tick in the same slot as the target tick?
|
||||
// Check if either grace period has expired,
|
||||
// or target tick is = grace period (i.e. poh recorder was just reset)
|
||||
if self.tick_height().saturating_sub(target_tick) < self.max_last_leader_grace_ticks
|
||||
&& (self.tick_height() >= target_tick
|
||||
|| self.max_last_leader_grace_ticks
|
||||
|
@ -236,6 +249,7 @@ impl PohRecorder {
|
|||
start_slot: u64,
|
||||
my_leader_slot_index: Option<u64>,
|
||||
ticks_per_slot: u64,
|
||||
id: Pubkey,
|
||||
) -> (Self, Receiver<WorkingBankEntries>) {
|
||||
let poh = Poh::new(last_entry_hash, tick_height);
|
||||
let (sender, receiver) = channel();
|
||||
|
@ -257,6 +271,7 @@ impl PohRecorder {
|
|||
})
|
||||
.unwrap_or(None),
|
||||
max_last_leader_grace_ticks: ticks_per_slot / MAX_LAST_LEADER_GRACE_TICKS_FACTOR,
|
||||
id,
|
||||
},
|
||||
receiver,
|
||||
)
|
||||
|
@ -309,8 +324,14 @@ mod tests {
|
|||
#[test]
|
||||
fn test_poh_recorder_no_zero_tick() {
|
||||
let prev_hash = Hash::default();
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), DEFAULT_TICKS_PER_SLOT);
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
Pubkey::default(),
|
||||
);
|
||||
poh_recorder.tick();
|
||||
assert_eq!(poh_recorder.tick_cache.len(), 1);
|
||||
assert_eq!(poh_recorder.tick_cache[0].1, 1);
|
||||
|
@ -320,8 +341,14 @@ mod tests {
|
|||
#[test]
|
||||
fn test_poh_recorder_tick_height_is_last_tick() {
|
||||
let prev_hash = Hash::default();
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), DEFAULT_TICKS_PER_SLOT);
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
Pubkey::default(),
|
||||
);
|
||||
poh_recorder.tick();
|
||||
poh_recorder.tick();
|
||||
assert_eq!(poh_recorder.tick_cache.len(), 2);
|
||||
|
@ -331,8 +358,14 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_poh_recorder_reset_clears_cache() {
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, Hash::default(), 0, Some(4), DEFAULT_TICKS_PER_SLOT);
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
Hash::default(),
|
||||
0,
|
||||
Some(4),
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
Pubkey::default(),
|
||||
);
|
||||
poh_recorder.tick();
|
||||
assert_eq!(poh_recorder.tick_cache.len(), 1);
|
||||
poh_recorder.reset(0, Hash::default(), 0, Some(4), DEFAULT_TICKS_PER_SLOT);
|
||||
|
@ -344,8 +377,14 @@ mod tests {
|
|||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
let working_bank = WorkingBank {
|
||||
bank,
|
||||
|
@ -363,8 +402,14 @@ mod tests {
|
|||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
let working_bank = WorkingBank {
|
||||
bank: bank.clone(),
|
||||
|
@ -394,8 +439,14 @@ mod tests {
|
|||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
poh_recorder.tick();
|
||||
poh_recorder.tick();
|
||||
|
@ -423,8 +474,14 @@ mod tests {
|
|||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
let working_bank = WorkingBank {
|
||||
bank,
|
||||
|
@ -444,8 +501,14 @@ mod tests {
|
|||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
let working_bank = WorkingBank {
|
||||
bank,
|
||||
|
@ -474,8 +537,14 @@ mod tests {
|
|||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
let working_bank = WorkingBank {
|
||||
bank,
|
||||
|
@ -501,8 +570,14 @@ mod tests {
|
|||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
let working_bank = WorkingBank {
|
||||
bank,
|
||||
|
@ -521,8 +596,14 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_reset_current() {
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, Hash::default(), 0, Some(4), DEFAULT_TICKS_PER_SLOT);
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
Hash::default(),
|
||||
0,
|
||||
Some(4),
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
Pubkey::default(),
|
||||
);
|
||||
poh_recorder.tick();
|
||||
poh_recorder.tick();
|
||||
assert_eq!(poh_recorder.tick_cache.len(), 2);
|
||||
|
@ -538,8 +619,14 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_reset_with_cached() {
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, Hash::default(), 0, Some(4), DEFAULT_TICKS_PER_SLOT);
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
Hash::default(),
|
||||
0,
|
||||
Some(4),
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
Pubkey::default(),
|
||||
);
|
||||
poh_recorder.tick();
|
||||
poh_recorder.tick();
|
||||
assert_eq!(poh_recorder.tick_cache.len(), 2);
|
||||
|
@ -555,8 +642,14 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_reset_to_new_value() {
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, Hash::default(), 0, Some(4), DEFAULT_TICKS_PER_SLOT);
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
Hash::default(),
|
||||
0,
|
||||
Some(4),
|
||||
DEFAULT_TICKS_PER_SLOT,
|
||||
Pubkey::default(),
|
||||
);
|
||||
poh_recorder.tick();
|
||||
poh_recorder.tick();
|
||||
poh_recorder.tick();
|
||||
|
@ -572,8 +665,14 @@ mod tests {
|
|||
fn test_reset_clear_bank() {
|
||||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, Hash::default(), 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
Hash::default(),
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
let ticks_per_slot = bank.ticks_per_slot();
|
||||
let working_bank = WorkingBank {
|
||||
bank,
|
||||
|
@ -589,8 +688,14 @@ mod tests {
|
|||
pub fn test_clear_signal() {
|
||||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, Hash::default(), 0, None, bank.ticks_per_slot());
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
Hash::default(),
|
||||
0,
|
||||
None,
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
let (sender, receiver) = sync_channel(1);
|
||||
poh_recorder.set_bank(&bank);
|
||||
poh_recorder.clear_bank_signal = Some(sender);
|
||||
|
@ -606,8 +711,14 @@ mod tests {
|
|||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, Some(4), bank.ticks_per_slot());
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
let end_slot = 3;
|
||||
let max_tick_height = (end_slot + 1) * ticks_per_slot - 1;
|
||||
|
@ -635,8 +746,14 @@ mod tests {
|
|||
let (genesis_block, _mint_keypair) = GenesisBlock::new(2);
|
||||
let bank = Arc::new(Bank::new(&genesis_block));
|
||||
let prev_hash = bank.last_blockhash();
|
||||
let (mut poh_recorder, _entry_receiver) =
|
||||
PohRecorder::new(0, prev_hash, 0, None, bank.ticks_per_slot());
|
||||
let (mut poh_recorder, _entry_receiver) = PohRecorder::new(
|
||||
0,
|
||||
prev_hash,
|
||||
0,
|
||||
None,
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
|
||||
// Test that with no leader slot, we don't reach the leader tick
|
||||
assert_eq!(poh_recorder.reached_leader_tick().0, false);
|
||||
|
|
|
@ -104,6 +104,7 @@ mod tests {
|
|||
use solana_runtime::bank::Bank;
|
||||
use solana_sdk::genesis_block::GenesisBlock;
|
||||
use solana_sdk::hash::hash;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
|
||||
#[test]
|
||||
fn test_poh_service() {
|
||||
|
@ -116,6 +117,7 @@ mod tests {
|
|||
bank.slot(),
|
||||
Some(4),
|
||||
bank.ticks_per_slot(),
|
||||
Pubkey::default(),
|
||||
);
|
||||
let poh_recorder = Arc::new(Mutex::new(poh_recorder));
|
||||
let exit = Arc::new(AtomicBool::new(false));
|
||||
|
|
Loading…
Reference in New Issue