From 68e4c47cd381186e09da42bd1d00a296d3462701 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Wed, 24 Oct 2018 13:12:55 +0200 Subject: [PATCH] Add slot-clock --- Cargo.toml | 1 + beacon_chain/utils/slot-clock/Cargo.toml | 6 ++ beacon_chain/utils/slot-clock/src/lib.rs | 71 ++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 beacon_chain/utils/slot-clock/Cargo.toml create mode 100644 beacon_chain/utils/slot-clock/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 6c9b8886d..b0872b8e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ members = [ "beacon_chain/utils/boolean-bitfield", "beacon_chain/utils/hashing", "beacon_chain/utils/honey-badger-split", + "beacon_chain/utils/slot-clock", "beacon_chain/utils/ssz", "beacon_chain/utils/ssz_helpers", "beacon_chain/utils/vec_shuffle", diff --git a/beacon_chain/utils/slot-clock/Cargo.toml b/beacon_chain/utils/slot-clock/Cargo.toml new file mode 100644 index 000000000..c10fb6bd9 --- /dev/null +++ b/beacon_chain/utils/slot-clock/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "slot-clock" +version = "0.1.0" +authors = ["Paul Hauner "] + +[dependencies] 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..1d801fe10 --- /dev/null +++ b/beacon_chain/utils/slot-clock/src/lib.rs @@ -0,0 +1,71 @@ +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); + } +}