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.
This commit is contained in:
Michael Sproul 2022-08-29 14:34:43 +00:00
parent 1a833ecc17
commit 7a50684741

View File

@ -33,20 +33,9 @@ pub fn spawn_notifier<T: BeaconChainTypes>(
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<T: BeaconChainTypes>(
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();