use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, OnceLock};
use std::time::{SystemTime, UNIX_EPOCH};
use tokio::sync::mpsc;
pub trait WallClock: Send + Sync {
fn unix_ms(&self) -> u64;
}
pub struct SystemWallClock;
impl WallClock for SystemWallClock {
fn unix_ms(&self) -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_millis() as u64)
.unwrap_or(0)
}
}
pub struct FakeWallClock {
ms: AtomicU64,
}
impl FakeWallClock {
pub fn new(ms: u64) -> Arc<Self> {
Arc::new(Self {
ms: AtomicU64::new(ms),
})
}
pub fn set(&self, ms: u64) {
self.ms.store(ms, Ordering::SeqCst);
}
}
impl WallClock for FakeWallClock {
fn unix_ms(&self) -> u64 {
self.ms.load(Ordering::SeqCst)
}
}
#[derive(Debug, Clone, Copy)]
pub enum ChainEvent {
Connected {
height: u64,
hash: [u8; 32],
mtp: u64,
},
Disconnected {
height: u64,
hash: [u8; 32],
},
}
static CHAIN_TX: OnceLock<mpsc::UnboundedSender<ChainEvent>> = OnceLock::new();
pub(crate) fn install_chain_feed(tx: mpsc::UnboundedSender<ChainEvent>) {
let _ = CHAIN_TX.set(tx);
}
pub fn dispatch_chain(event: ChainEvent) {
if let Some(tx) = CHAIN_TX.get() {
let _ = tx.send(event);
}
}