mithril_common/entities/
protocol_parameters.rs

1use fixed::types::U8F24;
2use serde::{Deserialize, Serialize};
3use sha2::{Digest, Sha256};
4
5/// Protocol cryptographic parameters
6#[derive(Clone, Debug, Serialize, Deserialize)]
7pub struct ProtocolParameters {
8    /// Quorum parameter
9    pub k: u64,
10
11    /// Security parameter (number of lotteries)
12    pub m: u64,
13
14    /// f in phi(w) = 1 - (1 - f)^w, where w is the stake of a participant
15    pub phi_f: f64,
16}
17
18impl ProtocolParameters {
19    /// ProtocolParameters factory
20    pub fn new(k: u64, m: u64, phi_f: f64) -> ProtocolParameters {
21        ProtocolParameters { k, m, phi_f }
22    }
23
24    /// phi_f_fixed is a fixed decimal representation of phi_f
25    /// used for PartialEq and Hash implementation
26    pub fn phi_f_fixed(&self) -> U8F24 {
27        U8F24::from_num(self.phi_f)
28    }
29
30    /// Computes the hash of ProtocolParameters
31    pub fn compute_hash(&self) -> String {
32        let mut hasher = Sha256::new();
33        hasher.update(self.k.to_be_bytes());
34        hasher.update(self.m.to_be_bytes());
35        hasher.update(self.phi_f_fixed().to_be_bytes());
36        hex::encode(hasher.finalize())
37    }
38}
39
40impl PartialEq<ProtocolParameters> for ProtocolParameters {
41    fn eq(&self, other: &ProtocolParameters) -> bool {
42        self.k == other.k && self.m == other.m && self.phi_f_fixed() == other.phi_f_fixed()
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn test_protocol_parameters_partialeq() {
52        assert_eq!(
53            ProtocolParameters::new(1000, 100, 0.123001),
54            ProtocolParameters::new(1000, 100, 0.123001)
55        );
56        assert_ne!(
57            ProtocolParameters::new(1000, 100, 0.1230011),
58            ProtocolParameters::new(1000, 100, 0.1230012)
59        );
60        assert_ne!(
61            ProtocolParameters::new(1000, 100, 0.12301),
62            ProtocolParameters::new(1000, 100, 0.12300)
63        );
64        assert_ne!(
65            ProtocolParameters::new(1001, 100, 0.12300),
66            ProtocolParameters::new(1000, 100, 0.12300)
67        );
68        assert_ne!(
69            ProtocolParameters::new(1000, 101, 0.12300),
70            ProtocolParameters::new(1000, 100, 0.12300)
71        );
72    }
73
74    #[test]
75    fn test_protocol_parameters_compute_hash() {
76        let hash_expected = "ace019657cd995b0dfbb1ce8721a1092715972c4ae0171cc636ab4a44e6e4279";
77
78        assert_eq!(
79            hash_expected,
80            ProtocolParameters::new(1000, 100, 0.123).compute_hash()
81        );
82        assert_ne!(
83            hash_expected,
84            ProtocolParameters::new(2000, 100, 0.123).compute_hash()
85        );
86        assert_ne!(
87            hash_expected,
88            ProtocolParameters::new(1000, 200, 0.123).compute_hash()
89        );
90        assert_ne!(
91            hash_expected,
92            ProtocolParameters::new(1000, 100, 0.124).compute_hash()
93        );
94    }
95}