use std::fmt::Display;
use async_broadcast::Sender;
use either::Either;
use hotshot_task::task::TaskEvent;
use hotshot_types::{
data::{
DaProposal2, Leaf2, PackedBundle, QuorumProposal2, UpgradeProposal, VidDisperse,
VidDisperseShare2,
},
message::Proposal,
request_response::ProposalRequestPayload,
simple_certificate::{
DaCertificate2, NextEpochQuorumCertificate2, QuorumCertificate, QuorumCertificate2,
TimeoutCertificate, TimeoutCertificate2, UpgradeCertificate, ViewSyncCommitCertificate2,
ViewSyncFinalizeCertificate2, ViewSyncPreCommitCertificate2,
},
simple_vote::{
DaVote2, QuorumVote2, TimeoutVote2, UpgradeVote, ViewSyncCommitVote2,
ViewSyncFinalizeVote2, ViewSyncPreCommitVote2,
},
traits::{
block_contents::BuilderFee, network::DataRequest, node_implementation::NodeType,
signature_key::SignatureKey, BlockPayload,
},
utils::BuilderCommitment,
vid::VidCommitment,
vote::HasViewNumber,
};
use vec1::Vec1;
use crate::view_sync::ViewSyncPhase;
impl<TYPES: NodeType> TaskEvent for HotShotEvent<TYPES> {
fn shutdown_event() -> Self {
HotShotEvent::Shutdown
}
}
#[derive(Debug, Clone)]
pub struct ProposalMissing<TYPES: NodeType> {
pub view: TYPES::View,
pub response_chan: Sender<Option<Proposal<TYPES, QuorumProposal2<TYPES>>>>,
}
impl<TYPES: NodeType> PartialEq for ProposalMissing<TYPES> {
fn eq(&self, other: &Self) -> bool {
self.view == other.view
}
}
impl<TYPES: NodeType> Eq for ProposalMissing<TYPES> {}
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct HotShotTaskCompleted;
#[derive(Eq, PartialEq, Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum HotShotEvent<TYPES: NodeType> {
Shutdown,
QuorumProposalRecv(Proposal<TYPES, QuorumProposal2<TYPES>>, TYPES::SignatureKey),
QuorumVoteRecv(QuorumVote2<TYPES>),
TimeoutVoteRecv(TimeoutVote2<TYPES>),
TimeoutVoteSend(TimeoutVote2<TYPES>),
DaProposalRecv(Proposal<TYPES, DaProposal2<TYPES>>, TYPES::SignatureKey),
DaProposalValidated(Proposal<TYPES, DaProposal2<TYPES>>, TYPES::SignatureKey),
DaVoteRecv(DaVote2<TYPES>),
DaCertificateRecv(DaCertificate2<TYPES>),
DaCertificateValidated(DaCertificate2<TYPES>),
QuorumProposalSend(Proposal<TYPES, QuorumProposal2<TYPES>>, TYPES::SignatureKey),
QuorumVoteSend(QuorumVote2<TYPES>),
ExtendedQuorumVoteSend(QuorumVote2<TYPES>),
QuorumProposalValidated(Proposal<TYPES, QuorumProposal2<TYPES>>, Leaf2<TYPES>),
QuorumProposalRequestSend(
ProposalRequestPayload<TYPES>,
<TYPES::SignatureKey as SignatureKey>::PureAssembledSignatureType,
),
QuorumProposalRequestRecv(
ProposalRequestPayload<TYPES>,
<TYPES::SignatureKey as SignatureKey>::PureAssembledSignatureType,
),
QuorumProposalResponseSend(TYPES::SignatureKey, Proposal<TYPES, QuorumProposal2<TYPES>>),
QuorumProposalResponseRecv(Proposal<TYPES, QuorumProposal2<TYPES>>),
DaProposalSend(Proposal<TYPES, DaProposal2<TYPES>>, TYPES::SignatureKey),
DaVoteSend(DaVote2<TYPES>),
QcFormed(Either<QuorumCertificate<TYPES>, TimeoutCertificate<TYPES>>),
Qc2Formed(Either<QuorumCertificate2<TYPES>, TimeoutCertificate2<TYPES>>),
NextEpochQc2Formed(Either<NextEpochQuorumCertificate2<TYPES>, TimeoutCertificate<TYPES>>),
DacSend(DaCertificate2<TYPES>, TYPES::SignatureKey),
ViewChange(TYPES::View, TYPES::Epoch),
ViewSyncTimeout(TYPES::View, u64, ViewSyncPhase),
ViewSyncPreCommitVoteRecv(ViewSyncPreCommitVote2<TYPES>),
ViewSyncCommitVoteRecv(ViewSyncCommitVote2<TYPES>),
ViewSyncFinalizeVoteRecv(ViewSyncFinalizeVote2<TYPES>),
ViewSyncPreCommitVoteSend(ViewSyncPreCommitVote2<TYPES>),
ViewSyncCommitVoteSend(ViewSyncCommitVote2<TYPES>),
ViewSyncFinalizeVoteSend(ViewSyncFinalizeVote2<TYPES>),
ViewSyncPreCommitCertificateRecv(ViewSyncPreCommitCertificate2<TYPES>),
ViewSyncCommitCertificateRecv(ViewSyncCommitCertificate2<TYPES>),
ViewSyncFinalizeCertificateRecv(ViewSyncFinalizeCertificate2<TYPES>),
ViewSyncPreCommitCertificateSend(ViewSyncPreCommitCertificate2<TYPES>, TYPES::SignatureKey),
ViewSyncCommitCertificateSend(ViewSyncCommitCertificate2<TYPES>, TYPES::SignatureKey),
ViewSyncFinalizeCertificateSend(ViewSyncFinalizeCertificate2<TYPES>, TYPES::SignatureKey),
ViewSyncTrigger(TYPES::View),
Timeout(TYPES::View, TYPES::Epoch),
TransactionsRecv(Vec<TYPES::Transaction>),
TransactionSend(TYPES::Transaction, TYPES::SignatureKey),
SendPayloadCommitmentAndMetadata(
VidCommitment,
BuilderCommitment,
<TYPES::BlockPayload as BlockPayload<TYPES>>::Metadata,
TYPES::View,
Vec1<BuilderFee<TYPES>>,
Option<TYPES::AuctionResult>,
),
BlockRecv(PackedBundle<TYPES>),
VidDisperseSend(Proposal<TYPES, VidDisperse<TYPES>>, TYPES::SignatureKey),
VidShareRecv(
TYPES::SignatureKey,
Proposal<TYPES, VidDisperseShare2<TYPES>>,
),
VidShareValidated(Proposal<TYPES, VidDisperseShare2<TYPES>>),
UpgradeProposalRecv(Proposal<TYPES, UpgradeProposal<TYPES>>, TYPES::SignatureKey),
UpgradeProposalSend(Proposal<TYPES, UpgradeProposal<TYPES>>, TYPES::SignatureKey),
UpgradeVoteRecv(UpgradeVote<TYPES>),
UpgradeVoteSend(UpgradeVote<TYPES>),
UpgradeCertificateFormed(UpgradeCertificate<TYPES>),
QuorumProposalPreliminarilyValidated(Proposal<TYPES, QuorumProposal2<TYPES>>),
VidRequestSend(
DataRequest<TYPES>,
TYPES::SignatureKey,
TYPES::SignatureKey,
),
VidRequestRecv(DataRequest<TYPES>, TYPES::SignatureKey),
VidResponseSend(
TYPES::SignatureKey,
TYPES::SignatureKey,
Proposal<TYPES, VidDisperseShare2<TYPES>>,
),
VidResponseRecv(
TYPES::SignatureKey,
Proposal<TYPES, VidDisperseShare2<TYPES>>,
),
HighQcRecv(QuorumCertificate2<TYPES>, TYPES::SignatureKey),
HighQcSend(
QuorumCertificate2<TYPES>,
TYPES::SignatureKey,
TYPES::SignatureKey,
),
}
impl<TYPES: NodeType> HotShotEvent<TYPES> {
#[allow(clippy::too_many_lines)]
pub fn view_number(&self) -> Option<TYPES::View> {
match self {
HotShotEvent::QuorumVoteRecv(v) => Some(v.view_number()),
HotShotEvent::TimeoutVoteRecv(v) | HotShotEvent::TimeoutVoteSend(v) => {
Some(v.view_number())
}
HotShotEvent::QuorumProposalRecv(proposal, _)
| HotShotEvent::QuorumProposalSend(proposal, _)
| HotShotEvent::QuorumProposalValidated(proposal, _)
| HotShotEvent::QuorumProposalResponseRecv(proposal)
| HotShotEvent::QuorumProposalResponseSend(_, proposal)
| HotShotEvent::QuorumProposalPreliminarilyValidated(proposal) => {
Some(proposal.data.view_number())
}
HotShotEvent::QuorumVoteSend(vote) | HotShotEvent::ExtendedQuorumVoteSend(vote) => {
Some(vote.view_number())
}
HotShotEvent::DaProposalRecv(proposal, _)
| HotShotEvent::DaProposalValidated(proposal, _)
| HotShotEvent::DaProposalSend(proposal, _) => Some(proposal.data.view_number()),
HotShotEvent::DaVoteRecv(vote) | HotShotEvent::DaVoteSend(vote) => {
Some(vote.view_number())
}
HotShotEvent::QcFormed(cert) => match cert {
either::Left(qc) => Some(qc.view_number()),
either::Right(tc) => Some(tc.view_number()),
},
HotShotEvent::Qc2Formed(cert) => match cert {
either::Left(qc) => Some(qc.view_number()),
either::Right(tc) => Some(tc.view_number()),
},
HotShotEvent::NextEpochQc2Formed(cert) => match cert {
either::Left(qc) => Some(qc.view_number()),
either::Right(tc) => Some(tc.view_number()),
},
HotShotEvent::ViewSyncCommitVoteSend(vote)
| HotShotEvent::ViewSyncCommitVoteRecv(vote) => Some(vote.view_number()),
HotShotEvent::ViewSyncPreCommitVoteRecv(vote)
| HotShotEvent::ViewSyncPreCommitVoteSend(vote) => Some(vote.view_number()),
HotShotEvent::ViewSyncFinalizeVoteRecv(vote)
| HotShotEvent::ViewSyncFinalizeVoteSend(vote) => Some(vote.view_number()),
HotShotEvent::ViewSyncPreCommitCertificateRecv(cert)
| HotShotEvent::ViewSyncPreCommitCertificateSend(cert, _) => Some(cert.view_number()),
HotShotEvent::ViewSyncCommitCertificateRecv(cert)
| HotShotEvent::ViewSyncCommitCertificateSend(cert, _) => Some(cert.view_number()),
HotShotEvent::ViewSyncFinalizeCertificateRecv(cert)
| HotShotEvent::ViewSyncFinalizeCertificateSend(cert, _) => Some(cert.view_number()),
HotShotEvent::SendPayloadCommitmentAndMetadata(_, _, _, view_number, _, _) => {
Some(*view_number)
}
HotShotEvent::BlockRecv(packed_bundle) => Some(packed_bundle.view_number),
HotShotEvent::Shutdown
| HotShotEvent::TransactionSend(_, _)
| HotShotEvent::TransactionsRecv(_) => None,
HotShotEvent::VidDisperseSend(proposal, _) => Some(proposal.data.view_number()),
HotShotEvent::VidShareRecv(_, proposal) | HotShotEvent::VidShareValidated(proposal) => {
Some(proposal.data.view_number())
}
HotShotEvent::UpgradeProposalRecv(proposal, _)
| HotShotEvent::UpgradeProposalSend(proposal, _) => Some(proposal.data.view_number()),
HotShotEvent::UpgradeVoteRecv(vote) | HotShotEvent::UpgradeVoteSend(vote) => {
Some(vote.view_number())
}
HotShotEvent::QuorumProposalRequestSend(req, _)
| HotShotEvent::QuorumProposalRequestRecv(req, _) => Some(req.view_number),
HotShotEvent::ViewChange(view_number, _)
| HotShotEvent::ViewSyncTimeout(view_number, _, _)
| HotShotEvent::ViewSyncTrigger(view_number)
| HotShotEvent::Timeout(view_number, ..) => Some(*view_number),
HotShotEvent::DaCertificateRecv(cert) | HotShotEvent::DacSend(cert, _) => {
Some(cert.view_number())
}
HotShotEvent::DaCertificateValidated(cert) => Some(cert.view_number),
HotShotEvent::UpgradeCertificateFormed(cert) => Some(cert.view_number()),
HotShotEvent::VidRequestSend(request, _, _)
| HotShotEvent::VidRequestRecv(request, _) => Some(request.view),
HotShotEvent::VidResponseSend(_, _, proposal)
| HotShotEvent::VidResponseRecv(_, proposal) => Some(proposal.data.view_number),
HotShotEvent::HighQcRecv(qc, _) | HotShotEvent::HighQcSend(qc, ..) => {
Some(qc.view_number())
}
}
}
}
impl<TYPES: NodeType> Display for HotShotEvent<TYPES> {
#[allow(clippy::too_many_lines)]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
HotShotEvent::Shutdown => write!(f, "Shutdown"),
HotShotEvent::QuorumProposalRecv(proposal, _) => write!(
f,
"QuorumProposalRecv(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::QuorumVoteRecv(v) => {
write!(f, "QuorumVoteRecv(view_number={:?})", v.view_number())
}
HotShotEvent::ExtendedQuorumVoteSend(v) => {
write!(
f,
"ExtendedQuorumVoteSend(view_number={:?})",
v.view_number()
)
}
HotShotEvent::TimeoutVoteRecv(v) => {
write!(f, "TimeoutVoteRecv(view_number={:?})", v.view_number())
}
HotShotEvent::TimeoutVoteSend(v) => {
write!(f, "TimeoutVoteSend(view_number={:?})", v.view_number())
}
HotShotEvent::DaProposalRecv(proposal, _) => write!(
f,
"DaProposalRecv(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::DaProposalValidated(proposal, _) => write!(
f,
"DaProposalValidated(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::DaVoteRecv(vote) => {
write!(f, "DaVoteRecv(view_number={:?})", vote.view_number())
}
HotShotEvent::DaCertificateRecv(cert) => {
write!(f, "DaCertificateRecv(view_number={:?})", cert.view_number())
}
HotShotEvent::DaCertificateValidated(cert) => write!(
f,
"DaCertificateValidated(view_number={:?})",
cert.view_number()
),
HotShotEvent::QuorumProposalSend(proposal, _) => write!(
f,
"QuorumProposalSend(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::QuorumVoteSend(vote) => {
write!(f, "QuorumVoteSend(view_number={:?})", vote.view_number())
}
HotShotEvent::QuorumProposalValidated(proposal, _) => write!(
f,
"QuorumProposalValidated(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::DaProposalSend(proposal, _) => write!(
f,
"DaProposalSend(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::DaVoteSend(vote) => {
write!(f, "DaVoteSend(view_number={:?})", vote.view_number())
}
HotShotEvent::QcFormed(cert) => match cert {
either::Left(qc) => write!(f, "QcFormed(view_number={:?})", qc.view_number()),
either::Right(tc) => write!(f, "QcFormed(view_number={:?})", tc.view_number()),
},
HotShotEvent::Qc2Formed(cert) => match cert {
either::Left(qc) => write!(f, "QcFormed2(view_number={:?})", qc.view_number()),
either::Right(tc) => write!(f, "QcFormed2(view_number={:?})", tc.view_number()),
},
HotShotEvent::NextEpochQc2Formed(cert) => match cert {
either::Left(qc) => {
write!(f, "NextEpochQc2Formed(view_number={:?})", qc.view_number())
}
either::Right(tc) => {
write!(f, "NextEpochQc2Formed(view_number={:?})", tc.view_number())
}
},
HotShotEvent::DacSend(cert, _) => {
write!(f, "DacSend(view_number={:?})", cert.view_number())
}
HotShotEvent::ViewChange(view_number, epoch_number) => {
write!(
f,
"ViewChange(view_number={view_number:?}, epoch_number={epoch_number:?})"
)
}
HotShotEvent::ViewSyncTimeout(view_number, _, _) => {
write!(f, "ViewSyncTimeout(view_number={view_number:?})")
}
HotShotEvent::ViewSyncPreCommitVoteRecv(vote) => write!(
f,
"ViewSyncPreCommitVoteRecv(view_number={:?})",
vote.view_number()
),
HotShotEvent::ViewSyncCommitVoteRecv(vote) => write!(
f,
"ViewSyncCommitVoteRecv(view_number={:?})",
vote.view_number()
),
HotShotEvent::ViewSyncFinalizeVoteRecv(vote) => write!(
f,
"ViewSyncFinalizeVoteRecv(view_number={:?})",
vote.view_number()
),
HotShotEvent::ViewSyncPreCommitVoteSend(vote) => write!(
f,
"ViewSyncPreCommitVoteSend(view_number={:?})",
vote.view_number()
),
HotShotEvent::ViewSyncCommitVoteSend(vote) => write!(
f,
"ViewSyncCommitVoteSend(view_number={:?})",
vote.view_number()
),
HotShotEvent::ViewSyncFinalizeVoteSend(vote) => write!(
f,
"ViewSyncFinalizeVoteSend(view_number={:?})",
vote.view_number()
),
HotShotEvent::ViewSyncPreCommitCertificateRecv(cert) => {
write!(
f,
"ViewSyncPreCommitCertificateRecv(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncCommitCertificateRecv(cert) => {
write!(
f,
"ViewSyncCommitCertificateRecv(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncFinalizeCertificateRecv(cert) => {
write!(
f,
"ViewSyncFinalizeCertificateRecv(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncPreCommitCertificateSend(cert, _) => {
write!(
f,
"ViewSyncPreCommitCertificateSend(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncCommitCertificateSend(cert, _) => {
write!(
f,
"ViewSyncCommitCertificateSend(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncFinalizeCertificateSend(cert, _) => {
write!(
f,
"ViewSyncFinalizeCertificateSend(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncTrigger(view_number) => {
write!(f, "ViewSyncTrigger(view_number={view_number:?})")
}
HotShotEvent::Timeout(view_number, epoch) => {
write!(f, "Timeout(view_number={view_number:?}, epoch={epoch:?})")
}
HotShotEvent::TransactionsRecv(_) => write!(f, "TransactionsRecv"),
HotShotEvent::TransactionSend(_, _) => write!(f, "TransactionSend"),
HotShotEvent::SendPayloadCommitmentAndMetadata(_, _, _, view_number, _, _) => {
write!(
f,
"SendPayloadCommitmentAndMetadata(view_number={view_number:?})"
)
}
HotShotEvent::BlockRecv(packed_bundle) => {
write!(f, "BlockRecv(view_number={:?})", packed_bundle.view_number)
}
HotShotEvent::VidDisperseSend(proposal, _) => write!(
f,
"VidDisperseSend(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::VidShareRecv(_, proposal) => write!(
f,
"VIDShareRecv(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::VidShareValidated(proposal) => write!(
f,
"VIDShareValidated(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::UpgradeProposalRecv(proposal, _) => write!(
f,
"UpgradeProposalRecv(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::UpgradeProposalSend(proposal, _) => write!(
f,
"UpgradeProposalSend(view_number={:?})",
proposal.data.view_number()
),
HotShotEvent::UpgradeVoteRecv(vote) => {
write!(f, "UpgradeVoteRecv(view_number={:?})", vote.view_number())
}
HotShotEvent::UpgradeVoteSend(vote) => {
write!(f, "UpgradeVoteSend(view_number={:?})", vote.view_number())
}
HotShotEvent::UpgradeCertificateFormed(cert) => write!(
f,
"UpgradeCertificateFormed(view_number={:?})",
cert.view_number()
),
HotShotEvent::QuorumProposalRequestSend(view_number, _) => {
write!(f, "QuorumProposalRequestSend(view_number={view_number:?})")
}
HotShotEvent::QuorumProposalRequestRecv(view_number, _) => {
write!(f, "QuorumProposalRequestRecv(view_number={view_number:?})")
}
HotShotEvent::QuorumProposalResponseSend(_, proposal) => {
write!(
f,
"QuorumProposalResponseSend(view_number={:?})",
proposal.data.view_number
)
}
HotShotEvent::QuorumProposalResponseRecv(proposal) => {
write!(
f,
"QuorumProposalResponseRecv(view_number={:?})",
proposal.data.view_number
)
}
HotShotEvent::QuorumProposalPreliminarilyValidated(proposal) => {
write!(
f,
"QuorumProposalPreliminarilyValidated(view_number={:?}",
proposal.data.view_number()
)
}
HotShotEvent::VidRequestSend(request, _, _) => {
write!(f, "VidRequestSend(view_number={:?}", request.view)
}
HotShotEvent::VidRequestRecv(request, _) => {
write!(f, "VidRequestRecv(view_number={:?}", request.view)
}
HotShotEvent::VidResponseSend(_, _, proposal) => {
write!(
f,
"VidResponseSend(view_number={:?}",
proposal.data.view_number
)
}
HotShotEvent::VidResponseRecv(_, proposal) => {
write!(
f,
"VidResponseRecv(view_number={:?}",
proposal.data.view_number
)
}
HotShotEvent::HighQcRecv(qc, _) => {
write!(f, "HighQcRecv(view_number={:?}", qc.view_number())
}
HotShotEvent::HighQcSend(qc, ..) => {
write!(f, "HighQcSend(view_number={:?}", qc.view_number())
}
}
}
}