1use crate::Viewable;
4use bytes::{Buf, BufMut};
5use commonware_codec::{
6 varint::UInt, Encode, EncodeSize, Error, Read, ReadExt, ReadRangeExt, Write,
7};
8use commonware_cryptography::{Digest, Signature as CSignature, Signer, Verifier};
9use commonware_utils::{quorum, union};
10
11pub type View = u64;
13
14#[derive(Clone)]
17pub struct Context<D: Digest> {
18 pub view: View,
20
21 pub parent: (View, D),
28}
29
30pub trait Attributable {
33 fn signer(&self) -> u32;
35}
36
37pub const NOTARIZE_SUFFIX: &[u8] = b"_NOTARIZE";
40pub const NULLIFY_SUFFIX: &[u8] = b"_NULLIFY";
41pub const FINALIZE_SUFFIX: &[u8] = b"_FINALIZE";
42
43#[inline]
45pub fn view_message(view: View) -> Vec<u8> {
46 View::encode(&view).into()
47}
48
49#[inline]
51pub fn notarize_namespace(namespace: &[u8]) -> Vec<u8> {
52 union(namespace, NOTARIZE_SUFFIX)
53}
54
55#[inline]
57pub fn nullify_namespace(namespace: &[u8]) -> Vec<u8> {
58 union(namespace, NULLIFY_SUFFIX)
59}
60
61#[inline]
63pub fn finalize_namespace(namespace: &[u8]) -> Vec<u8> {
64 union(namespace, FINALIZE_SUFFIX)
65}
66
67#[inline]
71pub fn threshold<P>(validators: &[P]) -> (u32, u32) {
72 let len = validators.len() as u32;
73 let threshold = quorum(len);
74 (threshold, len)
75}
76
77#[derive(Clone, Debug, PartialEq)]
80pub enum Voter<S: CSignature, D: Digest> {
81 Notarize(Notarize<S, D>),
83 Notarization(Notarization<S, D>),
85 Nullify(Nullify<S>),
87 Nullification(Nullification<S>),
89 Finalize(Finalize<S, D>),
91 Finalization(Finalization<S, D>),
93}
94
95impl<S: CSignature, D: Digest> Write for Voter<S, D> {
96 fn write(&self, writer: &mut impl BufMut) {
97 match self {
98 Voter::Notarize(notarize) => {
99 0u8.write(writer);
100 notarize.write(writer);
101 }
102 Voter::Notarization(notarization) => {
103 1u8.write(writer);
104 notarization.write(writer);
105 }
106 Voter::Nullify(nullify) => {
107 2u8.write(writer);
108 nullify.write(writer);
109 }
110 Voter::Nullification(nullification) => {
111 3u8.write(writer);
112 nullification.write(writer);
113 }
114 Voter::Finalize(finalize) => {
115 4u8.write(writer);
116 finalize.write(writer);
117 }
118 Voter::Finalization(finalization) => {
119 5u8.write(writer);
120 finalization.write(writer);
121 }
122 }
123 }
124}
125
126impl<S: CSignature, D: Digest> Read for Voter<S, D> {
127 type Cfg = usize;
128
129 fn read_cfg(reader: &mut impl Buf, max_len: &usize) -> Result<Self, Error> {
130 let tag = u8::read(reader)?;
131 match tag {
132 0 => Ok(Voter::Notarize(Notarize::<S, D>::read(reader)?)),
133 1 => Ok(Voter::Notarization(Notarization::<S, D>::read_cfg(
134 reader, max_len,
135 )?)),
136 2 => Ok(Voter::Nullify(Nullify::<S>::read(reader)?)),
137 3 => Ok(Voter::Nullification(Nullification::<S>::read_cfg(
138 reader, max_len,
139 )?)),
140 4 => Ok(Voter::Finalize(Finalize::<S, D>::read(reader)?)),
141 5 => Ok(Voter::Finalization(Finalization::<S, D>::read_cfg(
142 reader, max_len,
143 )?)),
144 _ => Err(Error::Invalid("consensus::simplex::Voter", "Invalid type")),
145 }
146 }
147}
148
149impl<S: CSignature, D: Digest> EncodeSize for Voter<S, D> {
150 fn encode_size(&self) -> usize {
151 1 + match self {
152 Voter::Notarize(notarize) => notarize.encode_size(),
153 Voter::Notarization(notarization) => notarization.encode_size(),
154 Voter::Nullify(nullify) => nullify.encode_size(),
155 Voter::Nullification(nullification) => nullification.encode_size(),
156 Voter::Finalize(finalize) => finalize.encode_size(),
157 Voter::Finalization(finalization) => finalization.encode_size(),
158 }
159 }
160}
161
162impl<S: CSignature, D: Digest> Viewable for Voter<S, D> {
163 type View = View;
164
165 fn view(&self) -> View {
166 match self {
167 Voter::Notarize(notarize) => notarize.view(),
168 Voter::Notarization(notarization) => notarization.view(),
169 Voter::Nullify(nullify) => nullify.view(),
170 Voter::Nullification(nullification) => nullification.view(),
171 Voter::Finalize(finalize) => finalize.view(),
172 Voter::Finalization(finalization) => finalization.view(),
173 }
174 }
175}
176
177#[derive(Clone, Debug, PartialEq, Eq, Hash)]
180pub struct Proposal<D: Digest> {
181 pub view: View,
183 pub parent: View,
185 pub payload: D,
187}
188
189impl<D: Digest> Proposal<D> {
190 pub fn new(view: View, parent: View, payload: D) -> Self {
192 Self {
193 view,
194 parent,
195 payload,
196 }
197 }
198}
199
200impl<D: Digest> Write for Proposal<D> {
201 fn write(&self, writer: &mut impl BufMut) {
202 UInt(self.view).write(writer);
203 UInt(self.parent).write(writer);
204 self.payload.write(writer);
205 }
206}
207
208impl<D: Digest> Read for Proposal<D> {
209 type Cfg = ();
210
211 fn read_cfg(reader: &mut impl Buf, _: &()) -> Result<Self, Error> {
212 let view = UInt::read_cfg(reader, &())?.into();
213 let parent = UInt::read_cfg(reader, &())?.into();
214 let payload = D::read_cfg(reader, &())?;
215 Ok(Self {
216 view,
217 parent,
218 payload,
219 })
220 }
221}
222
223impl<D: Digest> EncodeSize for Proposal<D> {
224 fn encode_size(&self) -> usize {
225 UInt(self.view).encode_size() + UInt(self.parent).encode_size() + self.payload.encode_size()
226 }
227}
228
229impl<D: Digest> Viewable for Proposal<D> {
230 type View = View;
231
232 fn view(&self) -> View {
233 self.view
234 }
235}
236
237#[derive(Clone, Debug, PartialEq, Eq, Hash)]
240pub struct Signature<S: CSignature> {
241 pub public_key: u32,
243 pub signature: S,
245}
246
247impl<S: CSignature> Signature<S> {
248 pub fn new(public_key: u32, signature: S) -> Self {
250 Self {
251 public_key,
252 signature,
253 }
254 }
255}
256
257impl<S: CSignature> Write for Signature<S> {
258 fn write(&self, writer: &mut impl BufMut) {
259 UInt(self.public_key).write(writer);
260 self.signature.write(writer);
261 }
262}
263
264impl<S: CSignature> Read for Signature<S> {
265 type Cfg = ();
266
267 fn read_cfg(reader: &mut impl Buf, _: &()) -> Result<Self, Error> {
268 let public_key = UInt::read(reader)?.into();
269 let signature = S::read(reader)?;
270 Ok(Self {
271 public_key,
272 signature,
273 })
274 }
275}
276
277impl<S: CSignature> EncodeSize for Signature<S> {
278 fn encode_size(&self) -> usize {
279 UInt(self.public_key).encode_size() + self.signature.encode_size()
280 }
281}
282
283impl<S: CSignature> Attributable for Signature<S> {
284 fn signer(&self) -> u32 {
285 self.public_key
286 }
287}
288
289#[derive(Clone, Debug, PartialEq, Eq, Hash)]
291pub struct Notarize<S: CSignature, D: Digest> {
292 pub proposal: Proposal<D>,
294 pub signature: Signature<S>,
296}
297
298impl<S: CSignature, D: Digest> Notarize<S, D> {
299 pub fn new(proposal: Proposal<D>, signature: Signature<S>) -> Self {
301 Self {
302 proposal,
303 signature,
304 }
305 }
306
307 pub fn verify<K: Verifier<Signature = S>>(&self, namespace: &[u8], public_key: &K) -> bool {
311 let notarize_namespace = notarize_namespace(namespace);
312 let message = self.proposal.encode();
313 public_key.verify(
314 Some(notarize_namespace.as_ref()),
315 &message,
316 &self.signature.signature,
317 )
318 }
319
320 pub fn sign<C: Signer<Signature = S>>(
322 namespace: &[u8],
323 signer: &mut C,
324 public_key_index: u32,
325 proposal: Proposal<D>,
326 ) -> Self {
327 let notarize_namespace = notarize_namespace(namespace);
328 let message = proposal.encode();
329 let signature = signer.sign(Some(notarize_namespace.as_ref()), &message);
330 Self {
331 proposal,
332 signature: Signature::new(public_key_index, signature),
333 }
334 }
335}
336
337impl<S: CSignature, D: Digest> Write for Notarize<S, D> {
338 fn write(&self, writer: &mut impl BufMut) {
339 self.proposal.write(writer);
340 self.signature.write(writer);
341 }
342}
343
344impl<S: CSignature, D: Digest> Read for Notarize<S, D> {
345 type Cfg = ();
346
347 fn read_cfg(reader: &mut impl Buf, _: &()) -> Result<Self, Error> {
348 let proposal = Proposal::<D>::read_cfg(reader, &())?;
349 let signature = Signature::<S>::read_cfg(reader, &())?;
350 Ok(Self {
351 proposal,
352 signature,
353 })
354 }
355}
356
357impl<S: CSignature, D: Digest> EncodeSize for Notarize<S, D> {
358 fn encode_size(&self) -> usize {
359 self.proposal.encode_size() + self.signature.encode_size()
360 }
361}
362
363impl<S: CSignature, D: Digest> Viewable for Notarize<S, D> {
364 type View = View;
365
366 fn view(&self) -> View {
367 self.proposal.view()
368 }
369}
370
371impl<S: CSignature, D: Digest> Attributable for Notarize<S, D> {
372 fn signer(&self) -> u32 {
373 self.signature.signer()
374 }
375}
376
377#[derive(Clone, Debug, PartialEq, Eq, Hash)]
380pub struct Notarization<S: CSignature, D: Digest> {
381 pub proposal: Proposal<D>,
383 pub signatures: Vec<Signature<S>>,
385}
386
387impl<S: CSignature, D: Digest> Notarization<S, D> {
388 pub fn new(proposal: Proposal<D>, signatures: Vec<Signature<S>>) -> Self {
394 Self {
395 proposal,
396 signatures,
397 }
398 }
399
400 pub fn verify<K: Verifier<Signature = S>>(&self, namespace: &[u8], participants: &[K]) -> bool {
409 let (threshold, count) = threshold(participants);
411 if self.signatures.len() < threshold as usize {
412 return false;
413 }
414 if self.signatures.len() > count as usize {
415 return false;
416 }
417
418 let notarize_namespace = notarize_namespace(namespace);
420 let message = self.proposal.encode();
421 for signature in &self.signatures {
422 let Some(public_key) = participants.get(signature.public_key as usize) else {
424 return false;
425 };
426
427 if !public_key.verify(
429 Some(notarize_namespace.as_ref()),
430 &message,
431 &signature.signature,
432 ) {
433 return false;
434 }
435 }
436 true
437 }
438}
439
440impl<S: CSignature, D: Digest> Write for Notarization<S, D> {
441 fn write(&self, writer: &mut impl BufMut) {
442 self.proposal.write(writer);
443 self.signatures.write(writer);
444 }
445}
446
447impl<S: CSignature, D: Digest> Read for Notarization<S, D> {
448 type Cfg = usize;
449
450 fn read_cfg(reader: &mut impl Buf, max_len: &usize) -> Result<Self, Error> {
451 let proposal = Proposal::<D>::read(reader)?;
452 let signatures = Vec::<Signature<S>>::read_range(reader, ..=*max_len)?;
453
454 for i in 1..signatures.len() {
456 if signatures[i - 1].public_key >= signatures[i].public_key {
457 return Err(Error::Invalid(
458 "consensus::simplex::Notarization",
459 "Signatures are not sorted by public key index",
460 ));
461 }
462 }
463 Ok(Self {
464 proposal,
465 signatures,
466 })
467 }
468}
469
470impl<S: CSignature, D: Digest> EncodeSize for Notarization<S, D> {
471 fn encode_size(&self) -> usize {
472 self.proposal.encode_size() + self.signatures.encode_size()
473 }
474}
475
476impl<S: CSignature, D: Digest> Viewable for Notarization<S, D> {
477 type View = View;
478
479 fn view(&self) -> View {
480 self.proposal.view()
481 }
482}
483
484#[derive(Clone, Debug, PartialEq, Eq, Hash)]
487pub struct Nullify<S: CSignature> {
488 pub view: View,
490 pub signature: Signature<S>,
492}
493
494impl<S: CSignature> Nullify<S> {
495 pub fn new(view: View, signature: Signature<S>) -> Self {
497 Self { view, signature }
498 }
499
500 pub fn verify<K: Verifier<Signature = S>>(&self, namespace: &[u8], public_key: &K) -> bool {
502 let nullify_namespace = nullify_namespace(namespace);
503 let message = view_message(self.view);
504 public_key.verify(
505 Some(nullify_namespace.as_ref()),
506 &message,
507 &self.signature.signature,
508 )
509 }
510
511 pub fn sign<C: Signer<Signature = S>>(
513 namespace: &[u8],
514 signer: &mut C,
515 public_key_index: u32,
516 view: View,
517 ) -> Self {
518 let nullify_namespace = nullify_namespace(namespace);
519 let message = view_message(view);
520 let signature = signer.sign(Some(nullify_namespace.as_ref()), &message);
521 Self {
522 view,
523 signature: Signature::new(public_key_index, signature),
524 }
525 }
526}
527
528impl<S: CSignature> Write for Nullify<S> {
529 fn write(&self, writer: &mut impl BufMut) {
530 UInt(self.view).write(writer);
531 self.signature.write(writer);
532 }
533}
534
535impl<S: CSignature> Read for Nullify<S> {
536 type Cfg = ();
537
538 fn read_cfg(reader: &mut impl Buf, _: &()) -> Result<Self, Error> {
539 let view = UInt::read(reader)?.into();
540 let signature = Signature::<S>::read(reader)?;
541 Ok(Self { view, signature })
542 }
543}
544
545impl<S: CSignature> EncodeSize for Nullify<S> {
546 fn encode_size(&self) -> usize {
547 UInt(self.view).encode_size() + self.signature.encode_size()
548 }
549}
550
551impl<S: CSignature> Viewable for Nullify<S> {
552 type View = View;
553
554 fn view(&self) -> View {
555 self.view
556 }
557}
558
559impl<S: CSignature> Attributable for Nullify<S> {
560 fn signer(&self) -> u32 {
561 self.signature.signer()
562 }
563}
564
565#[derive(Clone, Debug, PartialEq, Eq, Hash)]
568pub struct Nullification<S: CSignature> {
569 pub view: View,
571 pub signatures: Vec<Signature<S>>,
573}
574
575impl<S: CSignature> Nullification<S> {
576 pub fn new(view: View, signatures: Vec<Signature<S>>) -> Self {
582 Self { view, signatures }
583 }
584
585 pub fn verify<K: Verifier<Signature = S>>(&self, namespace: &[u8], participants: &[K]) -> bool {
589 let (threshold, count) = threshold(participants);
591 if self.signatures.len() < threshold as usize {
592 return false;
593 }
594 if self.signatures.len() > count as usize {
595 return false;
596 }
597
598 let nullify_namespace = nullify_namespace(namespace);
600 let message = view_message(self.view);
601 for signature in &self.signatures {
602 let Some(public_key) = participants.get(signature.public_key as usize) else {
604 return false;
605 };
606
607 if !public_key.verify(
609 Some(nullify_namespace.as_ref()),
610 &message,
611 &signature.signature,
612 ) {
613 return false;
614 }
615 }
616 true
617 }
618}
619
620impl<S: CSignature> Write for Nullification<S> {
621 fn write(&self, writer: &mut impl BufMut) {
622 UInt(self.view).write(writer);
623 self.signatures.write(writer);
624 }
625}
626
627impl<S: CSignature> Read for Nullification<S> {
628 type Cfg = usize;
629
630 fn read_cfg(reader: &mut impl Buf, max_len: &usize) -> Result<Self, Error> {
631 let view = UInt::read(reader)?.into();
632 let signatures = Vec::<Signature<S>>::read_range(reader, ..=*max_len)?;
633
634 for i in 1..signatures.len() {
636 if signatures[i - 1].public_key >= signatures[i].public_key {
637 return Err(Error::Invalid(
638 "consensus::simplex::Nullification",
639 "Signatures are not sorted by public key index",
640 ));
641 }
642 }
643 Ok(Self { view, signatures })
644 }
645}
646
647impl<S: CSignature> EncodeSize for Nullification<S> {
648 fn encode_size(&self) -> usize {
649 UInt(self.view).encode_size() + self.signatures.encode_size()
650 }
651}
652
653impl<S: CSignature> Viewable for Nullification<S> {
654 type View = View;
655
656 fn view(&self) -> View {
657 self.view
658 }
659}
660
661#[derive(Clone, Debug, PartialEq, Eq, Hash)]
665pub struct Finalize<S: CSignature, D: Digest> {
666 pub proposal: Proposal<D>,
668 pub signature: Signature<S>,
670}
671
672impl<S: CSignature, D: Digest> Finalize<S, D> {
673 pub fn new(proposal: Proposal<D>, signature: Signature<S>) -> Self {
675 Self {
676 proposal,
677 signature,
678 }
679 }
680
681 pub fn verify<K: Verifier<Signature = S>>(&self, namespace: &[u8], public_key: &K) -> bool {
683 let finalize_namespace = finalize_namespace(namespace);
684 let message = self.proposal.encode();
685 public_key.verify(
686 Some(finalize_namespace.as_ref()),
687 &message,
688 &self.signature.signature,
689 )
690 }
691
692 pub fn sign<C: Signer<Signature = S>>(
694 namespace: &[u8],
695 signer: &mut C,
696 public_key_index: u32,
697 proposal: Proposal<D>,
698 ) -> Self {
699 let finalize_namespace = finalize_namespace(namespace);
700 let message = proposal.encode();
701 let signature = signer.sign(Some(finalize_namespace.as_ref()), &message);
702 Self {
703 proposal,
704 signature: Signature::new(public_key_index, signature),
705 }
706 }
707}
708
709impl<S: CSignature, D: Digest> Write for Finalize<S, D> {
710 fn write(&self, writer: &mut impl BufMut) {
711 self.proposal.write(writer);
712 self.signature.write(writer);
713 }
714}
715
716impl<S: CSignature, D: Digest> Read for Finalize<S, D> {
717 type Cfg = ();
718
719 fn read_cfg(reader: &mut impl Buf, _: &()) -> Result<Self, Error> {
720 let proposal = Proposal::<D>::read(reader)?;
721 let signature = Signature::<S>::read(reader)?;
722 Ok(Self {
723 proposal,
724 signature,
725 })
726 }
727}
728
729impl<S: CSignature, D: Digest> EncodeSize for Finalize<S, D> {
730 fn encode_size(&self) -> usize {
731 self.proposal.encode_size() + self.signature.encode_size()
732 }
733}
734
735impl<S: CSignature, D: Digest> Viewable for Finalize<S, D> {
736 type View = View;
737
738 fn view(&self) -> View {
739 self.proposal.view()
740 }
741}
742
743impl<S: CSignature, D: Digest> Attributable for Finalize<S, D> {
744 fn signer(&self) -> u32 {
745 self.signature.signer()
746 }
747}
748
749#[derive(Clone, Debug, PartialEq, Eq, Hash)]
752pub struct Finalization<S: CSignature, D: Digest> {
753 pub proposal: Proposal<D>,
755 pub signatures: Vec<Signature<S>>,
757}
758
759impl<S: CSignature, D: Digest> Finalization<S, D> {
760 pub fn new(proposal: Proposal<D>, signatures: Vec<Signature<S>>) -> Self {
766 Self {
767 proposal,
768 signatures,
769 }
770 }
771
772 pub fn verify<V: Verifier<Signature = S>>(&self, namespace: &[u8], participants: &[V]) -> bool {
776 let (threshold, count) = threshold(participants);
778 if self.signatures.len() < threshold as usize {
779 return false;
780 }
781 if self.signatures.len() > count as usize {
782 return false;
783 }
784
785 let finalize_namespace = finalize_namespace(namespace);
787 let message = self.proposal.encode();
788 for signature in &self.signatures {
789 let Some(public_key) = participants.get(signature.public_key as usize) else {
791 return false;
792 };
793
794 if !public_key.verify(
796 Some(finalize_namespace.as_ref()),
797 &message,
798 &signature.signature,
799 ) {
800 return false;
801 }
802 }
803 true
804 }
805}
806
807impl<S: CSignature, D: Digest> Write for Finalization<S, D> {
808 fn write(&self, writer: &mut impl BufMut) {
809 self.proposal.write(writer);
810 self.signatures.write(writer);
811 }
812}
813
814impl<S: CSignature, D: Digest> Read for Finalization<S, D> {
815 type Cfg = usize;
816
817 fn read_cfg(reader: &mut impl Buf, max_len: &usize) -> Result<Self, Error> {
818 let proposal = Proposal::<D>::read(reader)?;
819 let signatures = Vec::<Signature<S>>::read_range(reader, ..=*max_len)?;
820
821 for i in 1..signatures.len() {
823 if signatures[i - 1].public_key >= signatures[i].public_key {
824 return Err(Error::Invalid(
825 "consensus::simplex::Finalization",
826 "Signatures are not sorted by public key index",
827 ));
828 }
829 }
830 Ok(Self {
831 proposal,
832 signatures,
833 })
834 }
835}
836
837impl<S: CSignature, D: Digest> EncodeSize for Finalization<S, D> {
838 fn encode_size(&self) -> usize {
839 self.proposal.encode_size() + self.signatures.encode_size()
840 }
841}
842
843impl<S: CSignature, D: Digest> Viewable for Finalization<S, D> {
844 type View = View;
845
846 fn view(&self) -> View {
847 self.proposal.view()
848 }
849}
850
851#[derive(Clone, Debug, PartialEq)]
854pub enum Backfiller<S: CSignature, D: Digest> {
855 Request(Request),
857 Response(Response<S, D>),
859}
860
861impl<S: CSignature, D: Digest> Write for Backfiller<S, D> {
862 fn write(&self, writer: &mut impl BufMut) {
863 match self {
864 Backfiller::Request(request) => {
865 0u8.write(writer);
866 request.write(writer);
867 }
868 Backfiller::Response(response) => {
869 1u8.write(writer);
870 response.write(writer);
871 }
872 }
873 }
874}
875
876impl<S: CSignature, D: Digest> Read for Backfiller<S, D> {
877 type Cfg = (usize, usize);
878
879 fn read_cfg(reader: &mut impl Buf, cfg: &(usize, usize)) -> Result<Self, Error> {
880 let tag = u8::read(reader)?;
881 match tag {
882 0 => Ok(Backfiller::Request(Request::read_cfg(reader, &cfg.0)?)),
883 1 => Ok(Backfiller::Response(Response::<S, D>::read_cfg(
884 reader, cfg,
885 )?)),
886 _ => Err(Error::Invalid(
887 "consensus::simplex::Backfiller",
888 "Invalid type",
889 )),
890 }
891 }
892}
893
894impl<S: CSignature, D: Digest> EncodeSize for Backfiller<S, D> {
895 fn encode_size(&self) -> usize {
896 1 + match self {
897 Backfiller::Request(request) => request.encode_size(),
898 Backfiller::Response(response) => response.encode_size(),
899 }
900 }
901}
902
903#[derive(Clone, Debug, PartialEq)]
906pub struct Request {
907 pub id: u64,
909 pub notarizations: Vec<View>,
911 pub nullifications: Vec<View>,
913}
914
915impl Request {
916 pub fn new(id: u64, notarizations: Vec<View>, nullifications: Vec<View>) -> Self {
918 Self {
919 id,
920 notarizations,
921 nullifications,
922 }
923 }
924}
925
926impl Write for Request {
927 fn write(&self, writer: &mut impl BufMut) {
928 UInt(self.id).write(writer);
929 self.notarizations.write(writer);
930 self.nullifications.write(writer);
931 }
932}
933
934impl Read for Request {
935 type Cfg = usize;
936
937 fn read_cfg(reader: &mut impl Buf, max_len: &usize) -> Result<Self, Error> {
938 let id = UInt::read(reader)?.into();
939 let notarizations = Vec::<View>::read_range(reader, ..=*max_len)?;
940 let remaining = max_len - notarizations.len();
941 let nullifications = Vec::<View>::read_range(reader, ..=remaining)?;
942 Ok(Self {
943 id,
944 notarizations,
945 nullifications,
946 })
947 }
948}
949
950impl EncodeSize for Request {
951 fn encode_size(&self) -> usize {
952 UInt(self.id).encode_size()
953 + self.notarizations.encode_size()
954 + self.nullifications.encode_size()
955 }
956}
957
958#[derive(Clone, Debug, PartialEq)]
961pub struct Response<S: CSignature, D: Digest> {
962 pub id: u64,
964 pub notarizations: Vec<Notarization<S, D>>,
966 pub nullifications: Vec<Nullification<S>>,
968}
969
970impl<S: CSignature, D: Digest> Response<S, D> {
971 pub fn new(
973 id: u64,
974 notarizations: Vec<Notarization<S, D>>,
975 nullifications: Vec<Nullification<S>>,
976 ) -> Self {
977 Self {
978 id,
979 notarizations,
980 nullifications,
981 }
982 }
983}
984
985impl<S: CSignature, D: Digest> Write for Response<S, D> {
986 fn write(&self, writer: &mut impl BufMut) {
987 UInt(self.id).write(writer);
988 self.notarizations.write(writer);
989 self.nullifications.write(writer);
990 }
991}
992
993impl<S: CSignature, D: Digest> Read for Response<S, D> {
994 type Cfg = (usize, usize);
995
996 fn read_cfg(reader: &mut impl Buf, (total, max_sigs): &(usize, usize)) -> Result<Self, Error> {
997 let id = UInt::read(reader)?.into();
998 let notarizations =
999 Vec::<Notarization<S, D>>::read_cfg(reader, &((..=total).into(), *max_sigs))?;
1000 let rem = total - notarizations.len();
1001 let nullifications =
1002 Vec::<Nullification<S>>::read_cfg(reader, &((..=rem).into(), *max_sigs))?;
1003 Ok(Self {
1004 id,
1005 notarizations,
1006 nullifications,
1007 })
1008 }
1009}
1010
1011impl<S: CSignature, D: Digest> EncodeSize for Response<S, D> {
1012 fn encode_size(&self) -> usize {
1013 UInt(self.id).encode_size()
1014 + self.notarizations.encode_size()
1015 + self.nullifications.encode_size()
1016 }
1017}
1018
1019#[derive(Clone, Debug, PartialEq, Hash, Eq)]
1022pub enum Activity<S: CSignature, D: Digest> {
1023 Notarize(Notarize<S, D>),
1025 Notarization(Notarization<S, D>),
1027 Nullify(Nullify<S>),
1029 Nullification(Nullification<S>),
1031 Finalize(Finalize<S, D>),
1033 Finalization(Finalization<S, D>),
1035 ConflictingNotarize(ConflictingNotarize<S, D>),
1037 ConflictingFinalize(ConflictingFinalize<S, D>),
1039 NullifyFinalize(NullifyFinalize<S, D>),
1041}
1042
1043impl<S: CSignature, D: Digest> Write for Activity<S, D> {
1044 fn write(&self, writer: &mut impl BufMut) {
1045 match self {
1046 Activity::Notarize(notarize) => {
1047 0u8.write(writer);
1048 notarize.write(writer);
1049 }
1050 Activity::Notarization(notarization) => {
1051 1u8.write(writer);
1052 notarization.write(writer);
1053 }
1054 Activity::Nullify(nullify) => {
1055 2u8.write(writer);
1056 nullify.write(writer);
1057 }
1058 Activity::Nullification(nullification) => {
1059 3u8.write(writer);
1060 nullification.write(writer);
1061 }
1062 Activity::Finalize(finalize) => {
1063 4u8.write(writer);
1064 finalize.write(writer);
1065 }
1066 Activity::Finalization(finalization) => {
1067 5u8.write(writer);
1068 finalization.write(writer);
1069 }
1070 Activity::ConflictingNotarize(conflicting_notarize) => {
1071 6u8.write(writer);
1072 conflicting_notarize.write(writer);
1073 }
1074 Activity::ConflictingFinalize(conflicting_finalize) => {
1075 7u8.write(writer);
1076 conflicting_finalize.write(writer);
1077 }
1078 Activity::NullifyFinalize(nullify_finalize) => {
1079 8u8.write(writer);
1080 nullify_finalize.write(writer);
1081 }
1082 }
1083 }
1084}
1085
1086impl<S: CSignature, D: Digest> Read for Activity<S, D> {
1087 type Cfg = usize;
1088
1089 fn read_cfg(reader: &mut impl Buf, max_len: &usize) -> Result<Self, Error> {
1090 let tag = u8::read(reader)?;
1091 match tag {
1092 0 => Ok(Activity::Notarize(Notarize::<S, D>::read(reader)?)),
1093 1 => Ok(Activity::Notarization(Notarization::<S, D>::read_cfg(
1094 reader, max_len,
1095 )?)),
1096 2 => Ok(Activity::Nullify(Nullify::<S>::read(reader)?)),
1097 3 => Ok(Activity::Nullification(Nullification::<S>::read_cfg(
1098 reader, max_len,
1099 )?)),
1100 4 => Ok(Activity::Finalize(Finalize::<S, D>::read(reader)?)),
1101 5 => Ok(Activity::Finalization(Finalization::<S, D>::read_cfg(
1102 reader, max_len,
1103 )?)),
1104 6 => Ok(Activity::ConflictingNotarize(
1105 ConflictingNotarize::<S, D>::read(reader)?,
1106 )),
1107 7 => Ok(Activity::ConflictingFinalize(
1108 ConflictingFinalize::<S, D>::read(reader)?,
1109 )),
1110 8 => Ok(Activity::NullifyFinalize(NullifyFinalize::<S, D>::read(
1111 reader,
1112 )?)),
1113 _ => Err(Error::Invalid(
1114 "consensus::simplex::Activity",
1115 "Invalid type",
1116 )),
1117 }
1118 }
1119}
1120
1121impl<S: CSignature, D: Digest> EncodeSize for Activity<S, D> {
1122 fn encode_size(&self) -> usize {
1123 1 + match self {
1124 Activity::Notarize(notarize) => notarize.encode_size(),
1125 Activity::Notarization(notarization) => notarization.encode_size(),
1126 Activity::Nullify(nullify) => nullify.encode_size(),
1127 Activity::Nullification(nullification) => nullification.encode_size(),
1128 Activity::Finalize(finalize) => finalize.encode_size(),
1129 Activity::Finalization(finalization) => finalization.encode_size(),
1130 Activity::ConflictingNotarize(conflicting_notarize) => {
1131 conflicting_notarize.encode_size()
1132 }
1133 Activity::ConflictingFinalize(conflicting_finalize) => {
1134 conflicting_finalize.encode_size()
1135 }
1136 Activity::NullifyFinalize(nullify_finalize) => nullify_finalize.encode_size(),
1137 }
1138 }
1139}
1140
1141impl<S: CSignature, D: Digest> Viewable for Activity<S, D> {
1142 type View = View;
1143
1144 fn view(&self) -> View {
1145 match self {
1146 Activity::Notarize(notarize) => notarize.view(),
1147 Activity::Notarization(notarization) => notarization.view(),
1148 Activity::Nullify(nullify) => nullify.view(),
1149 Activity::Nullification(nullification) => nullification.view(),
1150 Activity::Finalize(finalize) => finalize.view(),
1151 Activity::Finalization(finalization) => finalization.view(),
1152 Activity::ConflictingNotarize(conflicting_notarize) => conflicting_notarize.view(),
1153 Activity::ConflictingFinalize(conflicting_finalize) => conflicting_finalize.view(),
1154 Activity::NullifyFinalize(nullify_finalize) => nullify_finalize.view(),
1155 }
1156 }
1157}
1158
1159#[derive(Clone, Debug, PartialEq, Hash, Eq)]
1162pub struct ConflictingNotarize<S: CSignature, D: Digest> {
1163 pub view: View,
1165 pub parent_1: View,
1167 pub payload_1: D,
1169 pub signature_1: Signature<S>,
1171 pub parent_2: View,
1173 pub payload_2: D,
1175 pub signature_2: Signature<S>,
1177}
1178
1179impl<S: CSignature, D: Digest> ConflictingNotarize<S, D> {
1180 pub fn new(notarize_1: Notarize<S, D>, notarize_2: Notarize<S, D>) -> Self {
1182 assert_eq!(notarize_1.view(), notarize_2.view());
1183 assert_eq!(notarize_1.signer(), notarize_2.signer());
1184 Self {
1185 view: notarize_1.view(),
1186 parent_1: notarize_1.proposal.parent,
1187 payload_1: notarize_1.proposal.payload,
1188 signature_1: notarize_1.signature,
1189 parent_2: notarize_2.proposal.parent,
1190 payload_2: notarize_2.proposal.payload,
1191 signature_2: notarize_2.signature,
1192 }
1193 }
1194
1195 pub fn notarizes(&self) -> (Notarize<S, D>, Notarize<S, D>) {
1197 (
1198 Notarize::new(
1199 Proposal::new(self.view, self.parent_1, self.payload_1),
1200 self.signature_1.clone(),
1201 ),
1202 Notarize::new(
1203 Proposal::new(self.view, self.parent_2, self.payload_2),
1204 self.signature_2.clone(),
1205 ),
1206 )
1207 }
1208
1209 pub fn verify<V: Verifier<Signature = S>>(&self, namespace: &[u8], public_key: &V) -> bool {
1211 let (notarize_1, notarize_2) = self.notarizes();
1212 notarize_1.verify(namespace, public_key) && notarize_2.verify(namespace, public_key)
1213 }
1214}
1215
1216impl<S: CSignature, D: Digest> Write for ConflictingNotarize<S, D> {
1217 fn write(&self, writer: &mut impl BufMut) {
1218 UInt(self.view).write(writer);
1219 UInt(self.parent_1).write(writer);
1220 self.payload_1.write(writer);
1221 self.signature_1.write(writer);
1222 UInt(self.parent_2).write(writer);
1223 self.payload_2.write(writer);
1224 self.signature_2.write(writer);
1225 }
1226}
1227
1228impl<S: CSignature, D: Digest> Read for ConflictingNotarize<S, D> {
1229 type Cfg = ();
1230
1231 fn read_cfg(reader: &mut impl Buf, _: &()) -> Result<Self, Error> {
1232 let view = UInt::read(reader)?.into();
1233 let parent_1 = UInt::read(reader)?.into();
1234 let payload_1 = D::read_cfg(reader, &())?;
1235 let signature_1 = Signature::<S>::read(reader)?;
1236 let parent_2 = UInt::read(reader)?.into();
1237 let payload_2 = D::read_cfg(reader, &())?;
1238 let signature_2 = Signature::<S>::read(reader)?;
1239 if signature_1.signer() != signature_2.signer() {
1240 return Err(Error::Invalid(
1241 "consensus::simplex::ConflictingNotarize",
1242 "notarizes must have the same public key",
1243 ));
1244 }
1245 Ok(Self {
1246 view,
1247 parent_1,
1248 payload_1,
1249 signature_1,
1250 parent_2,
1251 payload_2,
1252 signature_2,
1253 })
1254 }
1255}
1256
1257impl<S: CSignature, D: Digest> EncodeSize for ConflictingNotarize<S, D> {
1258 fn encode_size(&self) -> usize {
1259 UInt(self.view).encode_size()
1260 + UInt(self.parent_1).encode_size()
1261 + self.payload_1.encode_size()
1262 + self.signature_1.encode_size()
1263 + UInt(self.parent_2).encode_size()
1264 + self.payload_2.encode_size()
1265 + self.signature_2.encode_size()
1266 }
1267}
1268
1269impl<S: CSignature, D: Digest> Viewable for ConflictingNotarize<S, D> {
1270 type View = View;
1271
1272 fn view(&self) -> View {
1273 self.view
1274 }
1275}
1276
1277impl<S: CSignature, D: Digest> Attributable for ConflictingNotarize<S, D> {
1278 fn signer(&self) -> u32 {
1279 self.signature_1.signer()
1280 }
1281}
1282
1283#[derive(Clone, Debug, PartialEq, Hash, Eq)]
1286pub struct ConflictingFinalize<S: CSignature, D: Digest> {
1287 pub view: View,
1289 pub parent_1: View,
1291 pub payload_1: D,
1293 pub signature_1: Signature<S>,
1295 pub parent_2: View,
1297 pub payload_2: D,
1299 pub signature_2: Signature<S>,
1301}
1302
1303impl<S: CSignature, D: Digest> ConflictingFinalize<S, D> {
1304 pub fn new(finalize_1: Finalize<S, D>, finalize_2: Finalize<S, D>) -> Self {
1306 assert_eq!(finalize_1.view(), finalize_2.view());
1307 assert_eq!(finalize_1.signer(), finalize_2.signer());
1308 Self {
1309 view: finalize_1.view(),
1310 parent_1: finalize_1.proposal.parent,
1311 payload_1: finalize_1.proposal.payload,
1312 signature_1: finalize_1.signature,
1313 parent_2: finalize_2.proposal.parent,
1314 payload_2: finalize_2.proposal.payload,
1315 signature_2: finalize_2.signature,
1316 }
1317 }
1318
1319 pub fn finalizes(&self) -> (Finalize<S, D>, Finalize<S, D>) {
1321 (
1322 Finalize::new(
1323 Proposal::new(self.view, self.parent_1, self.payload_1),
1324 self.signature_1.clone(),
1325 ),
1326 Finalize::new(
1327 Proposal::new(self.view, self.parent_2, self.payload_2),
1328 self.signature_2.clone(),
1329 ),
1330 )
1331 }
1332
1333 pub fn verify<V: Verifier<Signature = S>>(&self, namespace: &[u8], public_key: &V) -> bool {
1335 let (finalize_1, finalize_2) = self.finalizes();
1336 finalize_1.verify(namespace, public_key) && finalize_2.verify(namespace, public_key)
1337 }
1338}
1339
1340impl<S: CSignature, D: Digest> Write for ConflictingFinalize<S, D> {
1341 fn write(&self, writer: &mut impl BufMut) {
1342 UInt(self.view).write(writer);
1343 UInt(self.parent_1).write(writer);
1344 self.payload_1.write(writer);
1345 self.signature_1.write(writer);
1346 UInt(self.parent_2).write(writer);
1347 self.payload_2.write(writer);
1348 self.signature_2.write(writer);
1349 }
1350}
1351
1352impl<S: CSignature, D: Digest> Read for ConflictingFinalize<S, D> {
1353 type Cfg = ();
1354
1355 fn read_cfg(reader: &mut impl Buf, _: &()) -> Result<Self, Error> {
1356 let view = UInt::read(reader)?.into();
1357 let parent_1 = UInt::read(reader)?.into();
1358 let payload_1 = D::read_cfg(reader, &())?;
1359 let signature_1 = Signature::<S>::read(reader)?;
1360 let parent_2 = UInt::read(reader)?.into();
1361 let payload_2 = D::read_cfg(reader, &())?;
1362 let signature_2 = Signature::<S>::read(reader)?;
1363 if signature_1.signer() != signature_2.signer() {
1364 return Err(Error::Invalid(
1365 "consensus::simplex::ConflictingFinalize",
1366 "finalizes must have the same public key",
1367 ));
1368 }
1369 Ok(Self {
1370 view,
1371 parent_1,
1372 payload_1,
1373 signature_1,
1374 parent_2,
1375 payload_2,
1376 signature_2,
1377 })
1378 }
1379}
1380
1381impl<S: CSignature, D: Digest> EncodeSize for ConflictingFinalize<S, D> {
1382 fn encode_size(&self) -> usize {
1383 UInt(self.view).encode_size()
1384 + UInt(self.parent_1).encode_size()
1385 + self.payload_1.encode_size()
1386 + self.signature_1.encode_size()
1387 + UInt(self.parent_2).encode_size()
1388 + self.payload_2.encode_size()
1389 + self.signature_2.encode_size()
1390 }
1391}
1392
1393impl<S: CSignature, D: Digest> Viewable for ConflictingFinalize<S, D> {
1394 type View = View;
1395
1396 fn view(&self) -> View {
1397 self.view
1398 }
1399}
1400
1401impl<S: CSignature, D: Digest> Attributable for ConflictingFinalize<S, D> {
1402 fn signer(&self) -> u32 {
1403 self.signature_1.signer()
1404 }
1405}
1406
1407#[derive(Clone, Debug, PartialEq, Hash, Eq)]
1411pub struct NullifyFinalize<S: CSignature, D: Digest> {
1412 pub proposal: Proposal<D>,
1414 pub view_signature: Signature<S>,
1416 pub finalize_signature: Signature<S>,
1418}
1419
1420impl<S: CSignature, D: Digest> NullifyFinalize<S, D> {
1421 pub fn new(nullify: Nullify<S>, finalize: Finalize<S, D>) -> Self {
1423 assert_eq!(nullify.view(), finalize.view());
1424 assert_eq!(nullify.signer(), finalize.signer());
1425 Self {
1426 proposal: finalize.proposal,
1427 view_signature: nullify.signature,
1428 finalize_signature: finalize.signature,
1429 }
1430 }
1431
1432 pub fn verify<V: Verifier<Signature = S>>(&self, namespace: &[u8], public_key: &V) -> bool {
1434 let nullify = Nullify::new(self.proposal.view(), self.view_signature.clone());
1435 let finalize = Finalize::new(self.proposal.clone(), self.finalize_signature.clone());
1436 nullify.verify(namespace, public_key) && finalize.verify(namespace, public_key)
1437 }
1438}
1439
1440impl<S: CSignature, D: Digest> Write for NullifyFinalize<S, D> {
1441 fn write(&self, writer: &mut impl BufMut) {
1442 self.proposal.write(writer);
1443 self.view_signature.write(writer);
1444 self.finalize_signature.write(writer);
1445 }
1446}
1447
1448impl<S: CSignature, D: Digest> Read for NullifyFinalize<S, D> {
1449 type Cfg = ();
1450
1451 fn read_cfg(reader: &mut impl Buf, _: &()) -> Result<Self, Error> {
1452 let proposal = Proposal::<D>::read(reader)?;
1453 let view_signature = Signature::<S>::read(reader)?;
1454 let finalize_signature = Signature::<S>::read(reader)?;
1455 if view_signature.signer() != finalize_signature.signer() {
1456 return Err(Error::Invalid(
1457 "consensus::simplex::NullifyFinalize",
1458 "nullification and finalization must have the same public key",
1459 ));
1460 }
1461 Ok(Self {
1462 proposal,
1463 view_signature,
1464 finalize_signature,
1465 })
1466 }
1467}
1468
1469impl<S: CSignature, D: Digest> EncodeSize for NullifyFinalize<S, D> {
1470 fn encode_size(&self) -> usize {
1471 self.proposal.encode_size()
1472 + self.view_signature.encode_size()
1473 + self.finalize_signature.encode_size()
1474 }
1475}
1476
1477impl<S: CSignature, D: Digest> Viewable for NullifyFinalize<S, D> {
1478 type View = View;
1479
1480 fn view(&self) -> View {
1481 self.proposal.view()
1482 }
1483}
1484
1485impl<S: CSignature, D: Digest> Attributable for NullifyFinalize<S, D> {
1486 fn signer(&self) -> u32 {
1487 self.view_signature.signer()
1488 }
1489}
1490
1491#[cfg(test)]
1492mod tests {
1493 use super::*;
1494 use commonware_codec::{Decode, DecodeExt, Encode};
1495 use commonware_cryptography::{
1496 ed25519::{PrivateKey, PublicKey, Signature},
1497 sha256::Digest as Sha256Digest,
1498 PrivateKeyExt as _,
1499 };
1500
1501 const NAMESPACE: &[u8] = b"test";
1502
1503 fn sample_digest(v: u8) -> Sha256Digest {
1505 Sha256Digest::from([v; 32]) }
1507
1508 fn sample_scheme(v: u64) -> PrivateKey {
1509 PrivateKey::from_seed(v)
1510 }
1511
1512 #[test]
1513 fn test_proposal_encode_decode() {
1514 let proposal = Proposal::new(10, 5, sample_digest(1));
1515 let encoded = proposal.encode();
1516 let decoded = Proposal::<Sha256Digest>::decode(encoded).unwrap();
1517 assert_eq!(proposal, decoded);
1518 }
1519
1520 #[test]
1521 fn test_notarize_encode_decode() {
1522 let mut scheme = sample_scheme(0);
1523 let proposal = Proposal::new(10, 5, sample_digest(1));
1524 let notarize = Notarize::sign(NAMESPACE, &mut scheme, 0, proposal);
1525 let encoded = notarize.encode();
1526 let decoded = Notarize::<Signature, Sha256Digest>::decode(encoded).unwrap();
1527 assert_eq!(notarize, decoded);
1528 assert!(decoded.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1529 }
1530
1531 #[test]
1532 fn test_notarization_encode_decode() {
1533 let mut scheme_1 = sample_scheme(0);
1534 let mut scheme_2 = sample_scheme(1);
1535 let proposal = Proposal::new(10, 5, sample_digest(1));
1536 let notarize_1 = Notarize::sign(NAMESPACE, &mut scheme_1, 0, proposal.clone());
1537 let notarize_2 = Notarize::sign(NAMESPACE, &mut scheme_2, 1, proposal.clone());
1538 let signatures = vec![notarize_1.signature.clone(), notarize_2.signature.clone()];
1539 let notarization = Notarization::new(proposal.clone(), signatures.clone());
1540 let encoded = notarization.encode();
1541 let decoded =
1542 Notarization::<Signature, Sha256Digest>::decode_cfg(encoded, &usize::MAX).unwrap();
1543 assert_eq!(notarization, decoded);
1544 assert!(
1545 decoded.verify::<PublicKey>(NAMESPACE, &[scheme_1.public_key(), scheme_2.public_key()])
1546 );
1547 }
1548
1549 #[test]
1550 fn test_nullify_encode_decode() {
1551 let mut scheme = sample_scheme(0);
1552 let nullify = Nullify::sign(NAMESPACE, &mut scheme, 0, 10);
1553 let encoded = nullify.encode();
1554 let decoded = Nullify::<Signature>::decode(encoded).unwrap();
1555 assert_eq!(nullify, decoded);
1556 assert!(decoded.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1557 }
1558
1559 #[test]
1560 fn test_nullification_encode_decode() {
1561 let mut scheme_1 = sample_scheme(0);
1562 let mut scheme_2 = sample_scheme(1);
1563 let nullify_1 = Nullify::sign(NAMESPACE, &mut scheme_1, 0, 10);
1564 let nullify_2 = Nullify::sign(NAMESPACE, &mut scheme_2, 1, 10);
1565 let signatures = vec![nullify_1.signature.clone(), nullify_2.signature.clone()];
1566 let nullification = Nullification::new(10, signatures.clone());
1567 let encoded = nullification.encode();
1568 let decoded = Nullification::<Signature>::decode_cfg(encoded, &usize::MAX).unwrap();
1569 assert_eq!(nullification, decoded);
1570 assert!(
1571 decoded.verify::<PublicKey>(NAMESPACE, &[scheme_1.public_key(), scheme_2.public_key()])
1572 );
1573 }
1574
1575 #[test]
1576 fn test_finalize_encode_decode() {
1577 let mut scheme = sample_scheme(0);
1578 let proposal = Proposal::new(10, 5, sample_digest(1));
1579 let finalize = Finalize::sign(NAMESPACE, &mut scheme, 0, proposal);
1580 let encoded = finalize.encode();
1581 let decoded = Finalize::<Signature, Sha256Digest>::decode(encoded).unwrap();
1582 assert_eq!(finalize, decoded);
1583 }
1584
1585 #[test]
1586 fn test_finalization_encode_decode() {
1587 let mut scheme_1 = sample_scheme(0);
1588 let mut scheme_2 = sample_scheme(1);
1589 let proposal = Proposal::new(10, 5, sample_digest(1));
1590 let finalize_1 = Finalize::sign(NAMESPACE, &mut scheme_1, 0, proposal.clone());
1591 let finalize_2 = Finalize::sign(NAMESPACE, &mut scheme_2, 1, proposal.clone());
1592 let signatures = vec![finalize_1.signature.clone(), finalize_2.signature.clone()];
1593 let finalization = Finalization::new(proposal.clone(), signatures.clone());
1594 let encoded = finalization.encode();
1595 let decoded =
1596 Finalization::<Signature, Sha256Digest>::decode_cfg(encoded, &usize::MAX).unwrap();
1597 assert_eq!(finalization, decoded);
1598 assert!(
1599 decoded.verify::<PublicKey>(NAMESPACE, &[scheme_1.public_key(), scheme_2.public_key()])
1600 );
1601 }
1602
1603 #[test]
1604 fn test_backfiller_encode_decode() {
1605 let request = Request::new(1, vec![10, 11], vec![12, 13]);
1606 let backfiller = Backfiller::Request::<Signature, Sha256Digest>(request.clone());
1607 let encoded = backfiller.encode();
1608 let decoded =
1609 Backfiller::<Signature, Sha256Digest>::decode_cfg(encoded, &(usize::MAX, usize::MAX))
1610 .unwrap();
1611 assert!(matches!(decoded, Backfiller::Request(r) if r == request));
1612 }
1613
1614 #[test]
1615 fn test_request_encode_decode() {
1616 let request = Request::new(1, vec![10, 11], vec![12, 13]);
1617 let encoded = request.encode();
1618 let decoded = Request::decode_cfg(encoded, &usize::MAX).unwrap();
1619 assert_eq!(request, decoded);
1620 }
1621
1622 #[test]
1623 fn test_response_encode_decode() {
1624 let mut scheme = sample_scheme(0);
1625 let proposal = Proposal::new(10, 5, sample_digest(1));
1626 let notarize = Notarize::sign(NAMESPACE, &mut scheme, 0, proposal.clone());
1627 let notarization = Notarization::new(proposal.clone(), vec![notarize.signature.clone()]);
1628 let response = Response::new(1, vec![notarization], vec![]);
1629 let encoded = response.encode();
1630 let decoded =
1631 Response::<Signature, Sha256Digest>::decode_cfg(encoded, &(usize::MAX, usize::MAX))
1632 .unwrap();
1633 assert_eq!(response, decoded);
1634 }
1635
1636 #[test]
1637 fn test_conflicting_notarize_encode_decode() {
1638 let mut scheme = sample_scheme(0);
1639 let proposal1 = Proposal::new(10, 5, sample_digest(1));
1640 let proposal2 = Proposal::new(10, 6, sample_digest(2));
1641 let notarize1 = Notarize::sign(NAMESPACE, &mut scheme, 0, proposal1.clone());
1642 let notarize2 = Notarize::sign(NAMESPACE, &mut scheme, 0, proposal2.clone());
1643 let conflicting = ConflictingNotarize::new(notarize1, notarize2);
1644 let encoded = conflicting.encode();
1645 let decoded = ConflictingNotarize::<Signature, Sha256Digest>::decode(encoded).unwrap();
1646 assert_eq!(conflicting, decoded);
1647 assert!(conflicting.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1648 }
1649
1650 #[test]
1651 fn test_conflicting_finalize_encode_decode() {
1652 let mut scheme = sample_scheme(0);
1653 let proposal1 = Proposal::new(10, 5, sample_digest(1));
1654 let proposal2 = Proposal::new(10, 6, sample_digest(2));
1655 let finalize1 = Finalize::sign(NAMESPACE, &mut scheme, 0, proposal1.clone());
1656 let finalize2 = Finalize::sign(NAMESPACE, &mut scheme, 0, proposal2.clone());
1657 let conflicting = ConflictingFinalize::new(finalize1, finalize2);
1658 let encoded = conflicting.encode();
1659 let decoded = ConflictingFinalize::<Signature, Sha256Digest>::decode(encoded).unwrap();
1660 assert_eq!(conflicting, decoded);
1661 assert!(conflicting.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1662 }
1663
1664 #[test]
1665 fn test_nullify_finalize_encode_decode() {
1666 let mut scheme = sample_scheme(0);
1667 let proposal = Proposal::new(10, 5, sample_digest(1));
1668 let nullify = Nullify::sign(NAMESPACE, &mut scheme, 1, 10);
1669 let finalize = Finalize::sign(NAMESPACE, &mut scheme, 1, proposal.clone());
1670 let nullify_finalize = NullifyFinalize::new(nullify, finalize);
1671 let encoded = nullify_finalize.encode();
1672 let decoded = NullifyFinalize::<Signature, Sha256Digest>::decode(encoded).unwrap();
1673 assert_eq!(nullify_finalize, decoded);
1674 assert!(nullify_finalize.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1675 }
1676
1677 #[test]
1678 fn test_notarize_verify_wrong_namespace() {
1679 let mut scheme = sample_scheme(0);
1680 let proposal = Proposal::new(10, 5, sample_digest(1));
1681 let notarize = Notarize::sign(NAMESPACE, &mut scheme, 0, proposal);
1682
1683 assert!(!notarize.verify::<PublicKey>(b"wrong_namespace", &scheme.public_key()));
1685 }
1686
1687 #[test]
1688 fn test_notarize_verify_wrong_public_key() {
1689 let mut scheme1 = sample_scheme(0);
1690 let scheme2 = sample_scheme(1); let proposal = Proposal::new(10, 5, sample_digest(1));
1692 let notarize = Notarize::sign(NAMESPACE, &mut scheme1, 0, proposal);
1693
1694 assert!(!notarize.verify::<PublicKey>(NAMESPACE, &scheme2.public_key()));
1696 }
1697
1698 #[test]
1699 fn test_notarization_verify_insufficient_signatures() {
1700 let mut scheme_1 = sample_scheme(0);
1701 let mut scheme_2 = sample_scheme(1);
1702 let proposal = Proposal::new(10, 5, sample_digest(1));
1703 let notarize_1 = Notarize::sign(NAMESPACE, &mut scheme_1, 0, proposal.clone());
1704 let notarize_2 = Notarize::sign(NAMESPACE, &mut scheme_2, 1, proposal.clone());
1705
1706 let signatures = vec![notarize_1.signature.clone(), notarize_2.signature.clone()];
1708 let notarization = Notarization::new(proposal.clone(), signatures);
1709
1710 let validators = vec![
1712 scheme_1.public_key(),
1713 scheme_2.public_key(),
1714 sample_scheme(2).public_key(),
1715 sample_scheme(3).public_key(),
1716 ];
1717
1718 assert!(!notarization.verify::<PublicKey>(NAMESPACE, &validators));
1720 }
1721
1722 #[test]
1723 fn test_notarization_verify_invalid_validator_index() {
1724 let mut scheme_1 = sample_scheme(0);
1725 let scheme_2 = sample_scheme(1);
1726 let proposal = Proposal::new(10, 5, sample_digest(1));
1727
1728 let notarize_1 = Notarize::sign(NAMESPACE, &mut scheme_1, 0, proposal.clone());
1730 let invalid_sig =
1731 super::Signature::new(3, scheme_2.sign(Some(NAMESPACE), &proposal.encode()));
1732
1733 let signatures = vec![notarize_1.signature.clone(), invalid_sig];
1735 let notarization = Notarization::new(proposal.clone(), signatures);
1736
1737 let validators = vec![scheme_1.public_key(), scheme_2.public_key()];
1739
1740 assert!(!notarization.verify::<PublicKey>(NAMESPACE, &validators));
1742 }
1743
1744 #[test]
1745 fn test_conflicting_notarize_detection() {
1746 let mut scheme = sample_scheme(0);
1747
1748 let proposal1 = Proposal::new(10, 5, sample_digest(1));
1750 let proposal2 = Proposal::new(10, 6, sample_digest(2)); let notarize1 = Notarize::sign(NAMESPACE, &mut scheme, 0, proposal1.clone());
1754 let notarize2 = Notarize::sign(NAMESPACE, &mut scheme, 0, proposal2.clone());
1755
1756 let conflict = ConflictingNotarize::new(notarize1, notarize2);
1758
1759 assert!(conflict.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1761
1762 let mut scheme2 = sample_scheme(1);
1764 let invalid_notarize = Notarize::sign(NAMESPACE, &mut scheme2, 1, proposal1.clone());
1765
1766 let (_, n2) = conflict.notarizes();
1768 let invalid_conflict = ConflictingNotarize {
1769 view: n2.view(),
1770 parent_1: n2.proposal.parent,
1771 payload_1: n2.proposal.payload,
1772 signature_1: n2.signature,
1773 parent_2: invalid_notarize.proposal.parent,
1774 payload_2: invalid_notarize.proposal.payload,
1775 signature_2: invalid_notarize.signature,
1776 };
1777
1778 assert!(!invalid_conflict.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1780 assert!(!invalid_conflict.verify::<PublicKey>(NAMESPACE, &scheme2.public_key()));
1781 }
1782
1783 #[test]
1784 fn test_nullify_finalize_detection() {
1785 let mut scheme = sample_scheme(0);
1786 let view = 10;
1787
1788 let nullify = Nullify::sign(NAMESPACE, &mut scheme, 0, view);
1790
1791 let proposal = Proposal::new(view, 5, sample_digest(1));
1793 let finalize = Finalize::sign(NAMESPACE, &mut scheme, 0, proposal.clone());
1794
1795 let conflict = NullifyFinalize::new(nullify, finalize);
1797
1798 assert!(conflict.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1800
1801 let mut scheme2 = sample_scheme(1);
1803 let nullify2 = Nullify::sign(NAMESPACE, &mut scheme2, 1, view);
1804 let finalize2 = Finalize::sign(NAMESPACE, &mut scheme2, 1, proposal);
1805
1806 let conflict2 = NullifyFinalize::new(nullify2, finalize2);
1808 assert!(!conflict2.verify::<PublicKey>(NAMESPACE, &scheme.public_key()));
1809 }
1811
1812 #[test]
1813 fn test_nullification_invalid_signatures() {
1814 let mut scheme_1 = sample_scheme(0);
1815 let mut scheme_2 = sample_scheme(1);
1816
1817 let nullify_1 = Nullify::sign(NAMESPACE, &mut scheme_1, 0, 10);
1819 let nullify_2 = Nullify::sign(NAMESPACE, &mut scheme_2, 1, 10);
1820
1821 let signatures = vec![nullify_1.signature.clone(), nullify_2.signature.clone()];
1823 let nullification = Nullification::new(10, signatures);
1824
1825 let validators = vec![scheme_1.public_key(), scheme_2.public_key()];
1827
1828 assert!(nullification.verify::<PublicKey>(NAMESPACE, &validators));
1830
1831 let tampered_sig =
1833 super::Signature::new(2, scheme_1.sign(Some(NAMESPACE), &nullify_1.encode()));
1834
1835 let invalid_signatures = vec![nullify_1.signature.clone(), tampered_sig];
1836 let invalid_nullification = Nullification::new(10, invalid_signatures);
1837
1838 assert!(!invalid_nullification.verify::<PublicKey>(NAMESPACE, &validators));
1840 }
1841}