use crate::Network;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SlotConfig {
pub zero_time: u64,
pub zero_slot: u64,
pub slot_length: u64,
pub start_epoch: u64,
pub epoch_length: u64,
}
impl SlotConfig {
pub fn new(
zero_time: u64,
zero_slot: u64,
slot_length: u64,
start_epoch: u64,
epoch_length: u64,
) -> Self {
Self {
zero_time,
zero_slot,
slot_length,
start_epoch,
epoch_length,
}
}
pub fn mainnet() -> Self {
Self {
zero_time: 1596059091000,
zero_slot: 4492800,
slot_length: 1000,
start_epoch: 208,
epoch_length: 432000,
}
}
pub fn preview() -> Self {
Self {
zero_time: 1666656000000,
zero_slot: 0,
slot_length: 1000,
start_epoch: 0,
epoch_length: 86400,
}
}
pub fn preprod() -> Self {
Self {
zero_time: 1654041600000 + 1728000000,
zero_slot: 86400,
slot_length: 1000,
start_epoch: 4,
epoch_length: 432000,
}
}
}
impl Default for SlotConfig {
fn default() -> Self {
Self::mainnet()
}
}
pub fn get_slot_config(network: &Network) -> Option<SlotConfig> {
match network {
Network::Mainnet => Some(SlotConfig::mainnet()),
Network::Preview => Some(SlotConfig::preview()),
Network::Preprod => Some(SlotConfig::preprod()),
Network::Custom(_) => None,
}
}
pub fn slot_to_begin_unix_time(slot: u64, slot_config: &SlotConfig) -> u64 {
let ms_after_begin = (slot - slot_config.zero_slot) * slot_config.slot_length;
slot_config.zero_time + ms_after_begin
}
pub fn unix_time_to_enclosing_slot(unix_time: u64, slot_config: &SlotConfig) -> u64 {
let time_passed = unix_time - slot_config.zero_time;
let slots_passed = time_passed / slot_config.slot_length;
slots_passed + slot_config.zero_slot
}
pub fn resolve_slot_no(network: &Network, milliseconds: Option<u64>) -> Option<String> {
let slot_config = get_slot_config(network)?;
let time = milliseconds.unwrap_or_else(|| {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64
});
Some(unix_time_to_enclosing_slot(time, &slot_config).to_string())
}
pub fn resolve_epoch_no(network: &Network, milliseconds: Option<u64>) -> Option<u64> {
let config = get_slot_config(network)?;
let time = milliseconds.unwrap_or_else(|| {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64
});
let epoch = (time - config.zero_time) / 1000 / config.epoch_length + config.start_epoch;
Some(epoch)
}