-
Notifications
You must be signed in to change notification settings - Fork 9
/
time.rs
128 lines (114 loc) · 4.35 KB
/
time.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::config::VitStartParameters;
use crate::config::VoteBlockchainTime;
use crate::config::VoteTime;
use chrono::NaiveDateTime;
use jormungandr_lib::time::SecondsSinceUnixEpoch;
use std::collections::HashSet;
pub fn convert_to_blockchain_date(
parameters: &VitStartParameters,
block0_date: SecondsSinceUnixEpoch,
) -> VoteBlockchainTime {
match parameters.vote_time {
VoteTime::Blockchain(blockchain_date) => blockchain_date,
VoteTime::Real {
vote_start_timestamp,
tally_start_timestamp,
tally_end_timestamp,
find_best_match: _,
} => {
let block0_date = NaiveDateTime::from_timestamp(block0_date.to_secs() as i64, 0);
let from_block0_till_vote_start = (vote_start_timestamp - block0_date).num_seconds();
let from_vote_start_till_tally_start =
(tally_start_timestamp - block0_date).num_seconds();
let from_tally_start_till_tally_end = (tally_end_timestamp - block0_date).num_seconds();
let mut block0_to_start = count_divisors(from_block0_till_vote_start, 90, 60);
let start_to_end = count_divisors(from_vote_start_till_tally_start, 90, 60);
block0_to_start.extend(&start_to_end);
let max = block0_to_start.iter().max();
if max.is_none() {
panic!("bad data");
}
let max: i64 = *max.unwrap();
VoteBlockchainTime {
vote_start: (from_block0_till_vote_start / max) as u32,
tally_start: (from_vote_start_till_tally_start / max) as u32,
tally_end: (from_tally_start_till_tally_end / max) as u32,
slots_per_epoch: max as u32,
}
}
}
}
fn count_divisors(n: i64, grace: i64, start: i64) -> HashSet<i64> {
let mut output = HashSet::new();
for i in start..=n {
if n % i <= grace {
output.insert(i);
}
}
output
}
pub fn convert_to_human_date(
parameters: &VitStartParameters,
block0_date: SecondsSinceUnixEpoch,
) -> (NaiveDateTime, NaiveDateTime, NaiveDateTime) {
let parameters = parameters.clone();
println!(
"Current date {:?}",
NaiveDateTime::from_timestamp(block0_date.to_secs() as i64, 0)
);
match parameters.vote_time {
VoteTime::Blockchain(blockchain) => {
let epoch_duration = parameters.slot_duration as u32 * blockchain.slots_per_epoch;
let vote_start_timestamp =
block0_date.to_secs() as u32 + epoch_duration * blockchain.vote_start;
let vote_start_timestamp =
NaiveDateTime::from_timestamp(vote_start_timestamp as i64, 0);
let tally_start_timestamp =
block0_date.to_secs() as u32 + epoch_duration * blockchain.tally_start;
let tally_start_timestamp =
NaiveDateTime::from_timestamp(tally_start_timestamp as i64, 0);
let tally_end_timestamp =
block0_date.to_secs() as u32 + epoch_duration * blockchain.tally_end;
let tally_end_timestamp = NaiveDateTime::from_timestamp(tally_end_timestamp as i64, 0);
(
vote_start_timestamp,
tally_start_timestamp,
tally_end_timestamp,
)
}
VoteTime::Real {
vote_start_timestamp,
tally_start_timestamp,
tally_end_timestamp,
find_best_match: _,
} => (
vote_start_timestamp,
tally_start_timestamp,
tally_end_timestamp,
),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn time_test() {
let block0_date = SecondsSinceUnixEpoch::now();
let mut parameters = VitStartParameters::default();
let vote_time = VoteTime::real_from_str(
"2021-10-06 11:00:00",
"2021-10-06 18:00:00",
"2021-10-07 09:00:00",
)
.unwrap();
parameters.slot_duration = 10;
parameters.vote_time = vote_time.clone();
println!("Before {:#?}", vote_time);
let blockchain_time = convert_to_blockchain_date(¶meters, block0_date);
parameters.vote_time = VoteTime::Blockchain(blockchain_time);
println!(
"After {:#?}",
convert_to_human_date(¶meters, block0_date)
);
}
}