use {
agave_votor_messages::consensus_message::Block,
crossbeam_channel::{Receiver, Sender},
solana_clock::Slot,
solana_runtime::bank::Bank,
std::{
sync::{Arc, Mutex},
time::Instant,
},
};
#[derive(Debug, Clone)]
pub struct CompletedBlock {
pub slot: Slot,
pub bank: Arc<Bank>,
}
#[derive(Copy, Clone, Debug)]
pub struct LeaderWindowInfo {
pub start_slot: Slot,
pub end_slot: Slot,
pub parent_block: Block,
pub block_timer: Instant,
}
pub type VotorEventSender = Sender<VotorEvent>;
pub type VotorEventReceiver = Receiver<VotorEvent>;
#[derive(Debug, Clone)]
pub enum VotorEvent {
Block(CompletedBlock),
BlockNotarized(Block),
BlockNotarFallback(Block),
FirstShred(Slot),
ParentReady { slot: Slot, parent_block: Block },
TimeoutCrashedLeader(Slot),
Timeout(Slot),
SafeToNotar(Block),
SafeToSkip(Slot),
ProduceWindow(LeaderWindowInfo),
Finalized(Block, bool),
Standstill(Slot),
SetIdentity,
}
impl VotorEvent {
pub(crate) fn should_ignore(&self, root: Slot) -> bool {
match self {
VotorEvent::Block(completed_block) => completed_block.slot <= root,
VotorEvent::Timeout(s)
| VotorEvent::SafeToSkip(s)
| VotorEvent::TimeoutCrashedLeader(s)
| VotorEvent::FirstShred(s)
| VotorEvent::SafeToNotar(Block {
slot: s,
block_id: _,
})
| VotorEvent::Finalized(
Block {
slot: s,
block_id: _,
},
_,
)
| VotorEvent::BlockNotarized(Block {
slot: s,
block_id: _,
})
| VotorEvent::BlockNotarFallback(Block {
slot: s,
block_id: _,
})
| VotorEvent::ParentReady {
slot: s,
parent_block: _,
} => s <= &root,
VotorEvent::Standstill(s) => s < &root,
VotorEvent::ProduceWindow(info) => info.start_slot <= root,
VotorEvent::SetIdentity => false,
}
}
}
pub type RepairEventSender = Sender<RepairEvent>;
pub type RepairEventReceiver = Receiver<RepairEvent>;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum RepairEvent {
FetchBlock { block: Block },
}
impl RepairEvent {
pub fn slot(&self) -> Slot {
match self {
RepairEvent::FetchBlock { block } => block.slot,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum SwitchBankEvent {
Switch { block: Block },
}
impl SwitchBankEvent {
pub fn block(&self) -> Block {
match self {
SwitchBankEvent::Switch { block } => *block,
}
}
}
#[derive(Clone, Default)]
pub struct LatestSwitchRequest(Arc<Mutex<Option<SwitchBankEvent>>>);
impl LatestSwitchRequest {
pub fn try_advance(&self, event: SwitchBankEvent) -> Option<SwitchBankEvent> {
let mut guard = self.0.lock().unwrap();
match guard.as_ref() {
Some(cur) if event <= *cur => None,
_ => guard.replace(event),
}
}
pub fn take(&self) -> Option<SwitchBankEvent> {
self.0.lock().unwrap().take()
}
}