alto_types/
consensus.rs

1use crate::{FINALIZE_NAMESPACE, NOTARIZE_NAMESPACE, NULLIFY_NAMESPACE, SEED_NAMESPACE};
2use bytes::{Buf, BufMut};
3use commonware_cryptography::sha256::Digest;
4use commonware_cryptography::{bls12381, Bls12381, Scheme};
5use commonware_utils::{hex, Array, SizedSerialize};
6
7// We hardcode the keys here to guard against silent changes.
8#[repr(u8)]
9pub enum Kind {
10    Seed = 0,
11    Notarization = 1,
12    Nullification = 2,
13    Finalization = 3,
14}
15
16impl Kind {
17    pub fn from_u8(value: u8) -> Option<Self> {
18        match value {
19            0 => Some(Self::Seed),
20            1 => Some(Self::Notarization),
21            2 => Some(Self::Nullification),
22            3 => Some(Self::Finalization),
23            _ => None,
24        }
25    }
26
27    pub fn to_hex(&self) -> String {
28        match self {
29            Self::Seed => hex(&[0]),
30            Self::Notarization => hex(&[1]),
31            Self::Nullification => hex(&[2]),
32            Self::Finalization => hex(&[3]),
33        }
34    }
35}
36
37#[derive(Clone, Debug, PartialEq, Eq)]
38pub struct Seed {
39    pub view: u64,
40    pub signature: bls12381::Signature,
41}
42
43impl Seed {
44    pub fn payload(view: u64) -> Vec<u8> {
45        let mut bytes = Vec::with_capacity(u64::SERIALIZED_LEN);
46        bytes.put_u64(view);
47        bytes
48    }
49
50    fn pack(view: u64, signature: &bls12381::Signature) -> Vec<u8> {
51        let mut bytes = Vec::with_capacity(Self::SERIALIZED_LEN);
52        bytes.put_u64(view);
53        bytes.extend_from_slice(signature);
54        bytes
55    }
56
57    pub fn new(view: u64, signature: bls12381::Signature) -> Self {
58        Self { view, signature }
59    }
60
61    pub fn serialize(&self) -> Vec<u8> {
62        Self::pack(self.view, &self.signature)
63    }
64
65    pub fn deserialize(public: Option<&bls12381::PublicKey>, mut bytes: &[u8]) -> Option<Self> {
66        // Check if the length is correct
67        if bytes.len() != Self::SERIALIZED_LEN {
68            return None;
69        }
70
71        // Deserialize the block proof
72        let view = bytes.get_u64();
73        let signature = bls12381::Signature::read_from(&mut bytes).ok()?;
74
75        // Verify the signature
76        if let Some(public) = public {
77            let message = Self::payload(view);
78            if !Bls12381::verify(Some(SEED_NAMESPACE), &message, public, &signature) {
79                return None;
80            }
81        }
82        Some(Self { view, signature })
83    }
84}
85
86impl SizedSerialize for Seed {
87    const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN + bls12381::Signature::SERIALIZED_LEN;
88}
89
90#[derive(Clone, Debug, PartialEq, Eq)]
91pub struct Notarization {
92    pub view: u64,
93    pub parent: u64,
94    pub payload: Digest,
95    pub signature: bls12381::Signature,
96}
97
98impl Notarization {
99    pub fn payload(view: u64, parent: u64, payload: &Digest) -> Vec<u8> {
100        let mut bytes =
101            Vec::with_capacity(u64::SERIALIZED_LEN + u64::SERIALIZED_LEN + Digest::SERIALIZED_LEN);
102        bytes.put_u64(view);
103        bytes.put_u64(parent);
104        bytes.extend_from_slice(payload);
105        bytes
106    }
107
108    fn pack(view: u64, parent: u64, payload: &Digest, signature: &bls12381::Signature) -> Vec<u8> {
109        let mut bytes = Vec::with_capacity(Self::SERIALIZED_LEN);
110        bytes.put_u64(view);
111        bytes.put_u64(parent);
112        bytes.extend_from_slice(payload);
113        bytes.extend_from_slice(signature);
114        bytes
115    }
116
117    pub fn new(view: u64, parent: u64, payload: Digest, signature: bls12381::Signature) -> Self {
118        Self {
119            view,
120            parent,
121            payload,
122            signature,
123        }
124    }
125
126    pub fn serialize(&self) -> Vec<u8> {
127        Self::pack(self.view, self.parent, &self.payload, &self.signature)
128    }
129
130    pub fn deserialize(public: Option<&bls12381::PublicKey>, mut bytes: &[u8]) -> Option<Self> {
131        // Check if the length is correct
132        if bytes.len() != Self::SERIALIZED_LEN {
133            return None;
134        }
135
136        // Deserialize the block proof
137        let view = bytes.get_u64();
138        let parent = bytes.get_u64();
139        let payload = Digest::read_from(&mut bytes).ok()?;
140        let signature = bls12381::Signature::read_from(&mut bytes).ok()?;
141
142        // Verify the signature
143        if let Some(public) = public {
144            let message = Self::payload(view, parent, &payload);
145            if !Bls12381::verify(Some(NOTARIZE_NAMESPACE), &message, public, &signature) {
146                return None;
147            }
148        }
149        Some(Self {
150            view,
151            parent,
152            payload,
153            signature,
154        })
155    }
156}
157
158impl SizedSerialize for Notarization {
159    const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN
160        + u64::SERIALIZED_LEN
161        + Digest::SERIALIZED_LEN
162        + bls12381::Signature::SERIALIZED_LEN;
163}
164
165#[derive(Clone, Debug, PartialEq, Eq)]
166pub struct Nullification {
167    pub view: u64,
168    pub signature: bls12381::Signature,
169}
170
171impl Nullification {
172    pub fn payload(view: u64) -> Vec<u8> {
173        let mut bytes = Vec::with_capacity(u64::SERIALIZED_LEN);
174        bytes.put_u64(view);
175        bytes
176    }
177
178    fn pack(view: u64, signature: &bls12381::Signature) -> Vec<u8> {
179        let mut bytes = Vec::with_capacity(Self::SERIALIZED_LEN);
180        bytes.put_u64(view);
181        bytes.extend_from_slice(signature);
182        bytes
183    }
184
185    pub fn new(view: u64, signature: bls12381::Signature) -> Self {
186        Self { view, signature }
187    }
188
189    pub fn serialize(&self) -> Vec<u8> {
190        Self::pack(self.view, &self.signature)
191    }
192
193    pub fn deserialize(public: Option<&bls12381::PublicKey>, mut bytes: &[u8]) -> Option<Self> {
194        // Check if the length is correct
195        if bytes.len() != Self::SERIALIZED_LEN {
196            return None;
197        }
198
199        // Deserialize the block proof
200        let view = bytes.get_u64();
201        let signature = bls12381::Signature::read_from(&mut bytes).ok()?;
202
203        // Verify the signature
204        if let Some(public) = public {
205            let message = Self::payload(view);
206            if !Bls12381::verify(Some(NULLIFY_NAMESPACE), &message, public, &signature) {
207                return None;
208            }
209        }
210        Some(Self { view, signature })
211    }
212}
213
214impl SizedSerialize for Nullification {
215    const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN + bls12381::Signature::SERIALIZED_LEN;
216}
217
218#[derive(Clone, Debug, PartialEq, Eq)]
219pub struct Finalization {
220    pub view: u64,
221    pub parent: u64,
222    pub payload: Digest,
223    pub signature: bls12381::Signature,
224}
225
226impl Finalization {
227    pub fn payload(view: u64, parent: u64, payload: &Digest) -> Vec<u8> {
228        let mut bytes =
229            Vec::with_capacity(u64::SERIALIZED_LEN + u64::SERIALIZED_LEN + Digest::SERIALIZED_LEN);
230        bytes.put_u64(view);
231        bytes.put_u64(parent);
232        bytes.extend_from_slice(payload);
233        bytes
234    }
235
236    fn pack(view: u64, parent: u64, payload: &Digest, signature: &bls12381::Signature) -> Vec<u8> {
237        let mut bytes = Vec::with_capacity(Self::SERIALIZED_LEN);
238        bytes.put_u64(view);
239        bytes.put_u64(parent);
240        bytes.extend_from_slice(payload);
241        bytes.extend_from_slice(signature);
242        bytes
243    }
244
245    pub fn new(view: u64, parent: u64, payload: Digest, signature: bls12381::Signature) -> Self {
246        Self {
247            view,
248            parent,
249            payload,
250            signature,
251        }
252    }
253
254    pub fn serialize(&self) -> Vec<u8> {
255        Self::pack(self.view, self.parent, &self.payload, &self.signature)
256    }
257
258    pub fn deserialize(public: Option<&bls12381::PublicKey>, mut bytes: &[u8]) -> Option<Self> {
259        // Check if the length is correct
260        if bytes.len() != Self::SERIALIZED_LEN {
261            return None;
262        }
263
264        // Deserialize the block proof
265        let view = bytes.get_u64();
266        let parent = bytes.get_u64();
267        let payload = Digest::read_from(&mut bytes).ok()?;
268        let signature = bls12381::Signature::read_from(&mut bytes).ok()?;
269
270        // Verify the signature
271        if let Some(public) = public {
272            let message = Self::payload(view, parent, &payload);
273            if !Bls12381::verify(Some(FINALIZE_NAMESPACE), &message, public, &signature) {
274                return None;
275            }
276        }
277        Some(Self {
278            view,
279            parent,
280            payload,
281            signature,
282        })
283    }
284}
285
286impl SizedSerialize for Finalization {
287    const SERIALIZED_LEN: usize = u64::SERIALIZED_LEN
288        + u64::SERIALIZED_LEN
289        + Digest::SERIALIZED_LEN
290        + bls12381::Signature::SERIALIZED_LEN;
291}