Add slot timer to beacon node

This commit is contained in:
Paul Hauner
2019-03-27 10:36:20 +11:00
parent b887509607
commit b006586d19
9 changed files with 132 additions and 3 deletions

View File

@@ -3,10 +3,13 @@ mod testing_slot_clock;
pub use crate::system_time_slot_clock::{Error as SystemTimeSlotClockError, SystemTimeSlotClock};
pub use crate::testing_slot_clock::{Error as TestingSlotClockError, TestingSlotClock};
use std::time::Duration;
pub use types::Slot;
pub trait SlotClock: Send + Sync {
type Error;
fn present_slot(&self) -> Result<Option<Slot>, Self::Error>;
fn duration_to_next_slot(&self) -> Result<Option<Duration>, Self::Error>;
}

View File

@@ -54,6 +54,10 @@ impl SlotClock for SystemTimeSlotClock {
.and_then(|s| Some(s + self.genesis_slot))),
}
}
fn duration_to_next_slot(&self) -> Result<Option<Duration>, Error> {
duration_to_next_slot(self.genesis_seconds, self.slot_duration_seconds)
}
}
impl From<SystemTimeError> for Error {
@@ -67,6 +71,30 @@ fn slot_from_duration(slot_duration_seconds: u64, duration: Duration) -> Option<
duration.as_secs().checked_div(slot_duration_seconds)?,
))
}
// calculate the duration to the next slot
fn duration_to_next_slot(
genesis_time: u64,
seconds_per_slot: u64,
) -> Result<Option<Duration>, Error> {
let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
let genesis_time = Duration::from_secs(genesis_time);
if now < genesis_time {
return Ok(None);
}
let since_genesis = now - genesis_time;
let elapsed_slots = since_genesis.as_secs() / seconds_per_slot;
let next_slot_start_seconds = (elapsed_slots + 1)
.checked_mul(seconds_per_slot)
.expect("Next slot time should not overflow u64");
let time_to_next_slot = Duration::from_secs(next_slot_start_seconds) - since_genesis;
Ok(Some(time_to_next_slot))
}
#[cfg(test)]
mod tests {

View File

@@ -1,5 +1,6 @@
use super::SlotClock;
use std::sync::RwLock;
use std::time::Duration;
use types::Slot;
#[derive(Debug, PartialEq)]
@@ -32,6 +33,11 @@ impl SlotClock for TestingSlotClock {
let slot = *self.slot.read().expect("TestingSlotClock poisoned.");
Ok(Some(Slot::new(slot)))
}
/// Always returns a duration of 1 second.
fn duration_to_next_slot(&self) -> Result<Option<Duration>, Error> {
Ok(Some(Duration::from_secs(1)))
}
}
#[cfg(test)]