alto_types/
lib.rs

1//! Common types used throughout `alto`.
2
3mod block;
4pub use block::{Block, Finalized, Notarized};
5mod consensus;
6pub use consensus::{leader_index, Finalization, Kind, Notarization, Nullification, Seed};
7pub mod wasm;
8
9// We don't use functions here to guard against silent changes.
10pub const NAMESPACE: &[u8] = b"_ALTO";
11pub const P2P_NAMESPACE: &[u8] = b"_ALTO_P2P";
12pub const SEED_NAMESPACE: &[u8] = b"_ALTO_SEED";
13pub const NOTARIZE_NAMESPACE: &[u8] = b"_ALTO_NOTARIZE";
14pub const NULLIFY_NAMESPACE: &[u8] = b"_ALTO_NULLIFY";
15pub const FINALIZE_NAMESPACE: &[u8] = b"_ALTO_FINALIZE";
16
17#[cfg(test)]
18mod tests {
19    use super::*;
20    use commonware_cryptography::{hash, Bls12381, Scheme};
21    use rand::{rngs::StdRng, SeedableRng};
22
23    #[test]
24    fn test_seed() {
25        // Create network key
26        let mut rng = StdRng::seed_from_u64(0);
27        let mut network = Bls12381::new(&mut rng);
28
29        // Create seed
30        let view = 0;
31        let seed_payload = Seed::payload(view);
32        let seed_signature = network.sign(Some(SEED_NAMESPACE), &seed_payload);
33        let seed = Seed::new(view, seed_signature);
34
35        // Check seed serialization
36        let serialized = seed.serialize();
37        let deserialized = Seed::deserialize(Some(&network.public_key()), &serialized).unwrap();
38        assert_eq!(seed.view, deserialized.view);
39    }
40
41    #[test]
42    fn test_seed_manipulated() {
43        // Create network key
44        let mut rng = StdRng::seed_from_u64(0);
45        let mut network = Bls12381::new(&mut rng);
46
47        // Create seed
48        let view = 0;
49        let seed_payload = Seed::payload(view);
50        let seed_signature = network.sign(Some(SEED_NAMESPACE), &seed_payload);
51        let mut seed = Seed::new(view, seed_signature);
52
53        // Modify contents
54        seed.view = 1;
55
56        // Serialize seed
57        let serialized = seed.serialize();
58
59        // Deserialize seed
60        assert!(Seed::deserialize(Some(&network.public_key()), &serialized).is_none());
61
62        // Deserialize seed with no public key
63        assert!(Seed::deserialize(None, &serialized).is_some());
64    }
65
66    #[test]
67    fn test_nullification() {
68        // Create network key
69        let mut rng = StdRng::seed_from_u64(0);
70        let mut network = Bls12381::new(&mut rng);
71
72        // Create nullification
73        let view = 0;
74        let nullify_payload = Nullification::payload(view);
75        let nullify_signature = network.sign(Some(NULLIFY_NAMESPACE), &nullify_payload);
76        let nullification = Nullification::new(view, nullify_signature);
77
78        // Check nullification serialization
79        let serialized = nullification.serialize();
80        let deserialized =
81            Nullification::deserialize(Some(&network.public_key()), &serialized).unwrap();
82        assert_eq!(nullification.view, deserialized.view);
83    }
84
85    #[test]
86    fn test_nullification_manipulated() {
87        // Create network key
88        let mut rng = StdRng::seed_from_u64(0);
89        let mut network = Bls12381::new(&mut rng);
90
91        // Create nullification
92        let view = 0;
93        let nullify_payload = Nullification::payload(view);
94        let nullify_signature = network.sign(Some(NULLIFY_NAMESPACE), &nullify_payload);
95        let mut nullification = Nullification::new(view, nullify_signature);
96
97        // Modify contents
98        nullification.view = 1;
99
100        // Serialize nullification
101        let serialized = nullification.serialize();
102
103        // Deserialize nullification
104        assert!(Nullification::deserialize(Some(&network.public_key()), &serialized).is_none());
105
106        // Deserialize nullification with no public key
107        assert!(Nullification::deserialize(None, &serialized).is_some());
108    }
109
110    #[test]
111    fn test_notarization_finalization() {
112        // Create network key
113        let mut rng = StdRng::seed_from_u64(0);
114        let mut network = Bls12381::new(&mut rng);
115
116        // Create block
117        let parent_digest = hash(&[0; 32]);
118        let height = 0;
119        let timestamp = 1;
120        let block = Block::new(parent_digest, height, timestamp);
121        let block_digest = block.digest();
122
123        // Check block serialization
124        let serialized = block.serialize();
125        let deserialized = Block::deserialize(&serialized).unwrap();
126        assert_eq!(block_digest, deserialized.digest());
127        assert_eq!(block.parent, deserialized.parent);
128        assert_eq!(block.height, deserialized.height);
129        assert_eq!(block.timestamp, deserialized.timestamp);
130
131        // Create notarization
132        let view = 0;
133        let parent_view = 0;
134        let block_payload = Notarization::payload(view, parent_view, &block_digest);
135        let block_signature = network.sign(Some(NOTARIZE_NAMESPACE), &block_payload);
136        let notarization = Notarization::new(view, parent_view, block_digest, block_signature);
137
138        // Check notarization serialization
139        let serialized = notarization.serialize();
140        let deserialized =
141            Notarization::deserialize(Some(&network.public_key()), &serialized).unwrap();
142        assert_eq!(notarization.view, deserialized.view);
143        assert_eq!(notarization.parent, deserialized.parent);
144        assert_eq!(notarization.payload, deserialized.payload);
145
146        // Create finalization
147        let finalize_payload = Finalization::payload(view, parent_view, &notarization.payload);
148        let finalize_signature = network.sign(Some(FINALIZE_NAMESPACE), &finalize_payload);
149        let finalization =
150            Finalization::new(view, parent_view, notarization.payload, finalize_signature);
151
152        // Check finalization serialization
153        let serialized = finalization.serialize();
154        let deserialized =
155            Finalization::deserialize(Some(&network.public_key()), &serialized).unwrap();
156        assert_eq!(finalization.view, deserialized.view);
157        assert_eq!(finalization.parent, deserialized.parent);
158        assert_eq!(finalization.payload, deserialized.payload);
159    }
160
161    #[test]
162    fn test_notarization_finalization_manipulated() {
163        // Create network key
164        let mut rng = StdRng::seed_from_u64(0);
165        let mut network = Bls12381::new(&mut rng);
166
167        // Create block
168        let parent_digest = hash(&[0; 32]);
169        let height = 0;
170        let timestamp = 1;
171        let block = Block::new(parent_digest, height, timestamp);
172
173        // Create notarization
174        let view = 0;
175        let parent_view = 0;
176        let block_payload = Notarization::payload(view, parent_view, &block.digest());
177        let block_signature = network.sign(Some(NOTARIZE_NAMESPACE), &block_payload);
178
179        // Create incorrect notarization proof
180        let notarization =
181            Notarization::new(view + 1, parent_view, block.digest(), block_signature);
182
183        // Check notarization serialization
184        let serialized = notarization.serialize();
185        let result = Notarization::deserialize(Some(&network.public_key()), &serialized);
186        assert!(result.is_none());
187
188        // Check notarization serialization with no public key
189        let result = Notarization::deserialize(None, &serialized);
190        assert!(result.is_some());
191
192        // Create finalization
193        let finalize_payload = Finalization::payload(view, parent_view, &block.digest());
194        let finalize_signature = network.sign(Some(FINALIZE_NAMESPACE), &finalize_payload);
195
196        // Create incorrect finalization proof
197        let finalization =
198            Finalization::new(view + 1, parent_view, block.digest(), finalize_signature);
199
200        // Check finalization serialization
201        let serialized = finalization.serialize();
202        let result = Finalization::deserialize(Some(&network.public_key()), &serialized);
203        assert!(result.is_none());
204
205        // Check finalization serialization with no public key
206        let result = Finalization::deserialize(None, &serialized);
207        assert!(result.is_some());
208    }
209}