mithril_common/crypto_helper/cardano/kes/
kes_evolutions.rs

1use std::fmt::{Display, Formatter};
2use std::num::TryFromIntError;
3use std::ops::{Deref, DerefMut};
4
5use serde::{Deserialize, Serialize};
6
7use crate::entities::arithmetic_operation_wrapper::{
8    impl_add_to_wrapper, impl_partial_eq_to_wrapper, impl_sub_to_wrapper,
9};
10
11/// KesEvolutions represents the KES evolutions used to evolve the KES secret key
12///
13/// Even if KES evolutions are expressed as KES periods, we create a distinct type to avoid confusion
14/// with 'KesPeriod' that represents absolute KES periods in the blockchain.
15#[derive(
16    Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Hash,
17)]
18pub struct KesEvolutions(pub u64);
19
20impl Display for KesEvolutions {
21    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
22        write!(f, "{}", self.0)
23    }
24}
25
26impl Deref for KesEvolutions {
27    type Target = u64;
28
29    fn deref(&self) -> &Self::Target {
30        &self.0
31    }
32}
33
34impl DerefMut for KesEvolutions {
35    fn deref_mut(&mut self) -> &mut Self::Target {
36        &mut self.0
37    }
38}
39
40// Useful for conversion to sqlite number (that uses i64)
41impl TryFrom<KesEvolutions> for i64 {
42    type Error = TryFromIntError;
43
44    fn try_from(value: KesEvolutions) -> Result<Self, Self::Error> {
45        i64::try_from(value.0)
46    }
47}
48
49impl TryFrom<i64> for KesEvolutions {
50    type Error = TryFromIntError;
51
52    fn try_from(value: i64) -> Result<Self, Self::Error> {
53        Ok(KesEvolutions(u64::try_from(value)?))
54    }
55}
56
57impl From<KesEvolutions> for u64 {
58    fn from(value: KesEvolutions) -> Self {
59        value.0
60    }
61}
62
63impl_add_to_wrapper!(KesEvolutions, u64);
64impl_sub_to_wrapper!(KesEvolutions, u64);
65impl_partial_eq_to_wrapper!(KesEvolutions, u64);
66
67#[cfg(test)]
68mod tests {
69    use crate::entities::arithmetic_operation_wrapper::tests::test_op_assign;
70
71    use super::*;
72
73    #[test]
74    fn test_display() {
75        assert_eq!(format!("{}", KesEvolutions(72)), "72");
76        assert_eq!(format!("{}", &KesEvolutions(13224)), "13224");
77    }
78
79    #[test]
80    fn test_serialize() {
81        assert_eq!(serde_json::to_string(&KesEvolutions(72)).unwrap(), "72");
82    }
83
84    #[test]
85    fn test_deserialize() {
86        let kes_period: KesEvolutions = serde_json::from_str("13224").unwrap();
87        assert_eq!(kes_period, KesEvolutions(13224));
88    }
89
90    #[test]
91    #[allow(clippy::op_ref)]
92    fn test_add() {
93        assert_eq!(KesEvolutions(4), KesEvolutions(1) + KesEvolutions(3));
94        assert_eq!(KesEvolutions(4), KesEvolutions(1) + 3_u64);
95        assert_eq!(KesEvolutions(4), KesEvolutions(1) + &3_u64);
96
97        assert_eq!(KesEvolutions(4), 3_u64 + KesEvolutions(1));
98        assert_eq!(KesEvolutions(4), 3_u64 + &KesEvolutions(1));
99        assert_eq!(KesEvolutions(4), &3_u64 + KesEvolutions(1));
100        assert_eq!(KesEvolutions(4), &3_u64 + &KesEvolutions(1));
101
102        test_op_assign!(KesEvolutions(1), +=, KesEvolutions(3) => KesEvolutions(4));
103        test_op_assign!(KesEvolutions(1), +=, 3_u64 => KesEvolutions(4));
104        test_op_assign!(KesEvolutions(1), +=, &3_u64 => KesEvolutions(4));
105
106        test_op_assign!(1_u64, +=, KesEvolutions(3) => 4_u64);
107        test_op_assign!(1_u64, +=, &KesEvolutions(3) => 4_u64);
108    }
109
110    #[test]
111    #[allow(clippy::op_ref)]
112    fn test_sub() {
113        assert_eq!(KesEvolutions(8), KesEvolutions(14) - KesEvolutions(6));
114        assert_eq!(KesEvolutions(8), KesEvolutions(14) - 6_u64);
115        assert_eq!(KesEvolutions(8), KesEvolutions(14) - &6_u64);
116
117        assert_eq!(KesEvolutions(8), 6_u64 - KesEvolutions(14));
118        assert_eq!(KesEvolutions(8), 6_u64 - &KesEvolutions(14));
119        assert_eq!(KesEvolutions(8), &6_u64 - KesEvolutions(14));
120        assert_eq!(KesEvolutions(8), &6_u64 - &KesEvolutions(14));
121
122        test_op_assign!(KesEvolutions(14), -=, KesEvolutions(6) => KesEvolutions(8));
123        test_op_assign!(KesEvolutions(14), -=, 6_u64 => KesEvolutions(8));
124        test_op_assign!(KesEvolutions(14), -=, &6_u64 => KesEvolutions(8));
125
126        test_op_assign!(14_u64, -=, KesEvolutions(6) => 8_u64);
127        test_op_assign!(14_u64, -=, &KesEvolutions(6) => 8_u64);
128    }
129
130    #[test]
131    fn saturating_sub() {
132        assert_eq!(KesEvolutions(0), KesEvolutions(1) - KesEvolutions(5));
133        assert_eq!(KesEvolutions(0), KesEvolutions(1) - 5_u64);
134    }
135
136    #[test]
137    fn test_eq() {
138        assert_eq!(KesEvolutions(1), KesEvolutions(1));
139        assert_eq!(KesEvolutions(2), &KesEvolutions(2));
140        assert_eq!(&KesEvolutions(3), KesEvolutions(3));
141        assert_eq!(&KesEvolutions(4), &KesEvolutions(4));
142
143        assert_eq!(KesEvolutions(5), 5);
144        assert_eq!(KesEvolutions(6), &6);
145        assert_eq!(&KesEvolutions(7), 7);
146        assert_eq!(&KesEvolutions(8), &8);
147
148        assert_eq!(9, KesEvolutions(9));
149        assert_eq!(10, &KesEvolutions(10));
150        assert_eq!(&11, KesEvolutions(11));
151        assert_eq!(&12, &KesEvolutions(12));
152    }
153}