From 7a50684741abd707b06a0a726439da2ec737edf6 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Mon, 29 Aug 2022 14:34:43 +0000 Subject: [PATCH] Harden slot notifier against clock drift (#3519) ## Issue Addressed Partly resolves #3518 ## Proposed Changes Change the slot notifier to use `duration_to_next_slot` rather than an interval timer. This makes it robust against underlying clock changes. --- beacon_node/client/src/notifier.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/beacon_node/client/src/notifier.rs b/beacon_node/client/src/notifier.rs index 11f0f6e2a..1da7a7970 100644 --- a/beacon_node/client/src/notifier.rs +++ b/beacon_node/client/src/notifier.rs @@ -33,20 +33,9 @@ pub fn spawn_notifier( seconds_per_slot: u64, ) -> Result<(), String> { let slot_duration = Duration::from_secs(seconds_per_slot); - let duration_to_next_slot = beacon_chain - .slot_clock - .duration_to_next_slot() - .ok_or("slot_notifier unable to determine time to next slot")?; - - // Run this half way through each slot. - let start_instant = tokio::time::Instant::now() + duration_to_next_slot + (slot_duration / 2); - - // Run this each slot. - let interval_duration = slot_duration; let speedo = Mutex::new(Speedo::default()); let log = executor.log().clone(); - let mut interval = tokio::time::interval_at(start_instant, interval_duration); // Keep track of sync state and reset the speedo on specific sync state changes. // Specifically, if we switch between a sync and a backfill sync, reset the speedo. @@ -82,7 +71,20 @@ pub fn spawn_notifier( let mut last_backfill_log_slot = None; loop { - interval.tick().await; + // Run the notifier half way through each slot. + // + // Keep remeasuring the offset rather than using an interval, so that we can correct + // for system time clock adjustments. + let wait = match beacon_chain.slot_clock.duration_to_next_slot() { + Some(duration) => duration + slot_duration / 2, + None => { + warn!(log, "Unable to read current slot"); + sleep(slot_duration).await; + continue; + } + }; + sleep(wait).await; + let connected_peer_count = network.connected_peers(); let sync_state = network.sync_state();