hotshot_types/new_protocol/
proposal.rs1use serde::{Deserialize, Serialize};
2
3use crate::{
4 data::{
5 EpochNumber, Leaf2, QuorumProposal2, QuorumProposalWrapper, ViewChangeEvidence2, ViewNumber,
6 },
7 drb::DrbResult,
8 simple_certificate::{
9 LightClientStateUpdateCertificateV2, QuorumCertificate2, SimpleCertificate,
10 SuccessThreshold, UpgradeCertificate,
11 },
12 simple_vote::{HasEpoch, TimeoutData2, Vote2Data},
13 traits::node_implementation::NodeType,
14 vote::HasViewNumber,
15};
16
17#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
19#[serde(bound(deserialize = ""))]
20pub struct Proposal<T: NodeType> {
21 pub block_header: T::BlockHeader,
23
24 pub view_number: ViewNumber,
26
27 pub epoch: EpochNumber,
29
30 pub justify_qc: QuorumCertificate2<T>,
32
33 pub next_epoch_justify_qc: Option<SimpleCertificate<T, Vote2Data<T>, SuccessThreshold>>,
35
36 pub upgrade_certificate: Option<UpgradeCertificate<T>>,
38
39 pub view_change_evidence: Option<SimpleCertificate<T, TimeoutData2, SuccessThreshold>>,
44
45 #[serde(with = "serde_bytes")]
50 pub next_drb_result: Option<DrbResult>,
51
52 pub state_cert: Option<LightClientStateUpdateCertificateV2<T>>,
55}
56
57impl<T: NodeType> HasViewNumber for Proposal<T> {
58 fn view_number(&self) -> ViewNumber {
59 self.view_number
60 }
61}
62
63impl<T: NodeType> HasEpoch for Proposal<T> {
64 fn epoch(&self) -> Option<EpochNumber> {
65 Some(self.epoch)
66 }
67}
68
69impl<T: NodeType> From<QuorumProposalWrapper<T>> for Proposal<T> {
70 fn from(wrapper: QuorumProposalWrapper<T>) -> Self {
71 let qp = wrapper.proposal;
72 Self {
73 block_header: qp.block_header,
74 view_number: qp.view_number,
75 epoch: qp.epoch.unwrap_or(EpochNumber::new(0)),
76 justify_qc: qp.justify_qc,
77 next_epoch_justify_qc: None,
78 upgrade_certificate: qp.upgrade_certificate,
79 view_change_evidence: qp.view_change_evidence.and_then(|e| match e {
80 ViewChangeEvidence2::Timeout(tc) => Some(tc),
81 ViewChangeEvidence2::ViewSync(_) => None,
82 }),
83 next_drb_result: qp.next_drb_result,
84 state_cert: qp.state_cert,
85 }
86 }
87}
88
89impl<T: NodeType> From<Proposal<T>> for QuorumProposalWrapper<T> {
90 fn from(p: Proposal<T>) -> Self {
91 QuorumProposalWrapper::from(QuorumProposal2 {
92 block_header: p.block_header,
93 view_number: p.view_number,
94 epoch: Some(p.epoch),
95 justify_qc: p.justify_qc,
96 next_epoch_justify_qc: None,
97 upgrade_certificate: p.upgrade_certificate,
98 view_change_evidence: p.view_change_evidence.map(ViewChangeEvidence2::Timeout),
99 next_drb_result: p.next_drb_result,
100 state_cert: p.state_cert,
101 })
102 }
103}
104
105impl<T: NodeType> From<Proposal<T>> for Leaf2<T> {
106 fn from(p: Proposal<T>) -> Self {
107 Self::from_quorum_proposal(&QuorumProposalWrapper::from(p))
108 }
109}