From 31c78b77183422d4906482ab27343a3abe156da4 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Sun, 30 Dec 2018 13:02:44 +1100 Subject: [PATCH] Rename slot-clock -> slock_clock --- beacon_chain/utils/slot-clock/src/lib.rs | 74 ---------- .../{slot-clock => slot_clock}/Cargo.toml | 2 +- beacon_chain/utils/slot_clock/src/lib.rs | 11 ++ .../slot_clock/src/system_time_slot_clock.rs | 135 ++++++++++++++++++ .../slot_clock/src/testing_slot_clock.rs | 43 ++++++ 5 files changed, 190 insertions(+), 75 deletions(-) delete mode 100644 beacon_chain/utils/slot-clock/src/lib.rs rename beacon_chain/utils/{slot-clock => slot_clock}/Cargo.toml (84%) create mode 100644 beacon_chain/utils/slot_clock/src/lib.rs create mode 100644 beacon_chain/utils/slot_clock/src/system_time_slot_clock.rs create mode 100644 beacon_chain/utils/slot_clock/src/testing_slot_clock.rs diff --git a/beacon_chain/utils/slot-clock/src/lib.rs b/beacon_chain/utils/slot-clock/src/lib.rs deleted file mode 100644 index ffd1b5a9e..000000000 --- a/beacon_chain/utils/slot-clock/src/lib.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::time::{Duration, SystemTime, SystemTimeError}; - -pub fn slot_now( - genesis_seconds: u64, - slot_duration_seconds: u64, -) -> Result, SystemTimeError> { - let sys_time = SystemTime::now(); - let duration_since_epoch = sys_time.duration_since(SystemTime::UNIX_EPOCH)?; - let duration_since_genesis = - duration_since_epoch.checked_sub(Duration::from_secs(genesis_seconds)); - match duration_since_genesis { - None => Ok(None), - Some(d) => Ok(slot_from_duration(slot_duration_seconds, d)), - } -} - -fn slot_from_duration(slot_duration_seconds: u64, duration: Duration) -> Option { - duration.as_secs().checked_div(slot_duration_seconds) -} - -#[cfg(test)] -mod tests { - use super::*; - - /* - * Note: these tests are using actual system times and could fail if they are executed on a - * very slow machine. - */ - #[test] - fn test_slot_now() { - let s_time = 100; - - let now = SystemTime::now(); - let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap(); - - let genesis = since_epoch.as_secs() - s_time * 89; - assert_eq!(slot_now(genesis, s_time).unwrap(), Some(89)); - - let genesis = since_epoch.as_secs(); - assert_eq!(slot_now(genesis, s_time).unwrap(), Some(0)); - - let genesis = since_epoch.as_secs() - s_time * 42 - 5; - assert_eq!(slot_now(genesis, s_time).unwrap(), Some(42)); - } - - #[test] - fn test_slot_from_duration() { - let s_time = 100; - - assert_eq!(slot_from_duration(s_time, Duration::from_secs(0)), Some(0)); - assert_eq!(slot_from_duration(s_time, Duration::from_secs(10)), Some(0)); - assert_eq!( - slot_from_duration(s_time, Duration::from_secs(100)), - Some(1) - ); - assert_eq!( - slot_from_duration(s_time, Duration::from_secs(101)), - Some(1) - ); - assert_eq!( - slot_from_duration(s_time, Duration::from_secs(1000)), - Some(10) - ); - } - - #[test] - fn test_slot_from_duration_slot_time_zero() { - let s_time = 0; - - assert_eq!(slot_from_duration(s_time, Duration::from_secs(0)), None); - assert_eq!(slot_from_duration(s_time, Duration::from_secs(10)), None); - assert_eq!(slot_from_duration(s_time, Duration::from_secs(1000)), None); - } -} diff --git a/beacon_chain/utils/slot-clock/Cargo.toml b/beacon_chain/utils/slot_clock/Cargo.toml similarity index 84% rename from beacon_chain/utils/slot-clock/Cargo.toml rename to beacon_chain/utils/slot_clock/Cargo.toml index ccb2e4ed4..166f397fd 100644 --- a/beacon_chain/utils/slot-clock/Cargo.toml +++ b/beacon_chain/utils/slot_clock/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "slot-clock" +name = "slot_clock" version = "0.1.0" authors = ["Paul Hauner "] edition = "2018" diff --git a/beacon_chain/utils/slot_clock/src/lib.rs b/beacon_chain/utils/slot_clock/src/lib.rs new file mode 100644 index 000000000..7bdb775af --- /dev/null +++ b/beacon_chain/utils/slot_clock/src/lib.rs @@ -0,0 +1,11 @@ +mod system_time_slot_clock; +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}; + +pub trait SlotClock { + type Error; + + fn present_slot(&self) -> Result, Self::Error>; +} diff --git a/beacon_chain/utils/slot_clock/src/system_time_slot_clock.rs b/beacon_chain/utils/slot_clock/src/system_time_slot_clock.rs new file mode 100644 index 000000000..be7265ae8 --- /dev/null +++ b/beacon_chain/utils/slot_clock/src/system_time_slot_clock.rs @@ -0,0 +1,135 @@ +use super::SlotClock; +use std::time::{Duration, SystemTime}; + +pub use std::time::SystemTimeError; + +#[derive(Debug)] +pub enum Error { + SlotDurationIsZero, + SystemTimeError(SystemTimeError), +} + +/// Determines the present slot based upon the present system time. +pub struct SystemTimeSlotClock { + genesis_seconds: u64, + slot_duration_seconds: u64, +} + +impl SystemTimeSlotClock { + /// Create a new `SystemTimeSlotClock`. + /// + /// Returns an Error if `slot_duration_seconds == 0`. + pub fn new( + genesis_seconds: u64, + slot_duration_seconds: u64, + ) -> Result { + if slot_duration_seconds == 0 { + Err(Error::SlotDurationIsZero) + } else { + Ok(SystemTimeSlotClock { + genesis_seconds, + slot_duration_seconds, + }) + } + } +} + +impl SlotClock for SystemTimeSlotClock { + type Error = Error; + + fn present_slot(&self) -> Result, Error> { + let syslot_time = SystemTime::now(); + let duration_since_epoch = syslot_time.duration_since(SystemTime::UNIX_EPOCH)?; + let duration_since_genesis = + duration_since_epoch.checked_sub(Duration::from_secs(self.genesis_seconds)); + match duration_since_genesis { + None => Ok(None), + Some(d) => Ok(slot_from_duration(self.slot_duration_seconds, d)), + } + } +} + +impl From for Error { + fn from(e: SystemTimeError) -> Error { + Error::SystemTimeError(e) + } +} + +fn slot_from_duration(slot_duration_seconds: u64, duration: Duration) -> Option { + duration.as_secs().checked_div(slot_duration_seconds) +} + +#[cfg(test)] +mod tests { + use super::*; + + /* + * Note: these tests are using actual system times and could fail if they are executed on a + * very slow machine. + */ + #[test] + fn test_slot_now() { + let slot_time = 100; + + let now = SystemTime::now(); + let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap(); + + let genesis = since_epoch.as_secs() - slot_time * 89; + + let clock = SystemTimeSlotClock { + genesis_seconds: genesis, + slot_duration_seconds: slot_time, + }; + assert_eq!(clock.present_slot().unwrap(), Some(89)); + + let clock = SystemTimeSlotClock { + genesis_seconds: since_epoch.as_secs(), + slot_duration_seconds: slot_time, + }; + assert_eq!(clock.present_slot().unwrap(), Some(0)); + + let clock = SystemTimeSlotClock { + genesis_seconds: since_epoch.as_secs() - slot_time * 42 - 5, + slot_duration_seconds: slot_time, + }; + assert_eq!(clock.present_slot().unwrap(), Some(42)); + } + + #[test] + fn test_slot_from_duration() { + let slot_time = 100; + + assert_eq!( + slot_from_duration(slot_time, Duration::from_secs(0)), + Some(0) + ); + assert_eq!( + slot_from_duration(slot_time, Duration::from_secs(10)), + Some(0) + ); + assert_eq!( + slot_from_duration(slot_time, Duration::from_secs(100)), + Some(1) + ); + assert_eq!( + slot_from_duration(slot_time, Duration::from_secs(101)), + Some(1) + ); + assert_eq!( + slot_from_duration(slot_time, Duration::from_secs(1000)), + Some(10) + ); + } + + #[test] + fn test_slot_from_duration_slot_time_zero() { + let slot_time = 0; + + assert_eq!(slot_from_duration(slot_time, Duration::from_secs(0)), None); + assert_eq!(slot_from_duration(slot_time, Duration::from_secs(10)), None); + assert_eq!( + slot_from_duration(slot_time, Duration::from_secs(1000)), + None + ); + } +} diff --git a/beacon_chain/utils/slot_clock/src/testing_slot_clock.rs b/beacon_chain/utils/slot_clock/src/testing_slot_clock.rs new file mode 100644 index 000000000..de1d7ddb3 --- /dev/null +++ b/beacon_chain/utils/slot_clock/src/testing_slot_clock.rs @@ -0,0 +1,43 @@ +use super::SlotClock; + +#[derive(Debug, PartialEq)] +pub enum Error {} + +/// Determines the present slot based upon the present system time. +pub struct TestingSlotClock { + slot: u64, +} + +impl TestingSlotClock { + /// Create a new `TestingSlotClock`. + /// + /// Returns an Error if `slot_duration_seconds == 0`. + pub fn new(slot: u64) -> TestingSlotClock { + TestingSlotClock { slot } + } + + pub fn set_slot(&mut self, slot: u64) { + self.slot = slot; + } +} + +impl SlotClock for TestingSlotClock { + type Error = Error; + + fn present_slot(&self) -> Result, Error> { + Ok(Some(self.slot)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_slot_now() { + let mut clock = TestingSlotClock::new(10); + assert_eq!(clock.present_slot(), Ok(Some(10))); + clock.set_slot(123); + assert_eq!(clock.present_slot(), Ok(Some(123))); + } +}