use crate::kes::KesAlgorithm;
pub type KESPeriod = u32;
pub const KES_MAX_PERIOD_SUM6: KESPeriod = 63;
pub const KES_SLOTS_PER_PERIOD_MAINNET: u64 = 129_600;
pub const KES_SLOTS_PER_PERIOD_TESTNET: u64 = 129_600;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct KESPeriodInfo {
pub period: KESPeriod,
pub is_valid: bool,
pub total_periods: u32,
pub remaining_periods: u32,
}
pub fn kes_period_info<K: KesAlgorithm>(period: KESPeriod) -> KESPeriodInfo {
let total_periods = K::total_periods() as u32;
let is_valid = (period as u64) < K::total_periods();
let remaining_periods = if is_valid { total_periods - period } else { 0 };
KESPeriodInfo {
period,
is_valid,
total_periods,
remaining_periods,
}
}
pub fn is_valid_period<K: KesAlgorithm>(period: KESPeriod) -> bool {
(period as u64) < K::total_periods()
}
pub fn slot_from_period(period: KESPeriod, slots_per_period: u64, start_slot: u64) -> u64 {
start_slot + (period as u64) * slots_per_period
}
pub fn period_from_slot(slot: u64, slots_per_period: u64, start_slot: u64) -> KESPeriod {
if slot < start_slot {
0
} else {
((slot - start_slot) / slots_per_period) as KESPeriod
}
}
pub fn kes_expiry_slot<K: KesAlgorithm>(slots_per_period: u64, start_slot: u64) -> u64 {
start_slot + K::total_periods() * slots_per_period
}
pub fn is_kes_expired<K: KesAlgorithm>(slot: u64, slots_per_period: u64, start_slot: u64) -> bool {
slot >= kes_expiry_slot::<K>(slots_per_period, start_slot)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::kes::{Sum0Kes, Sum1Kes, Sum6Kes};
#[test]
fn test_kes_period_info_sum6() {
let info = kes_period_info::<Sum6Kes>(0);
assert!(info.is_valid);
assert_eq!(info.total_periods, 64);
assert_eq!(info.remaining_periods, 64);
let info = kes_period_info::<Sum6Kes>(32);
assert!(info.is_valid);
assert_eq!(info.remaining_periods, 32);
let info = kes_period_info::<Sum6Kes>(63);
assert!(info.is_valid);
assert_eq!(info.remaining_periods, 1);
let info = kes_period_info::<Sum6Kes>(64);
assert!(!info.is_valid);
assert_eq!(info.remaining_periods, 0);
}
#[test]
fn test_kes_period_info_sum0() {
let info = kes_period_info::<Sum0Kes>(0);
assert!(info.is_valid);
assert_eq!(info.total_periods, 1);
assert_eq!(info.remaining_periods, 1);
let info = kes_period_info::<Sum0Kes>(1);
assert!(!info.is_valid);
}
#[test]
fn test_kes_period_info_sum1() {
let info = kes_period_info::<Sum1Kes>(0);
assert!(info.is_valid);
assert_eq!(info.total_periods, 2);
let info = kes_period_info::<Sum1Kes>(1);
assert!(info.is_valid);
let info = kes_period_info::<Sum1Kes>(2);
assert!(!info.is_valid);
}
#[test]
fn test_is_valid_period() {
assert!(is_valid_period::<Sum6Kes>(0));
assert!(is_valid_period::<Sum6Kes>(63));
assert!(!is_valid_period::<Sum6Kes>(64));
assert!(!is_valid_period::<Sum6Kes>(100));
}
#[test]
fn test_slot_from_period() {
assert_eq!(slot_from_period(0, 129_600, 0), 0);
assert_eq!(slot_from_period(1, 129_600, 0), 129_600);
assert_eq!(slot_from_period(2, 129_600, 0), 259_200);
assert_eq!(slot_from_period(0, 129_600, 1000), 1000);
assert_eq!(slot_from_period(1, 129_600, 1000), 130_600);
}
#[test]
fn test_period_from_slot() {
assert_eq!(period_from_slot(0, 129_600, 0), 0);
assert_eq!(period_from_slot(129_599, 129_600, 0), 0);
assert_eq!(period_from_slot(129_600, 129_600, 0), 1);
assert_eq!(period_from_slot(259_199, 129_600, 0), 1);
assert_eq!(period_from_slot(259_200, 129_600, 0), 2);
assert_eq!(period_from_slot(1000, 129_600, 1000), 0);
assert_eq!(period_from_slot(130_599, 129_600, 1000), 0);
assert_eq!(period_from_slot(130_600, 129_600, 1000), 1);
}
#[test]
fn test_kes_expiry_slot() {
let expiry = kes_expiry_slot::<Sum6Kes>(129_600, 0);
assert_eq!(expiry, 64 * 129_600);
let expiry = kes_expiry_slot::<Sum1Kes>(129_600, 0);
assert_eq!(expiry, 2 * 129_600);
let expiry = kes_expiry_slot::<Sum6Kes>(129_600, 1000);
assert_eq!(expiry, 1000 + 64 * 129_600);
}
#[test]
fn test_is_kes_expired() {
assert!(!is_kes_expired::<Sum6Kes>(0, 129_600, 0));
assert!(!is_kes_expired::<Sum6Kes>(64 * 129_600 - 1, 129_600, 0));
assert!(is_kes_expired::<Sum6Kes>(64 * 129_600, 129_600, 0));
assert!(is_kes_expired::<Sum6Kes>(100 * 129_600, 129_600, 0));
}
#[test]
fn test_kes_constants() {
assert_eq!(KES_MAX_PERIOD_SUM6, 63);
assert_eq!(KES_SLOTS_PER_PERIOD_MAINNET, 129_600);
}
}