alto_types/
lib.rs

1//! Common types used throughout `alto`.
2
3mod block;
4pub use block::{Block, Finalized, Notarized};
5mod consensus;
6pub use consensus::{Finalization, Kind, Notarization, Nullification, Seed};
7
8// We don't use functions here to guard against silent changes.
9pub 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        // Create network key
25        let mut rng = StdRng::seed_from_u64(0);
26        let mut network = Bls12381::new(&mut rng);
27
28        // Create seed
29        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        // Check seed serialization
35        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        // Create network key
43        let mut rng = StdRng::seed_from_u64(0);
44        let mut network = Bls12381::new(&mut rng);
45
46        // Create seed
47        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        // Modify contents
53        seed.view = 1;
54
55        // Serialize seed
56        let serialized = seed.serialize();
57
58        // Deserialize seed
59        assert!(Seed::deserialize(Some(&network.public_key()), &serialized).is_none());
60
61        // Deserialize seed with no public key
62        assert!(Seed::deserialize(None, &serialized).is_some());
63    }
64
65    #[test]
66    fn test_nullification() {
67        // Create network key
68        let mut rng = StdRng::seed_from_u64(0);
69        let mut network = Bls12381::new(&mut rng);
70
71        // Create nullification
72        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        // Check nullification serialization
78        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        // Create network key
87        let mut rng = StdRng::seed_from_u64(0);
88        let mut network = Bls12381::new(&mut rng);
89
90        // Create nullification
91        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        // Modify contents
97        nullification.view = 1;
98
99        // Serialize nullification
100        let serialized = nullification.serialize();
101
102        // Deserialize nullification
103        assert!(Nullification::deserialize(Some(&network.public_key()), &serialized).is_none());
104
105        // Deserialize nullification with no public key
106        assert!(Nullification::deserialize(None, &serialized).is_some());
107    }
108
109    #[test]
110    fn test_notarization_finalization() {
111        // Create network key
112        let mut rng = StdRng::seed_from_u64(0);
113        let mut network = Bls12381::new(&mut rng);
114
115        // Create block
116        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        // Check block serialization
123        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        // Create notarization
131        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        // Check notarization serialization
138        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        // Create finalization
146        let finalize_payload = Finalization::payload(view, parent_view, &notarization.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        // Check finalization serialization
152        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        // Create network key
163        let mut rng = StdRng::seed_from_u64(0);
164        let mut network = Bls12381::new(&mut rng);
165
166        // Create block
167        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        // Create notarization
173        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        // Create incorrect notarization proof
179        let notarization =
180            Notarization::new(view + 1, parent_view, block.digest(), block_signature);
181
182        // Check notarization serialization
183        let serialized = notarization.serialize();
184        let result = Notarization::deserialize(Some(&network.public_key()), &serialized);
185        assert!(result.is_none());
186
187        // Check notarization serialization with no public key
188        let result = Notarization::deserialize(None, &serialized);
189        assert!(result.is_some());
190
191        // Create finalization
192        let finalize_payload = Finalization::payload(view, parent_view, &block.digest());
193        let finalize_signature = network.sign(Some(FINALIZE_NAMESPACE), &finalize_payload);
194
195        // Create incorrect finalization proof
196        let finalization =
197            Finalization::new(view + 1, parent_view, block.digest(), finalize_signature);
198
199        // Check finalization serialization
200        let serialized = finalization.serialize();
201        let result = Finalization::deserialize(Some(&network.public_key()), &serialized);
202        assert!(result.is_none());
203
204        // Check finalization serialization with no public key
205        let result = Finalization::deserialize(None, &serialized);
206        assert!(result.is_some());
207    }
208}