use std::fmt::Display;
use async_broadcast::Sender;
use either::Either;
use hotshot_task::task::TaskEvent;
use hotshot_types::{
data::{
DaProposal, Leaf, PackedBundle, QuorumProposal, UpgradeProposal, VidDisperse,
VidDisperseShare,
},
message::Proposal,
request_response::ProposalRequestPayload,
simple_certificate::{
DaCertificate, QuorumCertificate, TimeoutCertificate, UpgradeCertificate,
ViewSyncCommitCertificate2, ViewSyncFinalizeCertificate2, ViewSyncPreCommitCertificate2,
},
simple_vote::{
DaVote, QuorumVote, TimeoutVote, UpgradeVote, ViewSyncCommitVote, ViewSyncFinalizeVote,
ViewSyncPreCommitVote,
},
traits::{
block_contents::BuilderFee, node_implementation::NodeType, signature_key::SignatureKey,
BlockPayload,
},
utils::{BuilderCommitment, View},
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::Time,
pub response_chan: Sender<Option<Proposal<TYPES, QuorumProposal<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, QuorumProposal<TYPES>>, TYPES::SignatureKey),
QuorumVoteRecv(QuorumVote<TYPES>),
TimeoutVoteRecv(TimeoutVote<TYPES>),
TimeoutVoteSend(TimeoutVote<TYPES>),
DaProposalRecv(Proposal<TYPES, DaProposal<TYPES>>, TYPES::SignatureKey),
DaProposalValidated(Proposal<TYPES, DaProposal<TYPES>>, TYPES::SignatureKey),
DaVoteRecv(DaVote<TYPES>),
DaCertificateRecv(DaCertificate<TYPES>),
DaCertificateValidated(DaCertificate<TYPES>),
QuorumProposalSend(Proposal<TYPES, QuorumProposal<TYPES>>, TYPES::SignatureKey),
QuorumVoteSend(QuorumVote<TYPES>),
QuorumVoteDependenciesValidated(TYPES::Time),
QuorumProposalValidated(QuorumProposal<TYPES>, Leaf<TYPES>),
QuorumProposalRequestSend(
ProposalRequestPayload<TYPES>,
<TYPES::SignatureKey as SignatureKey>::PureAssembledSignatureType,
),
QuorumProposalRequestRecv(
ProposalRequestPayload<TYPES>,
<TYPES::SignatureKey as SignatureKey>::PureAssembledSignatureType,
),
QuorumProposalResponseSend(TYPES::SignatureKey, Proposal<TYPES, QuorumProposal<TYPES>>),
QuorumProposalResponseRecv(Proposal<TYPES, QuorumProposal<TYPES>>),
DaProposalSend(Proposal<TYPES, DaProposal<TYPES>>, TYPES::SignatureKey),
DaVoteSend(DaVote<TYPES>),
QcFormed(Either<QuorumCertificate<TYPES>, TimeoutCertificate<TYPES>>),
DacSend(DaCertificate<TYPES>, TYPES::SignatureKey),
ViewChange(TYPES::Time),
ViewSyncTimeout(TYPES::Time, u64, ViewSyncPhase),
ViewSyncPreCommitVoteRecv(ViewSyncPreCommitVote<TYPES>),
ViewSyncCommitVoteRecv(ViewSyncCommitVote<TYPES>),
ViewSyncFinalizeVoteRecv(ViewSyncFinalizeVote<TYPES>),
ViewSyncPreCommitVoteSend(ViewSyncPreCommitVote<TYPES>),
ViewSyncCommitVoteSend(ViewSyncCommitVote<TYPES>),
ViewSyncFinalizeVoteSend(ViewSyncFinalizeVote<TYPES>),
ViewSyncPreCommitCertificate2Recv(ViewSyncPreCommitCertificate2<TYPES>),
ViewSyncCommitCertificate2Recv(ViewSyncCommitCertificate2<TYPES>),
ViewSyncFinalizeCertificate2Recv(ViewSyncFinalizeCertificate2<TYPES>),
ViewSyncPreCommitCertificate2Send(ViewSyncPreCommitCertificate2<TYPES>, TYPES::SignatureKey),
ViewSyncCommitCertificate2Send(ViewSyncCommitCertificate2<TYPES>, TYPES::SignatureKey),
ViewSyncFinalizeCertificate2Send(ViewSyncFinalizeCertificate2<TYPES>, TYPES::SignatureKey),
ViewSyncTrigger(TYPES::Time),
Timeout(TYPES::Time),
TransactionsRecv(Vec<TYPES::Transaction>),
TransactionSend(TYPES::Transaction, TYPES::SignatureKey),
SendPayloadCommitmentAndMetadata(
VidCommitment,
BuilderCommitment,
<TYPES::BlockPayload as BlockPayload<TYPES>>::Metadata,
TYPES::Time,
Vec1<BuilderFee<TYPES>>,
Option<TYPES::AuctionResult>,
),
BlockRecv(PackedBundle<TYPES>),
BlockReady(VidDisperse<TYPES>, TYPES::Time),
LeafDecided(Vec<Leaf<TYPES>>),
VidDisperseSend(Proposal<TYPES, VidDisperse<TYPES>>, TYPES::SignatureKey),
VidShareRecv(Proposal<TYPES, VidDisperseShare<TYPES>>),
VidShareValidated(Proposal<TYPES, VidDisperseShare<TYPES>>),
UpgradeProposalRecv(Proposal<TYPES, UpgradeProposal<TYPES>>, TYPES::SignatureKey),
UpgradeProposalSend(Proposal<TYPES, UpgradeProposal<TYPES>>, TYPES::SignatureKey),
UpgradeVoteRecv(UpgradeVote<TYPES>),
UpgradeVoteSend(UpgradeVote<TYPES>),
UpgradeCertificateFormed(UpgradeCertificate<TYPES>),
ValidatedStateUpdated(TYPES::Time, View<TYPES>),
LockedViewUpdated(TYPES::Time),
LastDecidedViewUpdated(TYPES::Time),
UpdateHighQc(QuorumCertificate<TYPES>),
HighQcUpdated(QuorumCertificate<TYPES>),
QuorumProposalPreliminarilyValidated(Proposal<TYPES, QuorumProposal<TYPES>>),
}
impl<TYPES: NodeType> HotShotEvent<TYPES> {
#[allow(clippy::too_many_lines)]
pub fn view_number(&self) -> Option<TYPES::Time> {
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, _) => Some(proposal.data.view_number()),
HotShotEvent::QuorumVoteSend(vote) => Some(vote.view_number()),
HotShotEvent::QuorumProposalValidated(proposal, _) => Some(proposal.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::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::ViewSyncPreCommitCertificate2Recv(cert)
| HotShotEvent::ViewSyncPreCommitCertificate2Send(cert, _) => Some(cert.view_number()),
HotShotEvent::ViewSyncCommitCertificate2Recv(cert)
| HotShotEvent::ViewSyncCommitCertificate2Send(cert, _) => Some(cert.view_number()),
HotShotEvent::ViewSyncFinalizeCertificate2Recv(cert)
| HotShotEvent::ViewSyncFinalizeCertificate2Send(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::LeafDecided(_)
| 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::QuorumProposalResponseSend(_, proposal)
| HotShotEvent::QuorumProposalResponseRecv(proposal)
| HotShotEvent::QuorumProposalPreliminarilyValidated(proposal) => {
Some(proposal.data.view_number())
}
HotShotEvent::QuorumVoteDependenciesValidated(view_number)
| HotShotEvent::ViewChange(view_number)
| HotShotEvent::ViewSyncTimeout(view_number, _, _)
| HotShotEvent::ViewSyncTrigger(view_number)
| HotShotEvent::Timeout(view_number)
| HotShotEvent::BlockReady(_, view_number)
| HotShotEvent::LockedViewUpdated(view_number)
| HotShotEvent::LastDecidedViewUpdated(view_number)
| HotShotEvent::ValidatedStateUpdated(view_number, _) => Some(*view_number),
HotShotEvent::DaCertificateRecv(cert) | HotShotEvent::DacSend(cert, _) => {
Some(cert.view_number())
}
HotShotEvent::UpdateHighQc(cert) | HotShotEvent::HighQcUpdated(cert) => {
Some(cert.view_number())
}
HotShotEvent::DaCertificateValidated(cert) => Some(cert.view_number),
HotShotEvent::UpgradeCertificateFormed(cert) => Some(cert.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::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::QuorumVoteDependenciesValidated(view_number) => {
write!(
f,
"QuorumVoteDependenciesValidated(view_number={view_number:?})"
)
}
HotShotEvent::QuorumProposalValidated(proposal, _) => write!(
f,
"QuorumProposalValidated(view_number={:?})",
proposal.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::DacSend(cert, _) => {
write!(f, "DacSend(view_number={:?})", cert.view_number())
}
HotShotEvent::ViewChange(view_number) => {
write!(f, "ViewChange(view_number={view_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::ViewSyncPreCommitCertificate2Recv(cert) => {
write!(
f,
"ViewSyncPreCommitCertificate2Recv(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncCommitCertificate2Recv(cert) => {
write!(
f,
"ViewSyncCommitCertificate2Recv(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncFinalizeCertificate2Recv(cert) => {
write!(
f,
"ViewSyncFinalizeCertificate2Recv(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncPreCommitCertificate2Send(cert, _) => {
write!(
f,
"ViewSyncPreCommitCertificate2Send(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncCommitCertificate2Send(cert, _) => {
write!(
f,
"ViewSyncCommitCertificate2Send(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncFinalizeCertificate2Send(cert, _) => {
write!(
f,
"ViewSyncFinalizeCertificate2Send(view_number={:?})",
cert.view_number()
)
}
HotShotEvent::ViewSyncTrigger(view_number) => {
write!(f, "ViewSyncTrigger(view_number={view_number:?})")
}
HotShotEvent::Timeout(view_number) => write!(f, "Timeout(view_number={view_number:?})"),
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::BlockReady(_, view_number) => {
write!(f, "BlockReady(view_number={view_number:?})")
}
HotShotEvent::LeafDecided(leaves) => {
let view_numbers: Vec<<TYPES as NodeType>::Time> =
leaves.iter().map(Leaf::view_number).collect();
write!(f, "LeafDecided({view_numbers:?})")
}
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::ValidatedStateUpdated(view_number, _) => {
write!(f, "ValidatedStateUpdated(view_number={view_number:?})")
}
HotShotEvent::LockedViewUpdated(view_number) => {
write!(f, "LockedViewUpdated(view_number={view_number:?})")
}
HotShotEvent::LastDecidedViewUpdated(view_number) => {
write!(f, "LastDecidedViewUpdated(view_number={view_number:?})")
}
HotShotEvent::UpdateHighQc(cert) => {
write!(f, "UpdateHighQc(view_number={:?})", cert.view_number())
}
HotShotEvent::HighQcUpdated(cert) => {
write!(f, "HighQcUpdated(view_number={:?})", cert.view_number())
}
HotShotEvent::QuorumProposalPreliminarilyValidated(proposal) => {
write!(
f,
"QuorumProposalPreliminarilyValidated(view_number={:?}",
proposal.data.view_number()
)
}
}
}
}