From 5647f3be0c6c8dd4380723ba159f09a832456c2e Mon Sep 17 00:00:00 2001 From: dylan Date: Fri, 21 Nov 2025 17:00:47 -0700 Subject: [PATCH 1/5] feat: adds support for millisecond slot timepoints --- src/utils/calc.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/utils/calc.rs b/src/utils/calc.rs index 0cb824f..dcd4b58 100644 --- a/src/utils/calc.rs +++ b/src/utils/calc.rs @@ -234,6 +234,17 @@ impl SlotCalculator { self.point_within_slot(chrono::Utc::now().timestamp() as u64) } + /// The current number of milliseconds into the slot. + pub fn current_point_within_slot_ms(&self) -> Option { + let now = chrono::Utc::now(); + let timestamp = now.timestamp() as u64; + let millis = now.timestamp_subsec_millis() as u64; + + self.point_within_slot(timestamp).map(|point| { + std::time::Duration::from_secs(point).as_millis() as u64 + millis + }) + } + /// Calculates the slot that starts at the given timestamp. /// Returns `None` if the timestamp is not a slot boundary. /// Returns `None` if the timestamp is before the chain's start timestamp. From 11134b8b493d55612ad940299d472b10c68a13a1 Mon Sep 17 00:00:00 2001 From: dylan Date: Fri, 21 Nov 2025 17:13:19 -0700 Subject: [PATCH 2/5] fmt --- src/utils/calc.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils/calc.rs b/src/utils/calc.rs index dcd4b58..9986797 100644 --- a/src/utils/calc.rs +++ b/src/utils/calc.rs @@ -240,9 +240,8 @@ impl SlotCalculator { let timestamp = now.timestamp() as u64; let millis = now.timestamp_subsec_millis() as u64; - self.point_within_slot(timestamp).map(|point| { - std::time::Duration::from_secs(point).as_millis() as u64 + millis - }) + self.point_within_slot(timestamp) + .map(|point| std::time::Duration::from_secs(point).as_millis() as u64 + millis) } /// Calculates the slot that starts at the given timestamp. From b3daed69103dcbcdf182776cb8ed60fd61f77606 Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 2 Dec 2025 16:29:53 -0700 Subject: [PATCH 3/5] refactor: only fetch from the now object once - only fetch from the chrono object once - operate on the returned timestamp in all subsequent math for performance and time drift mitigation --- src/utils/calc.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/utils/calc.rs b/src/utils/calc.rs index 9986797..c93b0fa 100644 --- a/src/utils/calc.rs +++ b/src/utils/calc.rs @@ -235,13 +235,18 @@ impl SlotCalculator { } /// The current number of milliseconds into the slot. + /// + /// Truncates the millisecond timestamp to seconds, then uses that to + /// calculate the point within the slot, adding back the milliseconds + /// remainder to the final result to provide millisecond precision. pub fn current_point_within_slot_ms(&self) -> Option { - let now = chrono::Utc::now(); - let timestamp = now.timestamp() as u64; - let millis = now.timestamp_subsec_millis() as u64; + // NB: Only fetch from now() object once and reuse + let timestamp_ms = chrono::Utc::now().timestamp_millis() as u64; + let timestamp_s = timestamp_ms / 1000; + let remainder = timestamp_ms - timestamp_s; - self.point_within_slot(timestamp) - .map(|point| std::time::Duration::from_secs(point).as_millis() as u64 + millis) + self.point_within_slot(timestamp_s) + .map(|point| std::time::Duration::from_secs(point).as_millis() as u64 + remainder) } /// Calculates the slot that starts at the given timestamp. From 2895e2cf0f2639073c81b1a2d72589a9f31a51db Mon Sep 17 00:00:00 2001 From: dylan Date: Thu, 4 Dec 2025 10:38:33 -0700 Subject: [PATCH 4/5] fix: time is a hard problem --- src/utils/calc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/calc.rs b/src/utils/calc.rs index c93b0fa..97c1ba1 100644 --- a/src/utils/calc.rs +++ b/src/utils/calc.rs @@ -243,10 +243,10 @@ impl SlotCalculator { // NB: Only fetch from now() object once and reuse let timestamp_ms = chrono::Utc::now().timestamp_millis() as u64; let timestamp_s = timestamp_ms / 1000; - let remainder = timestamp_ms - timestamp_s; + let fractional = timestamp_ms % 1000; self.point_within_slot(timestamp_s) - .map(|point| std::time::Duration::from_secs(point).as_millis() as u64 + remainder) + .map(|point| point * 1000 + fractional) } /// Calculates the slot that starts at the given timestamp. From fd4699edfd0a8b307221632f860e10a44d8fabc6 Mon Sep 17 00:00:00 2001 From: dylan Date: Mon, 8 Dec 2025 12:28:50 -0700 Subject: [PATCH 5/5] dep: bump patch to publish on merge --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7bdbf3d..a2ef6ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "init4-bin-base" description = "Internal utilities for binaries produced by the init4 team" keywords = ["init4", "bin", "base"] -version = "0.18.0-rc.0" +version = "0.18.1-rc.0" edition = "2021" rust-version = "1.85" authors = ["init4", "James Prestwich", "evalir"]