Skip to content

Commit abf51a6

Browse files
authored
feat(utils): add slot_starting_at / slot_ending_at fns to the calculator (#55)
* feat(utils): add `slot_starting_at` / `slot_ending_at` fns to the calculator These functions can calculate the slot that begins or ends at a given timestamp, as LONG as it's a slot boundary. Else, the ywill return `None`. * chore: v bump to 0.8.0 * chore: docs, fixes * lmao
1 parent 88b3eeb commit abf51a6

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ name = "init4-bin-base"
44
description = "Internal utilities for binaries produced by the init4 team"
55
keywords = ["init4", "bin", "base"]
66

7-
version = "0.7.0"
7+
version = "0.7.1"
88
edition = "2021"
99
rust-version = "1.81"
1010
authors = ["init4", "James Prestwich"]

src/utils/calc.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,33 @@ impl SlotCalculator {
244244
pub fn current_point_within_slot(&self) -> Option<u64> {
245245
self.point_within_slot(chrono::Utc::now().timestamp() as u64)
246246
}
247+
248+
/// Calculates the slot that starts at the given timestamp.
249+
/// Returns `None` if the timestamp is not a slot boundary.
250+
/// Returns `None` if the timestamp is before the chain's start timestamp.
251+
pub fn slot_starting_at(&self, timestamp: u64) -> Option<usize> {
252+
let elapsed = timestamp.checked_sub(self.start_timestamp)?;
253+
254+
if elapsed % self.slot_duration != 0 {
255+
return None;
256+
}
257+
258+
self.slot_containing(timestamp)
259+
}
260+
261+
/// Calculates the slot that ends at the given timestamp.
262+
/// Returns `None` if the timestamp is not a slot boundary.
263+
/// Returns `None` if the timestamp is before the chain's start timestamp.
264+
pub fn slot_ending_at(&self, timestamp: u64) -> Option<usize> {
265+
let elapsed = timestamp.checked_sub(self.start_timestamp)?;
266+
267+
if elapsed % self.slot_duration != 0 {
268+
return None;
269+
}
270+
271+
self.slot_containing(timestamp)
272+
.and_then(|slot| slot.checked_sub(1))
273+
}
247274
}
248275

249276
#[cfg(test)]
@@ -261,14 +288,22 @@ mod tests {
261288
#[test]
262289
fn test_basic_slot_calculations() {
263290
let calculator = SlotCalculator::new(12, 0, 12);
291+
assert_eq!(calculator.slot_ending_at(0), None);
264292
assert_eq!(calculator.slot_containing(0), None);
265293
assert_eq!(calculator.slot_containing(1), None);
266294
assert_eq!(calculator.slot_containing(11), None);
267295

296+
assert_eq!(calculator.slot_ending_at(11), None);
297+
assert_eq!(calculator.slot_ending_at(12), Some(0));
298+
assert_eq!(calculator.slot_starting_at(12), Some(1));
268299
assert_eq!(calculator.slot_containing(12), Some(1));
269300
assert_eq!(calculator.slot_containing(13), Some(1));
301+
assert_eq!(calculator.slot_starting_at(13), None);
270302
assert_eq!(calculator.slot_containing(23), Some(1));
303+
assert_eq!(calculator.slot_ending_at(23), None);
271304

305+
assert_eq!(calculator.slot_ending_at(24), Some(1));
306+
assert_eq!(calculator.slot_starting_at(24), Some(2));
272307
assert_eq!(calculator.slot_containing(24), Some(2));
273308
assert_eq!(calculator.slot_containing(25), Some(2));
274309
assert_eq!(calculator.slot_containing(35), Some(2));

0 commit comments

Comments
 (0)