mithril_stm/protocol/
parameters.rs1use serde::{Deserialize, Serialize};
2
3use crate::codec;
4use crate::{PhiFValue, StmResult};
5
6use super::RegisterError;
7
8#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
16pub struct Parameters {
17 pub m: u64,
19 pub k: u64,
21 pub phi_f: PhiFValue,
23}
24
25impl Parameters {
26 pub fn to_bytes(&self) -> StmResult<Vec<u8>> {
31 codec::to_cbor_bytes(self)
32 }
33
34 pub fn from_bytes(bytes: &[u8]) -> StmResult<Self> {
42 codec::from_versioned_bytes(bytes, Self::from_bytes_legacy)
43 }
44
45 fn from_bytes_legacy(bytes: &[u8]) -> StmResult<Self> {
46 let mut u64_bytes = [0u8; 8];
47 u64_bytes.copy_from_slice(bytes.get(..8).ok_or(RegisterError::SerializationError)?);
48 let m = u64::from_be_bytes(u64_bytes);
49 u64_bytes.copy_from_slice(bytes.get(8..16).ok_or(RegisterError::SerializationError)?);
50 let k = u64::from_be_bytes(u64_bytes);
51 u64_bytes.copy_from_slice(bytes.get(16..24).ok_or(RegisterError::SerializationError)?);
52 let phi_f = f64::from_be_bytes(u64_bytes);
53
54 Ok(Self { m, k, phi_f })
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 mod golden {
63 use super::*;
64
65 const GOLDEN_JSON: &str = r#"
66 {
67 "m": 20973,
68 "k": 2422,
69 "phi_f": 0.2
70 }
71 "#;
72
73 fn golden_value() -> Parameters {
74 Parameters {
75 m: 20973,
76 k: 2422,
77 phi_f: 0.2,
78 }
79 }
80
81 #[test]
82 fn golden_conversions() {
83 let value = serde_json::from_str(GOLDEN_JSON)
84 .expect("This JSON deserialization should not fail");
85 assert_eq!(golden_value(), value);
86
87 let serialized =
88 serde_json::to_string(&value).expect("This JSON serialization should not fail");
89 let golden_serialized = serde_json::to_string(&golden_value())
90 .expect("This JSON serialization should not fail");
91 assert_eq!(golden_serialized, serialized);
92 }
93 }
94
95 mod cbor {
96 use super::*;
97
98 const LEGACY_BYTES: &[u8; 24] = &[
99 0, 0, 0, 0, 0, 0, 81, 237, 0, 0, 0, 0, 0, 0, 9, 118, 63, 201, 153, 153, 153, 153, 153,
100 154,
101 ];
102
103 fn test_value() -> Parameters {
104 Parameters {
105 m: 20973,
106 k: 2422,
107 phi_f: 0.2,
108 }
109 }
110
111 #[test]
112 fn cbor_roundtrip() {
113 let value = test_value();
114 let bytes = value.to_bytes().expect("CBOR serialization should not fail");
115 let decoded =
116 Parameters::from_bytes(&bytes).expect("CBOR deserialization should not fail");
117 assert_eq!(value, decoded);
118 }
119
120 #[test]
121 fn legacy_bytes_can_still_be_decoded() {
122 let decoded = Parameters::from_bytes(LEGACY_BYTES)
123 .expect("Legacy deserialization should not fail");
124 assert_eq!(test_value(), decoded);
125 }
126
127 const GOLDEN_CBOR_BYTES: &[u8; 27] = &[
128 1, 163, 97, 109, 25, 81, 237, 97, 107, 25, 9, 118, 101, 112, 104, 105, 95, 102, 251,
129 63, 201, 153, 153, 153, 153, 153, 154,
130 ];
131
132 #[test]
133 fn cbor_golden_bytes_can_be_decoded() {
134 let decoded = Parameters::from_bytes(GOLDEN_CBOR_BYTES)
135 .expect("CBOR golden bytes deserialization should not fail");
136 assert_eq!(test_value(), decoded);
137 }
138
139 #[test]
140 fn cbor_encoding_is_stable() {
141 let bytes = test_value().to_bytes().expect("CBOR serialization should not fail");
142 assert_eq!(GOLDEN_CBOR_BYTES.as_slice(), bytes.as_slice());
143 }
144 }
145}