1mod block;
4pub use block::{Block, Finalized, Notarized};
5mod consensus;
6use commonware_utils::hex;
7pub use consensus::{
8 Activity, Evaluation, Finalization, Identity, Notarization, PublicKey, Scheme, Seed, Seedable,
9 Signature,
10};
11pub mod wasm;
12
13pub const NAMESPACE: &[u8] = b"_ALTO";
15
16pub const EPOCH: u64 = 0;
22pub const EPOCH_LENGTH: u64 = u64::MAX;
29
30#[repr(u8)]
31pub enum Kind {
32 Seed = 0,
33 Notarization = 1,
34 Finalization = 2,
35}
36
37impl Kind {
38 pub fn from_u8(value: u8) -> Option<Self> {
39 match value {
40 0 => Some(Self::Seed),
41 1 => Some(Self::Notarization),
42 2 => Some(Self::Finalization),
43 _ => None,
44 }
45 }
46
47 pub fn to_hex(&self) -> String {
48 match self {
49 Self::Seed => hex(&[0]),
50 Self::Notarization => hex(&[1]),
51 Self::Finalization => hex(&[2]),
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use commonware_codec::{DecodeExt, Encode};
60 use commonware_consensus::{
61 simplex::types::{Finalization, Finalize, Notarization, Notarize, Proposal},
62 types::Round,
63 };
64 use commonware_cryptography::{
65 bls12381::{dkg::ops, primitives::variant::MinSig},
66 ed25519, Digestible, Hasher, PrivateKeyExt, Sha256, Signer,
67 };
68 use commonware_utils::set::Ordered;
69 use rand::{rngs::StdRng, SeedableRng};
70
71 #[test]
72 fn test_notarized() {
73 let mut rng = StdRng::seed_from_u64(0);
75 let n = 4;
76 let participants = (0..n)
77 .map(|_| ed25519::PrivateKey::from_rng(&mut rng).public_key())
78 .collect::<Ordered<_>>();
79 let (polynomial, shares) = ops::generate_shares::<_, MinSig>(&mut rng, None, n, 3);
80 let schemes: Vec<_> = shares
81 .into_iter()
82 .map(|share| Scheme::new(participants.clone(), &polynomial, share))
83 .collect();
84
85 let digest = Sha256::hash(b"hello world");
87 let block = Block::new(digest, 10, 100);
88 let proposal = Proposal::new(Round::new(EPOCH, 11), 8, block.digest());
89
90 let notarizes: Vec<_> = schemes
92 .iter()
93 .map(|scheme| Notarize::sign(scheme, NAMESPACE, proposal.clone()).unwrap())
94 .collect();
95 let notarization = Notarization::from_notarizes(&schemes[0], ¬arizes).unwrap();
96 let notarized = Notarized::new(notarization, block.clone());
97
98 let encoded = notarized.encode();
100 let decoded = Notarized::decode(encoded).expect("failed to decode notarized");
101 assert_eq!(notarized, decoded);
102
103 assert!(notarized.verify(&schemes[0], NAMESPACE));
105 }
106
107 #[test]
108 fn test_finalized() {
109 let mut rng = StdRng::seed_from_u64(0);
111 let n = 4;
112 let (polynomial, shares) = ops::generate_shares::<_, MinSig>(&mut rng, None, n, 3);
113 let participants = (0..n)
114 .map(|_| ed25519::PrivateKey::from_rng(&mut rng).public_key())
115 .collect::<Ordered<_>>();
116 let schemes: Vec<_> = shares
117 .into_iter()
118 .map(|share| Scheme::new(participants.clone(), &polynomial, share))
119 .collect();
120
121 let digest = Sha256::hash(b"hello world");
123 let block = Block::new(digest, 10, 100);
124 let proposal = Proposal::new(Round::new(EPOCH, 11), 8, block.digest());
125
126 let finalizes: Vec<_> = schemes
128 .iter()
129 .map(|scheme| Finalize::sign(scheme, NAMESPACE, proposal.clone()).unwrap())
130 .collect();
131 let finalization = Finalization::from_finalizes(&schemes[0], &finalizes).unwrap();
132 let finalized = Finalized::new(finalization, block.clone());
133
134 let encoded = finalized.encode();
136 let decoded = Finalized::decode(encoded).expect("failed to decode finalized");
137 assert_eq!(finalized, decoded);
138
139 assert!(finalized.verify(&schemes[0], NAMESPACE));
141 }
142}