use std::{
sync::Arc,
time::{Duration, Instant},
};
use parking_lot::Mutex;
use sp_consensus::SyncOracle as SyncOracleT;
const OFFLINE_THRESHOLD: Duration = Duration::from_secs(6);
const FAR_BEHIND_THRESHOLD: u32 = 15;
const MAJOR_SYNC_THRESHOLD: Duration = Duration::from_secs(10);
#[derive(Clone)]
pub struct SyncOracle {
last_far_behind: Arc<Mutex<Instant>>,
last_update: Arc<Mutex<Instant>>,
}
impl SyncOracle {
pub fn new() -> Self {
SyncOracle {
last_update: Arc::new(Mutex::new(Instant::now() - OFFLINE_THRESHOLD)),
last_far_behind: Arc::new(Mutex::new(Instant::now())),
}
}
pub fn update_behind(&self, behind: u32) {
let now = Instant::now();
*self.last_update.lock() = now;
if behind > FAR_BEHIND_THRESHOLD {
*self.last_far_behind.lock() = now;
}
}
pub fn major_sync(&self) -> bool {
self.last_far_behind.lock().elapsed() < MAJOR_SYNC_THRESHOLD
}
}
impl Default for SyncOracle {
fn default() -> Self {
SyncOracle::new()
}
}
impl SyncOracleT for SyncOracle {
fn is_major_syncing(&self) -> bool {
self.major_sync()
}
fn is_offline(&self) -> bool {
self.last_update.lock().elapsed() > OFFLINE_THRESHOLD
}
}