1use std::{
10 borrow::Borrow,
11 fmt::Debug,
12 hash::Hash,
13 marker::PhantomData,
14 ops::{Deref, DerefMut},
15};
16
17use alloy_primitives::FixedBytes;
18use committable::{Commitment, Committable};
19use hotshot_utils::anytrace::*;
20use jf_utils::canonical;
21use serde::{Deserialize, Serialize};
22use vbs::version::Version;
23
24use crate::{
25 data::{EpochNumber, Leaf, Leaf2, VidCommitment, ViewNumber},
26 light_client::{CircuitField, LightClientState, StakeTableState},
27 message::UpgradeLock,
28 traits::{
29 node_implementation::NodeType,
30 signature_key::{SignatureKey, StateSignatureKey},
31 },
32 utils::epoch_from_block_number,
33 vote::{HasViewNumber, Vote},
34};
35
36pub trait QuorumMarker {}
38
39#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
41#[serde(bound(deserialize = ""))]
42pub struct QuorumData<TYPES: NodeType> {
43 pub leaf_commit: Commitment<Leaf<TYPES>>,
45}
46
47#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Hash, Eq)]
49#[serde(bound(deserialize = ""))]
50pub struct QuorumData2<TYPES: NodeType> {
51 pub leaf_commit: Commitment<Leaf2<TYPES>>,
53 pub epoch: Option<EpochNumber>,
55 pub block_number: Option<u64>,
57}
58
59impl<T: NodeType> QuorumData2<T> {
60 pub fn is_well_formed(&self, epoch_height: u64) -> bool {
61 let Some(epoch) = self.epoch else {
62 return false;
63 };
64 let Some(block) = self.block_number else {
65 return false;
66 };
67 epoch == epoch_from_block_number(block, epoch_height).into()
68 }
69}
70
71#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
73#[serde(bound(deserialize = ""))]
74pub struct NextEpochQuorumData2<TYPES: NodeType>(QuorumData2<TYPES>);
75
76#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
78pub struct DaData {
79 pub payload_commit: VidCommitment,
81}
82
83#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
85pub struct DaData2 {
86 pub payload_commit: VidCommitment,
88 pub next_epoch_payload_commit: Option<VidCommitment>,
90 pub epoch: Option<EpochNumber>,
92}
93
94#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
96pub struct TimeoutData {
97 pub view: ViewNumber,
99}
100
101#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
103pub struct TimeoutData2 {
104 pub view: ViewNumber,
106 pub epoch: Option<EpochNumber>,
108}
109
110#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
113pub struct TimeoutData3 {
114 pub view: ViewNumber,
116 pub epoch: EpochNumber,
118 pub lock: Option<LockView>,
120}
121
122#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
127pub struct LockView {
128 pub epoch: EpochNumber,
130 pub view: ViewNumber,
131}
132
133impl LockView {
134 pub fn of<T: NodeType>(cert: &crate::simple_certificate::QuorumCertificate2<T>) -> Self {
136 Self {
137 epoch: cert.data.epoch.unwrap_or_else(EpochNumber::genesis),
138 view: cert.view_number(),
139 }
140 }
141}
142
143#[derive(Debug)]
154pub enum TimeoutLock<'a, T: NodeType> {
155 None,
157 Stale(LockView),
159 Recent(&'a crate::simple_certificate::QuorumCertificate2<T>),
162}
163
164impl<'a, T: NodeType> TimeoutLock<'a, T> {
165 pub fn of(
166 cert: Option<&'a crate::simple_certificate::QuorumCertificate2<T>>,
167 epoch: EpochNumber,
168 ) -> Self {
169 let Some(cert) = cert else {
170 return Self::None;
171 };
172 let lock = LockView::of(cert);
173 if lock.epoch.saturating_add(1) >= *epoch {
174 Self::Recent(cert)
175 } else {
176 Self::Stale(lock)
177 }
178 }
179
180 pub fn recent(self) -> Option<&'a crate::simple_certificate::QuorumCertificate2<T>> {
182 match self {
183 Self::Recent(cert) => Some(cert),
184 Self::None | Self::Stale(_) => None,
185 }
186 }
187
188 pub fn verified_in(self) -> Option<EpochNumber> {
190 self.recent().map(|cert| LockView::of(cert).epoch)
191 }
192}
193
194impl std::fmt::Display for LockView {
195 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
196 write!(f, "{}@{}", self.epoch, self.view)
197 }
198}
199
200#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
202pub struct ViewSyncPreCommitData {
203 pub relay: u64,
205 pub round: ViewNumber,
207}
208
209#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
211pub struct ViewSyncPreCommitData2 {
212 pub relay: u64,
214 pub round: ViewNumber,
216 pub epoch: Option<EpochNumber>,
218}
219
220#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
222pub struct ViewSyncCommitData {
223 pub relay: u64,
225 pub round: ViewNumber,
227}
228
229#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
231pub struct ViewSyncCommitData2 {
232 pub relay: u64,
234 pub round: ViewNumber,
236 pub epoch: Option<EpochNumber>,
238}
239
240#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
242pub struct ViewSyncFinalizeData {
243 pub relay: u64,
245 pub round: ViewNumber,
247}
248
249#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
251pub struct ViewSyncFinalizeData2 {
252 pub relay: u64,
254 pub round: ViewNumber,
256 pub epoch: Option<EpochNumber>,
258}
259
260#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
262pub struct UpgradeProposalData {
263 pub old_version: Version,
265 pub new_version: Version,
267 pub decide_by: ViewNumber,
270 #[serde(with = "serde_bytes")]
272 pub new_version_hash: Vec<u8>,
273 pub old_version_last_view: ViewNumber,
275 pub new_version_first_view: ViewNumber,
277}
278
279#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
281pub struct UpgradeProposalData2 {
282 pub old_version: Version,
284 pub new_version: Version,
286 pub decide_by: ViewNumber,
289 #[serde(with = "serde_bytes")]
291 pub new_version_hash: Vec<u8>,
292 pub old_version_last_view: ViewNumber,
294 pub new_version_first_view: ViewNumber,
296 pub epoch: EpochNumber,
298}
299
300impl UpgradeProposalData2 {
301 pub fn strip_epoch(self) -> UpgradeProposalData {
303 UpgradeProposalData {
304 old_version: self.old_version,
305 new_version: self.new_version,
306 decide_by: self.decide_by,
307 new_version_hash: self.new_version_hash,
308 old_version_last_view: self.old_version_last_view,
309 new_version_first_view: self.new_version_first_view,
310 }
311 }
312
313 pub fn restore_epoch(data: UpgradeProposalData, epoch: EpochNumber) -> Self {
315 Self {
316 old_version: data.old_version,
317 new_version: data.new_version,
318 decide_by: data.decide_by,
319 new_version_hash: data.new_version_hash,
320 old_version_last_view: data.old_version_last_view,
321 new_version_first_view: data.new_version_first_view,
322 epoch,
323 }
324 }
325}
326
327#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
329#[serde(bound(deserialize = ""))]
330pub struct Vote2Data<T: NodeType> {
331 pub leaf_commit: Commitment<Leaf2<T>>,
332 pub epoch: EpochNumber,
333 pub block_number: u64,
334}
335
336impl<T: NodeType> QuorumMarker for Vote2Data<T> {}
337
338impl<T: NodeType> Vote2Data<T> {
339 pub fn is_well_formed(&self, epoch_height: u64) -> bool {
340 self.epoch == epoch_from_block_number(self.block_number, epoch_height).into()
341 }
342}
343
344impl<T: NodeType> HasEpoch for Vote2Data<T> {
345 fn epoch(&self) -> Option<EpochNumber> {
346 Some(self.epoch)
347 }
348}
349
350impl<T: NodeType> Committable for Vote2Data<T> {
351 fn commit(&self) -> Commitment<Self> {
352 committable::RawCommitmentBuilder::new("Vote2Data")
353 .var_size_bytes(self.leaf_commit.as_ref())
354 .u64(*self.epoch)
355 .u64(self.block_number)
356 .constant_str("Vote2")
357 .finalize()
358 }
359}
360
361pub trait Voteable<TYPES: NodeType>:
365 sealed::Sealed + Committable + Clone + Serialize + Debug + PartialEq + Hash + Eq
366{
367}
368
369pub trait Voteable2<TYPES: NodeType>:
373 sealed::Sealed + HasEpoch + Committable + Clone + Serialize + Debug + PartialEq + Hash + Eq
374{
375}
376
377mod sealed {
381 use committable::Committable;
382
383 pub trait Sealed {}
385
386 impl<C: Committable> Sealed for C {}
388}
389
390impl<T: NodeType> QuorumMarker for QuorumData<T> {}
391impl<T: NodeType> QuorumMarker for QuorumData2<T> {}
392impl<T: NodeType> QuorumMarker for NextEpochQuorumData2<T> {}
393impl QuorumMarker for TimeoutData {}
394impl QuorumMarker for TimeoutData2 {}
395impl QuorumMarker for TimeoutData3 {}
396impl QuorumMarker for ViewSyncPreCommitData {}
397impl QuorumMarker for ViewSyncCommitData {}
398impl QuorumMarker for ViewSyncFinalizeData {}
399impl QuorumMarker for ViewSyncPreCommitData2 {}
400impl QuorumMarker for ViewSyncCommitData2 {}
401impl QuorumMarker for ViewSyncFinalizeData2 {}
402impl QuorumMarker for UpgradeProposalData {}
403impl QuorumMarker for UpgradeProposalData2 {}
404
405#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
407pub struct SimpleVote<TYPES: NodeType, DATA: Voteable<TYPES>> {
408 pub signature: (
410 TYPES::SignatureKey,
411 <TYPES::SignatureKey as SignatureKey>::PureAssembledSignatureType,
412 ),
413 pub data: DATA,
415 pub view_number: ViewNumber,
417}
418
419impl<TYPES: NodeType, DATA: Voteable<TYPES> + 'static> HasViewNumber for SimpleVote<TYPES, DATA> {
420 fn view_number(&self) -> ViewNumber {
421 self.view_number
422 }
423}
424
425impl<TYPES: NodeType, DATA: Voteable<TYPES> + 'static> Vote<TYPES> for SimpleVote<TYPES, DATA> {
426 type Commitment = DATA;
427
428 fn signing_key(&self) -> <TYPES as NodeType>::SignatureKey {
429 self.signature.0.clone()
430 }
431
432 fn signature(&self) -> <TYPES::SignatureKey as SignatureKey>::PureAssembledSignatureType {
433 self.signature.1.clone()
434 }
435
436 fn date(&self) -> &DATA {
437 &self.data
438 }
439
440 fn data_commitment(&self) -> Commitment<DATA> {
441 self.data.commit()
442 }
443}
444
445impl<TYPES: NodeType, DATA: Voteable<TYPES> + 'static> SimpleVote<TYPES, DATA> {
446 pub fn create_signed_vote(
450 data: DATA,
451 view: ViewNumber,
452 pub_key: &TYPES::SignatureKey,
453 private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
454 upgrade_lock: &UpgradeLock<TYPES>,
455 ) -> Result<Self> {
456 let commit = VersionedVoteData::new(data.clone(), view, upgrade_lock)?.commit();
457
458 let signature = (
459 pub_key.clone(),
460 TYPES::SignatureKey::sign(private_key, commit.as_ref())
461 .wrap()
462 .context(error!("Failed to sign vote"))?,
463 );
464
465 Ok(Self {
466 signature,
467 data,
468 view_number: view,
469 })
470 }
471}
472
473#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
474pub struct VersionedVoteData<TYPES: NodeType, DATA: Voteable<TYPES>> {
476 data: DATA,
478
479 view: ViewNumber,
481
482 version: Version,
484
485 _pd: PhantomData<TYPES>,
487}
488
489impl<TYPES: NodeType, DATA: Voteable<TYPES>> VersionedVoteData<TYPES, DATA> {
490 pub fn new(data: DATA, view: ViewNumber, upgrade_lock: &UpgradeLock<TYPES>) -> Result<Self> {
496 let version = upgrade_lock.version(view)?;
497
498 Ok(Self {
499 data,
500 view,
501 version,
502 _pd: PhantomData,
503 })
504 }
505
506 pub fn new_infallible(data: DATA, view: ViewNumber, upgrade_lock: &UpgradeLock<TYPES>) -> Self {
510 let version = upgrade_lock.version_infallible(view);
511
512 Self {
513 data,
514 view,
515 version,
516 _pd: PhantomData,
517 }
518 }
519}
520
521impl<TYPES: NodeType, DATA: Voteable<TYPES>> Committable for VersionedVoteData<TYPES, DATA> {
522 fn commit(&self) -> Commitment<Self> {
523 committable::RawCommitmentBuilder::new("Vote")
524 .var_size_bytes(self.data.commit().as_ref())
525 .u64(*self.view)
526 .finalize()
527 }
528}
529
530impl<TYPES: NodeType> Committable for QuorumData<TYPES> {
531 fn commit(&self) -> Commitment<Self> {
532 committable::RawCommitmentBuilder::new("Quorum data")
533 .var_size_bytes(self.leaf_commit.as_ref())
534 .finalize()
535 }
536}
537
538impl<TYPES: NodeType> Committable for QuorumData2<TYPES> {
539 fn commit(&self) -> Commitment<Self> {
540 let QuorumData2 {
541 leaf_commit,
542 epoch,
543 block_number,
544 } = self;
545
546 let mut cb = committable::RawCommitmentBuilder::new("Quorum data")
547 .var_size_bytes(leaf_commit.as_ref());
548
549 if let Some(ref epoch) = *epoch {
550 cb = cb.u64_field("epoch number", **epoch);
551 }
552
553 if let Some(ref block_number) = *block_number {
554 cb = cb.u64_field("block number", *block_number);
555 }
556
557 cb.finalize()
558 }
559}
560
561impl<TYPES: NodeType> Committable for NextEpochQuorumData2<TYPES> {
562 fn commit(&self) -> Commitment<Self> {
563 let NextEpochQuorumData2(QuorumData2 {
564 leaf_commit,
565 epoch,
566 block_number,
567 }) = self;
568
569 let mut cb = committable::RawCommitmentBuilder::new("Quorum data")
570 .var_size_bytes(leaf_commit.as_ref());
571
572 if let Some(ref epoch) = *epoch {
573 cb = cb.u64_field("epoch number", **epoch);
574 }
575
576 if let Some(ref block_number) = *block_number {
577 cb = cb.u64_field("block number", *block_number);
578 }
579
580 cb.finalize()
581 }
582}
583
584impl Committable for TimeoutData {
585 fn commit(&self) -> Commitment<Self> {
586 committable::RawCommitmentBuilder::new("Timeout data")
587 .u64(*self.view)
588 .finalize()
589 }
590}
591
592impl Committable for TimeoutData2 {
593 fn commit(&self) -> Commitment<Self> {
594 let TimeoutData2 { view, epoch: _ } = self;
595
596 committable::RawCommitmentBuilder::new("Timeout data")
597 .u64(**view)
598 .finalize()
599 }
600}
601
602impl Committable for TimeoutData3 {
603 fn commit(&self) -> Commitment<Self> {
604 let TimeoutData3 { view, epoch, lock } = self;
605
606 let builder = committable::RawCommitmentBuilder::new("Timeout data v3")
607 .u64_field("view number", **view)
608 .u64_field("epoch number", **epoch);
609 match lock {
610 None => builder.u64_field("lock", 0),
611 Some(lock) => builder
612 .u64_field("lock", 1)
613 .u64_field("lock epoch", *lock.epoch)
614 .u64_field("lock view", *lock.view),
615 }
616 .finalize()
617 }
618}
619
620impl Committable for DaData {
621 fn commit(&self) -> Commitment<Self> {
622 committable::RawCommitmentBuilder::new("DA data")
623 .var_size_bytes(self.payload_commit.as_ref())
624 .finalize()
625 }
626}
627
628impl Committable for DaData2 {
629 fn commit(&self) -> Commitment<Self> {
630 let DaData2 {
631 payload_commit,
632 next_epoch_payload_commit,
633 epoch,
634 } = self;
635
636 let mut cb = committable::RawCommitmentBuilder::new("DA data")
637 .var_size_bytes(payload_commit.as_ref());
638
639 if let Some(ref next_epoch_payload_commit) = *next_epoch_payload_commit {
640 cb = cb.var_size_bytes(next_epoch_payload_commit.as_ref());
641 }
642
643 if let Some(ref epoch) = *epoch {
644 cb = cb.u64_field("epoch number", **epoch);
645 }
646
647 cb.finalize()
648 }
649}
650
651impl Committable for UpgradeProposalData {
652 fn commit(&self) -> Commitment<Self> {
653 let builder = committable::RawCommitmentBuilder::new("Upgrade data");
654 builder
655 .u64(*self.decide_by)
656 .u64(*self.new_version_first_view)
657 .u64(*self.old_version_last_view)
658 .var_size_bytes(self.new_version_hash.as_slice())
659 .u16(self.new_version.minor)
660 .u16(self.new_version.major)
661 .u16(self.old_version.minor)
662 .u16(self.old_version.major)
663 .finalize()
664 }
665}
666
667impl Committable for UpgradeProposalData2 {
668 fn commit(&self) -> Commitment<Self> {
669 let builder = committable::RawCommitmentBuilder::new("Upgrade data v2");
670 builder
671 .u64(*self.decide_by)
672 .u64(*self.new_version_first_view)
673 .u64(*self.old_version_last_view)
674 .var_size_bytes(self.new_version_hash.as_slice())
675 .u16(self.new_version.minor)
676 .u16(self.new_version.major)
677 .u16(self.old_version.minor)
678 .u16(self.old_version.major)
679 .u64_field("epoch number", *self.epoch)
680 .finalize()
681 }
682}
683
684fn view_and_relay_commit<T: Committable>(
686 view: ViewNumber,
687 relay: u64,
688 epoch: Option<EpochNumber>,
689 tag: &str,
690) -> Commitment<T> {
691 let builder = committable::RawCommitmentBuilder::new(tag);
692 let mut cb = builder.u64(*view).u64(relay);
693
694 if let Some(epoch) = epoch {
695 cb = cb.u64_field("epoch number", *epoch);
696 }
697
698 cb.finalize()
699}
700
701impl Committable for ViewSyncPreCommitData {
702 fn commit(&self) -> Commitment<Self> {
703 view_and_relay_commit(self.round, self.relay, None, "View Sync Precommit")
704 }
705}
706
707impl Committable for ViewSyncPreCommitData2 {
708 fn commit(&self) -> Commitment<Self> {
709 let ViewSyncPreCommitData2 {
710 relay,
711 round,
712 epoch,
713 } = self;
714
715 view_and_relay_commit(*round, *relay, *epoch, "View Sync Precommit")
716 }
717}
718
719impl Committable for ViewSyncFinalizeData {
720 fn commit(&self) -> Commitment<Self> {
721 view_and_relay_commit(self.round, self.relay, None, "View Sync Finalize")
722 }
723}
724
725impl Committable for ViewSyncFinalizeData2 {
726 fn commit(&self) -> Commitment<Self> {
727 let ViewSyncFinalizeData2 {
728 relay,
729 round,
730 epoch,
731 } = self;
732
733 view_and_relay_commit(*round, *relay, *epoch, "View Sync Finalize")
734 }
735}
736
737impl Committable for ViewSyncCommitData {
738 fn commit(&self) -> Commitment<Self> {
739 view_and_relay_commit(self.round, self.relay, None, "View Sync Commit")
740 }
741}
742
743impl Committable for ViewSyncCommitData2 {
744 fn commit(&self) -> Commitment<Self> {
745 let ViewSyncCommitData2 {
746 relay,
747 round,
748 epoch,
749 } = self;
750
751 view_and_relay_commit(*round, *relay, *epoch, "View Sync Commit")
752 }
753}
754
755pub trait HasEpoch {
757 fn epoch(&self) -> Option<EpochNumber>;
759}
760
761#[macro_export]
763macro_rules! impl_has_epoch {
764 ($($t:ty),*) => {
765 $(
766 impl HasEpoch for $t {
767 fn epoch(&self) -> Option<EpochNumber> {
768 self.epoch
769 }
770 }
771 )*
772 };
773}
774
775impl<NODE: NodeType> HasEpoch for QuorumData2<NODE> {
776 fn epoch(&self) -> Option<EpochNumber> {
777 self.epoch
778 }
779}
780
781impl<NODE: NodeType> HasEpoch for NextEpochQuorumData2<NODE> {
782 fn epoch(&self) -> Option<EpochNumber> {
783 self.0.epoch
784 }
785}
786
787impl HasEpoch for TimeoutData3 {
788 fn epoch(&self) -> Option<EpochNumber> {
789 Some(self.epoch)
790 }
791}
792
793impl HasEpoch for UpgradeProposalData2 {
794 fn epoch(&self) -> Option<EpochNumber> {
795 Some(self.epoch)
796 }
797}
798
799impl_has_epoch!(
800 DaData2,
801 TimeoutData2,
802 ViewSyncPreCommitData2,
803 ViewSyncCommitData2,
804 ViewSyncFinalizeData2
805);
806
807#[macro_export]
809macro_rules! impl_has_none_epoch {
810 ($($t:ty),*) => {
811 $(
812 impl HasEpoch for $t {
813 fn epoch(&self) -> Option<EpochNumber> {
814 None
815 }
816 }
817 )*
818 };
819}
820
821impl<NODE: NodeType> HasEpoch for QuorumData<NODE> {
822 fn epoch(&self) -> Option<EpochNumber> {
823 None
824 }
825}
826
827impl_has_none_epoch!(
828 DaData,
829 TimeoutData,
830 ViewSyncPreCommitData,
831 ViewSyncCommitData,
832 ViewSyncFinalizeData,
833 UpgradeProposalData
834);
835
836impl<TYPES: NodeType, DATA: Voteable<TYPES> + HasEpoch> HasEpoch for SimpleVote<TYPES, DATA> {
837 fn epoch(&self) -> Option<EpochNumber> {
838 self.data.epoch()
839 }
840}
841
842impl<
845 TYPES: NodeType,
846 V: sealed::Sealed + Committable + Clone + Serialize + Debug + PartialEq + Hash + Eq,
847> Voteable<TYPES> for V
848{
849}
850
851impl<
854 TYPES: NodeType,
855 V: sealed::Sealed + HasEpoch + Committable + Clone + Serialize + Debug + PartialEq + Hash + Eq,
856> Voteable2<TYPES> for V
857{
858}
859
860impl<TYPES: NodeType> QuorumVote<TYPES> {
861 pub fn to_vote2(self) -> QuorumVote2<TYPES> {
863 let bytes: [u8; 32] = self.data.leaf_commit.into();
864
865 let signature = self.signature;
866 let data = QuorumData2 {
867 leaf_commit: Commitment::from_raw(bytes),
868 epoch: None,
869 block_number: None,
870 };
871 let view_number = self.view_number;
872
873 SimpleVote {
874 signature,
875 data,
876 view_number,
877 }
878 }
879}
880
881impl<TYPES: NodeType> QuorumVote2<TYPES> {
882 pub fn to_vote(self) -> QuorumVote<TYPES> {
884 let bytes: [u8; 32] = self.data.leaf_commit.into();
885
886 let signature = self.signature.clone();
887 let data = QuorumData {
888 leaf_commit: Commitment::from_raw(bytes),
889 };
890 let view_number = self.view_number;
891
892 SimpleVote {
893 signature,
894 data,
895 view_number,
896 }
897 }
898}
899
900impl<TYPES: NodeType> DaVote<TYPES> {
901 pub fn to_vote2(self) -> DaVote2<TYPES> {
903 let signature = self.signature;
904 let data = DaData2 {
905 payload_commit: self.data.payload_commit,
906 next_epoch_payload_commit: None,
907 epoch: None,
908 };
909 let view_number = self.view_number;
910
911 SimpleVote {
912 signature,
913 data,
914 view_number,
915 }
916 }
917}
918
919impl<TYPES: NodeType> DaVote2<TYPES> {
920 pub fn to_vote(self) -> DaVote<TYPES> {
922 let signature = self.signature;
923 let data = DaData {
924 payload_commit: self.data.payload_commit,
925 };
926 let view_number = self.view_number;
927
928 SimpleVote {
929 signature,
930 data,
931 view_number,
932 }
933 }
934}
935
936impl<TYPES: NodeType> TimeoutVote<TYPES> {
937 pub fn to_vote2(self) -> TimeoutVote2<TYPES> {
939 let signature = self.signature;
940 let data = TimeoutData2 {
941 view: self.data.view,
942 epoch: None,
943 };
944 let view_number = self.view_number;
945
946 SimpleVote {
947 signature,
948 data,
949 view_number,
950 }
951 }
952}
953
954impl<TYPES: NodeType> TimeoutVote2<TYPES> {
955 pub fn to_vote(self) -> TimeoutVote<TYPES> {
957 let signature = self.signature;
958 let data = TimeoutData {
959 view: self.data.view,
960 };
961 let view_number = self.view_number;
962
963 SimpleVote {
964 signature,
965 data,
966 view_number,
967 }
968 }
969}
970
971impl<TYPES: NodeType> ViewSyncPreCommitVote<TYPES> {
972 pub fn to_vote2(self) -> ViewSyncPreCommitVote2<TYPES> {
974 let signature = self.signature;
975 let data = ViewSyncPreCommitData2 {
976 relay: self.data.relay,
977 round: self.data.round,
978 epoch: None,
979 };
980 let view_number = self.view_number;
981
982 SimpleVote {
983 signature,
984 data,
985 view_number,
986 }
987 }
988}
989
990impl<TYPES: NodeType> ViewSyncPreCommitVote2<TYPES> {
991 pub fn to_vote(self) -> ViewSyncPreCommitVote<TYPES> {
993 let signature = self.signature;
994 let data = ViewSyncPreCommitData {
995 relay: self.data.relay,
996 round: self.data.round,
997 };
998 let view_number = self.view_number;
999
1000 SimpleVote {
1001 signature,
1002 data,
1003 view_number,
1004 }
1005 }
1006}
1007
1008impl<TYPES: NodeType> ViewSyncCommitVote<TYPES> {
1009 pub fn to_vote2(self) -> ViewSyncCommitVote2<TYPES> {
1011 let signature = self.signature;
1012 let data = ViewSyncCommitData2 {
1013 relay: self.data.relay,
1014 round: self.data.round,
1015 epoch: None,
1016 };
1017 let view_number = self.view_number;
1018
1019 SimpleVote {
1020 signature,
1021 data,
1022 view_number,
1023 }
1024 }
1025}
1026
1027impl<TYPES: NodeType> ViewSyncCommitVote2<TYPES> {
1028 pub fn to_vote(self) -> ViewSyncCommitVote<TYPES> {
1030 let signature = self.signature;
1031 let data = ViewSyncCommitData {
1032 relay: self.data.relay,
1033 round: self.data.round,
1034 };
1035 let view_number = self.view_number;
1036
1037 SimpleVote {
1038 signature,
1039 data,
1040 view_number,
1041 }
1042 }
1043}
1044
1045impl<TYPES: NodeType> ViewSyncFinalizeVote<TYPES> {
1046 pub fn to_vote2(self) -> ViewSyncFinalizeVote2<TYPES> {
1048 let signature = self.signature;
1049 let data = ViewSyncFinalizeData2 {
1050 relay: self.data.relay,
1051 round: self.data.round,
1052 epoch: None,
1053 };
1054 let view_number = self.view_number;
1055
1056 SimpleVote {
1057 signature,
1058 data,
1059 view_number,
1060 }
1061 }
1062}
1063
1064impl<TYPES: NodeType> ViewSyncFinalizeVote2<TYPES> {
1065 pub fn to_vote(self) -> ViewSyncFinalizeVote<TYPES> {
1067 let signature = self.signature;
1068 let data = ViewSyncFinalizeData {
1069 relay: self.data.relay,
1070 round: self.data.round,
1071 };
1072 let view_number = self.view_number;
1073
1074 SimpleVote {
1075 signature,
1076 data,
1077 view_number,
1078 }
1079 }
1080}
1081
1082pub type QuorumVote<TYPES> = SimpleVote<TYPES, QuorumData<TYPES>>;
1086pub type QuorumVote2<TYPES> = SimpleVote<TYPES, QuorumData2<TYPES>>;
1089pub type NextEpochQuorumVote2<TYPES> = SimpleVote<TYPES, NextEpochQuorumData2<TYPES>>;
1091pub type DaVote<TYPES> = SimpleVote<TYPES, DaData>;
1093pub type DaVote2<TYPES> = SimpleVote<TYPES, DaData2>;
1095
1096pub type TimeoutVote<TYPES> = SimpleVote<TYPES, TimeoutData>;
1098pub type TimeoutVote2<TYPES> = SimpleVote<TYPES, TimeoutData2>;
1100pub type TimeoutVote3<TYPES> = SimpleVote<TYPES, TimeoutData3>;
1102
1103pub type ViewSyncPreCommitVote<TYPES> = SimpleVote<TYPES, ViewSyncPreCommitData>;
1105pub type ViewSyncPreCommitVote2<TYPES> = SimpleVote<TYPES, ViewSyncPreCommitData2>;
1107pub type ViewSyncFinalizeVote<TYPES> = SimpleVote<TYPES, ViewSyncFinalizeData>;
1109pub type ViewSyncFinalizeVote2<TYPES> = SimpleVote<TYPES, ViewSyncFinalizeData2>;
1111pub type ViewSyncCommitVote<TYPES> = SimpleVote<TYPES, ViewSyncCommitData>;
1113pub type ViewSyncCommitVote2<TYPES> = SimpleVote<TYPES, ViewSyncCommitData2>;
1115pub type UpgradeVote<TYPES> = SimpleVote<TYPES, UpgradeProposalData>;
1117pub type UpgradeVote2<TYPES> = SimpleVote<TYPES, UpgradeProposalData2>;
1119
1120impl<TYPES: NodeType> Borrow<QuorumData2<TYPES>> for NextEpochQuorumData2<TYPES> {
1121 fn borrow(&self) -> &QuorumData2<TYPES> {
1122 &self.0
1123 }
1124}
1125impl<TYPES: NodeType> Deref for NextEpochQuorumData2<TYPES> {
1126 type Target = QuorumData2<TYPES>;
1127 fn deref(&self) -> &Self::Target {
1128 &self.0
1129 }
1130}
1131impl<TYPES: NodeType> DerefMut for NextEpochQuorumData2<TYPES> {
1132 fn deref_mut(&mut self) -> &mut Self::Target {
1133 &mut self.0
1134 }
1135}
1136impl<TYPES: NodeType> From<QuorumData2<TYPES>> for NextEpochQuorumData2<TYPES> {
1137 fn from(data: QuorumData2<TYPES>) -> Self {
1138 Self(QuorumData2 {
1139 epoch: data.epoch,
1140 leaf_commit: data.leaf_commit,
1141 block_number: data.block_number,
1142 })
1143 }
1144}
1145
1146impl<TYPES: NodeType> From<QuorumVote2<TYPES>> for NextEpochQuorumVote2<TYPES> {
1147 fn from(qvote: QuorumVote2<TYPES>) -> Self {
1148 Self {
1149 data: qvote.data.into(),
1150 view_number: qvote.view_number,
1151 signature: qvote.signature.clone(),
1152 }
1153 }
1154}
1155
1156#[derive(Serialize, Deserialize, Eq, Hash, PartialEq, Debug, Clone)]
1158pub struct LightClientStateUpdateVote<TYPES: NodeType> {
1159 pub epoch: EpochNumber,
1161 pub light_client_state: LightClientState,
1163 pub next_stake_table_state: StakeTableState,
1165 pub signature: <TYPES::StateSignatureKey as StateSignatureKey>::StateSignature,
1167}
1168
1169#[derive(Serialize, Deserialize, Eq, Hash, PartialEq, Debug, Clone)]
1171pub struct LightClientStateUpdateVote2<TYPES: NodeType> {
1172 pub epoch: EpochNumber,
1174 pub light_client_state: LightClientState,
1176 pub next_stake_table_state: StakeTableState,
1178 pub signature: <TYPES::StateSignatureKey as StateSignatureKey>::StateSignature,
1180 pub v2_signature: <TYPES::StateSignatureKey as StateSignatureKey>::StateSignature,
1182 pub auth_root: FixedBytes<32>,
1184 #[serde(with = "canonical")]
1188 pub signed_state_digest: CircuitField,
1189}
1190
1191impl<TYPES: NodeType> LightClientStateUpdateVote<TYPES> {
1192 pub fn to_vote2(self) -> LightClientStateUpdateVote2<TYPES> {
1193 LightClientStateUpdateVote2 {
1194 epoch: self.epoch,
1195 light_client_state: self.light_client_state,
1196 next_stake_table_state: self.next_stake_table_state,
1197 signature: self.signature.clone(),
1198 v2_signature: self.signature,
1199 auth_root: Default::default(),
1200 signed_state_digest: Default::default(),
1201 }
1202 }
1203}
1204
1205impl<TYPES: NodeType> LightClientStateUpdateVote2<TYPES> {
1206 pub fn to_vote(self) -> LightClientStateUpdateVote<TYPES> {
1207 LightClientStateUpdateVote {
1208 epoch: self.epoch,
1209 light_client_state: self.light_client_state,
1210 next_stake_table_state: self.next_stake_table_state,
1211 signature: self.v2_signature,
1212 }
1213 }
1214}
1215
1216impl<TYPES: NodeType> HasViewNumber for LightClientStateUpdateVote<TYPES> {
1217 fn view_number(&self) -> ViewNumber {
1218 ViewNumber::new(self.light_client_state.view_number)
1219 }
1220}
1221
1222impl<TYPES: NodeType> HasEpoch for LightClientStateUpdateVote<TYPES> {
1223 fn epoch(&self) -> Option<EpochNumber> {
1224 Some(self.epoch)
1225 }
1226}
1227
1228#[derive(Serialize, Deserialize, Eq, Hash, PartialEq, Debug, Clone)]
1229#[serde(bound(deserialize = "QuorumVote2<TYPES>:for<'a> Deserialize<'a>"))]
1230pub struct EpochRootQuorumVote<TYPES: NodeType> {
1231 pub vote: QuorumVote2<TYPES>,
1232 pub state_vote: LightClientStateUpdateVote<TYPES>,
1233}
1234
1235#[derive(Serialize, Deserialize, Eq, Hash, PartialEq, Debug, Clone)]
1236#[serde(bound(deserialize = "QuorumVote2<TYPES>:for<'a> Deserialize<'a>"))]
1237pub struct EpochRootQuorumVote2<TYPES: NodeType> {
1238 pub vote: QuorumVote2<TYPES>,
1239 pub state_vote: LightClientStateUpdateVote2<TYPES>,
1240}
1241
1242impl<TYPES: NodeType> EpochRootQuorumVote<TYPES> {
1243 pub fn to_vote2(self) -> EpochRootQuorumVote2<TYPES> {
1244 EpochRootQuorumVote2 {
1245 vote: self.vote,
1246 state_vote: self.state_vote.to_vote2(),
1247 }
1248 }
1249}
1250
1251impl<TYPES: NodeType> EpochRootQuorumVote2<TYPES> {
1252 pub fn to_vote(self) -> EpochRootQuorumVote<TYPES> {
1253 EpochRootQuorumVote {
1254 vote: self.vote,
1255 state_vote: self.state_vote.to_vote(),
1256 }
1257 }
1258}
1259
1260impl<TYPES: NodeType> HasViewNumber for EpochRootQuorumVote<TYPES> {
1261 fn view_number(&self) -> ViewNumber {
1262 self.vote.view_number()
1263 }
1264}
1265
1266impl<TYPES: NodeType> HasEpoch for EpochRootQuorumVote<TYPES> {
1267 fn epoch(&self) -> Option<EpochNumber> {
1268 self.vote.epoch()
1269 }
1270}
1271
1272impl<TYPES: NodeType> HasViewNumber for EpochRootQuorumVote2<TYPES> {
1273 fn view_number(&self) -> ViewNumber {
1274 self.vote.view_number()
1275 }
1276}
1277
1278impl<TYPES: NodeType> HasEpoch for EpochRootQuorumVote2<TYPES> {
1279 fn epoch(&self) -> Option<EpochNumber> {
1280 self.vote.epoch()
1281 }
1282}