1mod block;
4pub use block::{Block, Finalized, Notarized};
5mod consensus;
6pub use consensus::{Finalization, Kind, Notarization, Nullification, Seed};
7
8pub const NAMESPACE: &[u8] = b"_ALTO";
10pub const P2P_NAMESPACE: &[u8] = b"_ALTO_P2P";
11pub const SEED_NAMESPACE: &[u8] = b"_ALTO_SEED";
12pub const NOTARIZE_NAMESPACE: &[u8] = b"_ALTO_NOTARIZE";
13pub const NULLIFY_NAMESPACE: &[u8] = b"_ALTO_NULLIFY";
14pub const FINALIZE_NAMESPACE: &[u8] = b"_ALTO_FINALIZE";
15
16#[cfg(test)]
17mod tests {
18 use super::*;
19 use commonware_cryptography::{hash, Bls12381, Scheme};
20 use rand::{rngs::StdRng, SeedableRng};
21
22 #[test]
23 fn test_seed() {
24 let mut rng = StdRng::seed_from_u64(0);
26 let mut network = Bls12381::new(&mut rng);
27
28 let view = 0;
30 let seed_payload = Seed::payload(view);
31 let seed_signature = network.sign(Some(SEED_NAMESPACE), &seed_payload);
32 let seed = Seed::new(view, seed_signature);
33
34 let serialized = seed.serialize();
36 let deserialized = Seed::deserialize(Some(&network.public_key()), &serialized).unwrap();
37 assert_eq!(seed.view, deserialized.view);
38 }
39
40 #[test]
41 fn test_seed_manipulated() {
42 let mut rng = StdRng::seed_from_u64(0);
44 let mut network = Bls12381::new(&mut rng);
45
46 let view = 0;
48 let seed_payload = Seed::payload(view);
49 let seed_signature = network.sign(Some(SEED_NAMESPACE), &seed_payload);
50 let mut seed = Seed::new(view, seed_signature);
51
52 seed.view = 1;
54
55 let serialized = seed.serialize();
57
58 assert!(Seed::deserialize(Some(&network.public_key()), &serialized).is_none());
60
61 assert!(Seed::deserialize(None, &serialized).is_some());
63 }
64
65 #[test]
66 fn test_nullification() {
67 let mut rng = StdRng::seed_from_u64(0);
69 let mut network = Bls12381::new(&mut rng);
70
71 let view = 0;
73 let nullify_payload = Nullification::payload(view);
74 let nullify_signature = network.sign(Some(NULLIFY_NAMESPACE), &nullify_payload);
75 let nullification = Nullification::new(view, nullify_signature);
76
77 let serialized = nullification.serialize();
79 let deserialized =
80 Nullification::deserialize(Some(&network.public_key()), &serialized).unwrap();
81 assert_eq!(nullification.view, deserialized.view);
82 }
83
84 #[test]
85 fn test_nullification_manipulated() {
86 let mut rng = StdRng::seed_from_u64(0);
88 let mut network = Bls12381::new(&mut rng);
89
90 let view = 0;
92 let nullify_payload = Nullification::payload(view);
93 let nullify_signature = network.sign(Some(NULLIFY_NAMESPACE), &nullify_payload);
94 let mut nullification = Nullification::new(view, nullify_signature);
95
96 nullification.view = 1;
98
99 let serialized = nullification.serialize();
101
102 assert!(Nullification::deserialize(Some(&network.public_key()), &serialized).is_none());
104
105 assert!(Nullification::deserialize(None, &serialized).is_some());
107 }
108
109 #[test]
110 fn test_notarization_finalization() {
111 let mut rng = StdRng::seed_from_u64(0);
113 let mut network = Bls12381::new(&mut rng);
114
115 let parent_digest = hash(&[0; 32]);
117 let height = 0;
118 let timestamp = 1;
119 let block = Block::new(parent_digest, height, timestamp);
120 let block_digest = block.digest();
121
122 let serialized = block.serialize();
124 let deserialized = Block::deserialize(&serialized).unwrap();
125 assert_eq!(block_digest, deserialized.digest());
126 assert_eq!(block.parent, deserialized.parent);
127 assert_eq!(block.height, deserialized.height);
128 assert_eq!(block.timestamp, deserialized.timestamp);
129
130 let view = 0;
132 let parent_view = 0;
133 let block_payload = Notarization::payload(view, parent_view, &block_digest);
134 let block_signature = network.sign(Some(NOTARIZE_NAMESPACE), &block_payload);
135 let notarization = Notarization::new(view, parent_view, block_digest, block_signature);
136
137 let serialized = notarization.serialize();
139 let deserialized =
140 Notarization::deserialize(Some(&network.public_key()), &serialized).unwrap();
141 assert_eq!(notarization.view, deserialized.view);
142 assert_eq!(notarization.parent, deserialized.parent);
143 assert_eq!(notarization.payload, deserialized.payload);
144
145 let finalize_payload = Finalization::payload(view, parent_view, ¬arization.payload);
147 let finalize_signature = network.sign(Some(FINALIZE_NAMESPACE), &finalize_payload);
148 let finalization =
149 Finalization::new(view, parent_view, notarization.payload, finalize_signature);
150
151 let serialized = finalization.serialize();
153 let deserialized =
154 Finalization::deserialize(Some(&network.public_key()), &serialized).unwrap();
155 assert_eq!(finalization.view, deserialized.view);
156 assert_eq!(finalization.parent, deserialized.parent);
157 assert_eq!(finalization.payload, deserialized.payload);
158 }
159
160 #[test]
161 fn test_notarization_finalization_manipulated() {
162 let mut rng = StdRng::seed_from_u64(0);
164 let mut network = Bls12381::new(&mut rng);
165
166 let parent_digest = hash(&[0; 32]);
168 let height = 0;
169 let timestamp = 1;
170 let block = Block::new(parent_digest, height, timestamp);
171
172 let view = 0;
174 let parent_view = 0;
175 let block_payload = Notarization::payload(view, parent_view, &block.digest());
176 let block_signature = network.sign(Some(NOTARIZE_NAMESPACE), &block_payload);
177
178 let notarization =
180 Notarization::new(view + 1, parent_view, block.digest(), block_signature);
181
182 let serialized = notarization.serialize();
184 let result = Notarization::deserialize(Some(&network.public_key()), &serialized);
185 assert!(result.is_none());
186
187 let result = Notarization::deserialize(None, &serialized);
189 assert!(result.is_some());
190
191 let finalize_payload = Finalization::payload(view, parent_view, &block.digest());
193 let finalize_signature = network.sign(Some(FINALIZE_NAMESPACE), &finalize_payload);
194
195 let finalization =
197 Finalization::new(view + 1, parent_view, block.digest(), finalize_signature);
198
199 let serialized = finalization.serialize();
201 let result = Finalization::deserialize(Some(&network.public_key()), &serialized);
202 assert!(result.is_none());
203
204 let result = Finalization::deserialize(None, &serialized);
206 assert!(result.is_some());
207 }
208}