whisky_common/utils/
time.rs1use crate::Network;
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct SlotConfig {
9 pub zero_time: u64,
11 pub zero_slot: u64,
13 pub slot_length: u64,
15 pub start_epoch: u64,
17 pub epoch_length: u64,
19}
20
21impl SlotConfig {
22 pub fn new(
24 zero_time: u64,
25 zero_slot: u64,
26 slot_length: u64,
27 start_epoch: u64,
28 epoch_length: u64,
29 ) -> Self {
30 Self {
31 zero_time,
32 zero_slot,
33 slot_length,
34 start_epoch,
35 epoch_length,
36 }
37 }
38
39 pub fn mainnet() -> Self {
41 Self {
42 zero_time: 1596059091000,
43 zero_slot: 4492800,
44 slot_length: 1000,
45 start_epoch: 208,
46 epoch_length: 432000,
47 }
48 }
49
50 pub fn preview() -> Self {
52 Self {
53 zero_time: 1666656000000,
54 zero_slot: 0,
55 slot_length: 1000,
56 start_epoch: 0,
57 epoch_length: 86400,
58 }
59 }
60
61 pub fn preprod() -> Self {
63 Self {
64 zero_time: 1654041600000 + 1728000000,
65 zero_slot: 86400,
66 slot_length: 1000,
67 start_epoch: 4,
68 epoch_length: 432000,
69 }
70 }
71}
72
73impl Default for SlotConfig {
74 fn default() -> Self {
75 Self::mainnet()
76 }
77}
78
79pub fn get_slot_config(network: &Network) -> Option<SlotConfig> {
87 match network {
88 Network::Mainnet => Some(SlotConfig::mainnet()),
89 Network::Preview => Some(SlotConfig::preview()),
90 Network::Preprod => Some(SlotConfig::preprod()),
91 Network::Custom(_) => None,
92 }
93}
94
95pub fn slot_to_begin_unix_time(slot: u64, slot_config: &SlotConfig) -> u64 {
104 let ms_after_begin = (slot - slot_config.zero_slot) * slot_config.slot_length;
105 slot_config.zero_time + ms_after_begin
106}
107
108pub fn unix_time_to_enclosing_slot(unix_time: u64, slot_config: &SlotConfig) -> u64 {
117 let time_passed = unix_time - slot_config.zero_time;
118 let slots_passed = time_passed / slot_config.slot_length;
119 slots_passed + slot_config.zero_slot
120}
121
122pub fn resolve_slot_no(network: &Network, milliseconds: Option<u64>) -> Option<String> {
131 let slot_config = get_slot_config(network)?;
132 let time = milliseconds.unwrap_or_else(|| {
133 std::time::SystemTime::now()
134 .duration_since(std::time::UNIX_EPOCH)
135 .expect("Time went backwards")
136 .as_millis() as u64
137 });
138 Some(unix_time_to_enclosing_slot(time, &slot_config).to_string())
139}
140
141pub fn resolve_epoch_no(network: &Network, milliseconds: Option<u64>) -> Option<u64> {
150 let config = get_slot_config(network)?;
151 let time = milliseconds.unwrap_or_else(|| {
152 std::time::SystemTime::now()
153 .duration_since(std::time::UNIX_EPOCH)
154 .expect("Time went backwards")
155 .as_millis() as u64
156 });
157
158 let epoch = (time - config.zero_time) / 1000 / config.epoch_length + config.start_epoch;
159 Some(epoch)
160}