Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name = "init4-bin-base"
description = "Internal utilities for binaries produced by the init4 team"
keywords = ["init4", "bin", "base"]

version = "0.7.0"
version = "0.7.1"
edition = "2021"
rust-version = "1.81"
authors = ["init4", "James Prestwich"]
Expand Down
39 changes: 39 additions & 0 deletions src/utils/calc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,37 @@ impl SlotCalculator {
pub fn current_point_within_slot(&self) -> Option<u64> {
self.point_within_slot(chrono::Utc::now().timestamp() as u64)
}

/// 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.
pub const fn slot_starting_at(&self, timestamp: u64) -> Option<usize> {
let Some(elapsed) = timestamp.checked_sub(self.start_timestamp) else {
return None;
};

if elapsed % self.slot_duration != 0 {
return None;
}

self.slot_containing(timestamp)
}

/// Calculates the slot that ends 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.
pub fn slot_ending_at(&self, timestamp: u64) -> Option<usize> {
let Some(elapsed) = timestamp.checked_sub(self.start_timestamp) else {
return None;
};

if elapsed % self.slot_duration != 0 {
return None;
}

self.slot_containing(timestamp)
.and_then(|slot| slot.checked_sub(1))
}
}

#[cfg(test)]
Expand All @@ -261,14 +292,22 @@ mod tests {
#[test]
fn test_basic_slot_calculations() {
let calculator = SlotCalculator::new(12, 0, 12);
assert_eq!(calculator.slot_ending_at(0), None);
assert_eq!(calculator.slot_containing(0), None);
assert_eq!(calculator.slot_containing(1), None);
assert_eq!(calculator.slot_containing(11), None);

assert_eq!(calculator.slot_ending_at(11), None);
assert_eq!(calculator.slot_ending_at(12), Some(0));
assert_eq!(calculator.slot_starting_at(12), Some(1));
assert_eq!(calculator.slot_containing(12), Some(1));
assert_eq!(calculator.slot_containing(13), Some(1));
assert_eq!(calculator.slot_starting_at(13), None);
assert_eq!(calculator.slot_containing(23), Some(1));
assert_eq!(calculator.slot_ending_at(23), None);

assert_eq!(calculator.slot_ending_at(24), Some(1));
assert_eq!(calculator.slot_starting_at(24), Some(2));
assert_eq!(calculator.slot_containing(24), Some(2));
assert_eq!(calculator.slot_containing(25), Some(2));
assert_eq!(calculator.slot_containing(35), Some(2));
Expand Down
Loading