1use {
4 crossbeam_channel::{Receiver, Sender},
5 log::*,
6 solana_clock::Slot,
7 std::fmt,
8};
9
10pub type PohTimingReceiver = Receiver<SlotPohTimingInfo>;
12
13pub type PohTimingSender = Sender<SlotPohTimingInfo>;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum PohTimingPoint {
19 PohSlotStart(u64),
20 PohSlotEnd(u64),
21 FullSlotReceived(u64),
22}
23
24impl fmt::Display for PohTimingPoint {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 match *self {
27 PohTimingPoint::PohSlotStart(t) => write!(f, "poh_start={t}"),
28 PohTimingPoint::PohSlotEnd(t) => write!(f, "poh_end ={t}"),
29 PohTimingPoint::FullSlotReceived(t) => write!(f, "poh_full ={t}"),
30 }
31 }
32}
33
34#[derive(Clone, Debug)]
37pub struct SlotPohTimingInfo {
38 pub slot: Slot,
40 pub root_slot: Option<Slot>,
42 pub timing_point: PohTimingPoint,
44}
45
46impl fmt::Display for SlotPohTimingInfo {
47 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48 write!(
49 f,
50 "PohTimingPoint: {}, slot={}, root_slot={}",
51 self.timing_point,
52 self.slot,
53 self.root_slot.unwrap_or(0),
54 )
55 }
56}
57
58impl SlotPohTimingInfo {
59 pub fn new_slot_start_poh_time_point(
61 slot: Slot,
62 root_slot: Option<Slot>,
63 timestamp: u64,
64 ) -> SlotPohTimingInfo {
65 SlotPohTimingInfo {
66 slot,
67 root_slot,
68 timing_point: PohTimingPoint::PohSlotStart(timestamp),
69 }
70 }
71
72 pub fn new_slot_end_poh_time_point(
74 slot: Slot,
75 root_slot: Option<Slot>,
76 timestamp: u64,
77 ) -> SlotPohTimingInfo {
78 SlotPohTimingInfo {
79 slot,
80 root_slot,
81 timing_point: PohTimingPoint::PohSlotEnd(timestamp),
82 }
83 }
84
85 pub fn new_slot_full_poh_time_point(
87 slot: Slot,
88 root_slot: Option<Slot>,
89 timestamp: u64,
90 ) -> SlotPohTimingInfo {
91 SlotPohTimingInfo {
92 slot,
93 root_slot,
94 timing_point: PohTimingPoint::FullSlotReceived(timestamp),
95 }
96 }
97}
98
99pub fn send_poh_timing_point(sender: &PohTimingSender, slot_timing: SlotPohTimingInfo) {
101 trace!("{}", slot_timing);
102 if let Err(e) = sender.try_send(slot_timing) {
103 info!("failed to send slot poh timing {:?}", e);
104 }
105}
106
107#[cfg(test)]
108mod test {
109 use super::*;
110 #[test]
111 fn test_poh_timing_point() {
112 let p = SlotPohTimingInfo::new_slot_start_poh_time_point(100, Some(101), 100);
114 assert!(p.slot == 100);
115 assert_eq!(p.root_slot, Some(101));
116 assert_eq!(p.timing_point, PohTimingPoint::PohSlotStart(100));
117 assert_eq!(
118 format!("{p}"),
119 "PohTimingPoint: poh_start=100, slot=100, root_slot=101"
120 );
121
122 let p = SlotPohTimingInfo::new_slot_start_poh_time_point(100, None, 100);
124 assert!(p.slot == 100);
125 assert_eq!(p.root_slot, None);
126 assert_eq!(p.timing_point, PohTimingPoint::PohSlotStart(100));
127 assert_eq!(
128 format!("{p}"),
129 "PohTimingPoint: poh_start=100, slot=100, root_slot=0"
130 );
131
132 let p = SlotPohTimingInfo::new_slot_end_poh_time_point(100, Some(101), 100);
134 assert!(p.slot == 100);
135 assert_eq!(p.root_slot, Some(101));
136 assert_eq!(p.timing_point, PohTimingPoint::PohSlotEnd(100));
137 assert_eq!(
138 format!("{p}"),
139 "PohTimingPoint: poh_end =100, slot=100, root_slot=101"
140 );
141
142 let p = SlotPohTimingInfo::new_slot_end_poh_time_point(100, None, 100);
144 assert!(p.slot == 100);
145 assert_eq!(p.root_slot, None);
146 assert_eq!(p.timing_point, PohTimingPoint::PohSlotEnd(100));
147 assert_eq!(
148 format!("{p}"),
149 "PohTimingPoint: poh_end =100, slot=100, root_slot=0"
150 );
151
152 let p = SlotPohTimingInfo::new_slot_full_poh_time_point(100, Some(101), 100);
154 assert!(p.slot == 100);
155 assert_eq!(p.root_slot, Some(101));
156 assert_eq!(p.timing_point, PohTimingPoint::FullSlotReceived(100));
157 assert_eq!(
158 format!("{p}"),
159 "PohTimingPoint: poh_full =100, slot=100, root_slot=101"
160 );
161
162 let p = SlotPohTimingInfo::new_slot_full_poh_time_point(100, None, 100);
164 assert!(p.slot == 100);
165 assert_eq!(p.root_slot, None);
166 assert_eq!(p.timing_point, PohTimingPoint::FullSlotReceived(100));
167
168 assert_eq!(
169 format!("{p}"),
170 "PohTimingPoint: poh_full =100, slot=100, root_slot=0"
171 );
172 }
173}