Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create new Certificate and Vote types and use them for Quorum #1967

Merged
merged 18 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/hotshot/src/traits/election/static_committee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use tracing::debug;

/// Dummy implementation of [`Membership`]

#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct GeneralStaticCommittee<T, LEAF: LeafType<NodeType = T>, PUBKEY: SignatureKey> {
/// All the nodes participating and their stake
nodes_with_stake: Vec<PUBKEY::StakeTableEntry>,
Expand Down
46 changes: 23 additions & 23 deletions crates/hotshot/src/types/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,29 +330,29 @@ impl<TYPES: NodeType, I: NodeImplementation<TYPES> + 'static> SystemContextHandl
}

/// create a yes message
#[cfg(feature = "hotshot-testing")]
pub fn create_yes_message(
&self,
justify_qc_commitment: Commitment<QuorumCertificate<TYPES, Commitment<I::Leaf>>>,
leaf_commitment: Commitment<I::Leaf>,
current_view: TYPES::Time,
vote_token: TYPES::VoteTokenType,
) -> GeneralConsensusMessage<TYPES, I>
where
QuorumEx<TYPES, I>: ConsensusExchange<
TYPES,
Message<TYPES, I>,
Certificate = QuorumCertificate<TYPES, Commitment<I::Leaf>>,
>,
{
let inner = self.hotshot.inner.clone();
inner.exchanges.quorum_exchange().create_yes_message(
justify_qc_commitment,
leaf_commitment,
current_view,
vote_token,
)
}
// #[cfg(feature = "hotshot-testing")]
// pub fn create_yes_message(
// &self,
// justify_qc_commitment: Commitment<QuorumCertificate<TYPES, Commitment<I::Leaf>>>,
// leaf_commitment: Commitment<I::Leaf>,
// current_view: TYPES::Time,
// vote_token: TYPES::VoteTokenType,
// ) -> GeneralConsensusMessage<TYPES, I>
// where
// QuorumEx<TYPES, I>: ConsensusExchange<
// TYPES,
// Message<TYPES, I>,
// Certificate = QuorumCertificate<TYPES, Commitment<I::Leaf>>,
// >,
// {
// let inner = self.hotshot.inner.clone();
// inner.exchanges.quorum_exchange().create_yes_message(
// justify_qc_commitment,
// leaf_commitment,
// current_view,
// vote_token,
// )
// }

/// Wrapper around `HotShotConsensusApi`'s `send_broadcast_consensus_message` function
#[cfg(feature = "hotshot-testing")]
Expand Down
318 changes: 150 additions & 168 deletions crates/task-impls/src/consensus.rs

Large diffs are not rendered by default.

17 changes: 12 additions & 5 deletions crates/task-impls/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ use hotshot_types::{
certificate::{DACertificate, QuorumCertificate, TimeoutCertificate, VIDCertificate},
data::{DAProposal, VidDisperse},
message::Proposal,
simple_certificate::QuorumCertificate2,
simple_vote::YesVote,
traits::node_implementation::{
NodeImplementation, NodeType, QuorumProposalType, ViewSyncProposalType,
NodeImplementation, NodeType, QuorumMembership, QuorumProposalType, ViewSyncProposalType,
},
vote::{DAVote, QuorumVote, TimeoutVote, VIDVote, ViewSyncVote},
vote::{DAVote, TimeoutVote, VIDVote, ViewSyncVote},
};

/// All of the possible events that can be passed between Sequecning `HotShot` tasks
Expand All @@ -19,7 +21,7 @@ pub enum HotShotEvent<TYPES: NodeType, I: NodeImplementation<TYPES>> {
/// A quorum proposal has been received from the network; handled by the consensus task
QuorumProposalRecv(Proposal<QuorumProposalType<TYPES, I>>, TYPES::SignatureKey),
/// A quorum vote has been received from the network; handled by the consensus task
QuorumVoteRecv(QuorumVote<TYPES, Commitment<I::Leaf>>),
QuorumVoteRecv(YesVote<TYPES, I::Leaf, QuorumMembership<TYPES, I>>),
/// A timeout vote recevied from the network; handled by consensus task
TimeoutVoteRecv(TimeoutVote<TYPES>),
/// Send a timeout vote to the network; emitted by consensus task replicas
Expand All @@ -33,13 +35,18 @@ pub enum HotShotEvent<TYPES: NodeType, I: NodeImplementation<TYPES>> {
/// Send a quorum proposal to the network; emitted by the leader in the consensus task
QuorumProposalSend(Proposal<QuorumProposalType<TYPES, I>>, TYPES::SignatureKey),
/// Send a quorum vote to the next leader; emitted by a replica in the consensus task after seeing a valid quorum proposal
QuorumVoteSend(QuorumVote<TYPES, Commitment<I::Leaf>>),
QuorumVoteSend(YesVote<TYPES, I::Leaf, QuorumMembership<TYPES, I>>),
/// Send a DA proposal to the DA committee; emitted by the DA leader (which is the same node as the leader of view v + 1) in the DA task
DAProposalSend(Proposal<DAProposal<TYPES>>, TYPES::SignatureKey),
/// Send a DA vote to the DA leader; emitted by DA committee members in the DA task after seeing a valid DA proposal
DAVoteSend(DAVote<TYPES>),
/// The next leader has collected enough votes to form a QC; emitted by the next leader in the consensus task; an internal event only
QCFormed(Either<QuorumCertificate<TYPES, Commitment<I::Leaf>>, TimeoutCertificate<TYPES>>),
QCFormed(
Either<
QuorumCertificate2<TYPES, I::Leaf, QuorumMembership<TYPES, I>>,
TimeoutCertificate<TYPES>,
>,
),
/// The DA leader has collected enough votes to form a DAC; emitted by the DA leader in the DA task; sent to the entire network via the networking task
DACSend(DACertificate<TYPES>, TYPES::SignatureKey),
/// The current view has changed; emitted by the replica in the consensus task or replica in the view sync task; received by almost all other tasks
Expand Down
2 changes: 2 additions & 0 deletions crates/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub mod data;
pub mod error;
pub mod event;
pub mod message;
pub mod simple_certificate;
pub mod simple_vote;
pub mod traits;
pub mod utils;
pub mod vote;
Expand Down
18 changes: 12 additions & 6 deletions crates/types/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
//! This module contains types used to represent the various types of messages that
//! `HotShot` nodes can send among themselves.

use crate::vote2::HasViewNumber;
use crate::{
certificate::{DACertificate, VIDCertificate},
data::{DAProposal, ProposalType, VidDisperse},
simple_vote::YesVote,
traits::{
network::{NetworkMsg, ViewMessage},
node_implementation::{
ExchangesType, NodeImplementation, NodeType, QuorumProposalType, ViewSyncProposalType,
ExchangesType, NodeImplementation, NodeType, QuorumMembership, QuorumProposalType,
ViewSyncProposalType,
},
signature_key::EncodedSignature,
},
Expand Down Expand Up @@ -148,7 +151,10 @@ where
/// Message with a quorum proposal.
Proposal(Proposal<QuorumProposalType<TYPES, I>>, TYPES::SignatureKey),
/// Message with a quorum vote.
Vote(QuorumVote<TYPES, Commitment<I::Leaf>>, TYPES::SignatureKey),
Vote(
YesVote<TYPES, I::Leaf, QuorumMembership<TYPES, I>>,
TYPES::SignatureKey,
),
/// Message with a view sync vote.
ViewSyncVote(ViewSyncVote<TYPES>),
/// Message with a view sync certificate.
Expand Down Expand Up @@ -303,7 +309,7 @@ impl<
}
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Hash, Eq)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(bound(deserialize = "", serialize = ""))]
/// Messages related to both validating and sequencing consensus.
pub enum GeneralConsensusMessage<TYPES: NodeType, I: NodeImplementation<TYPES>>
Expand All @@ -314,7 +320,7 @@ where
Proposal(Proposal<QuorumProposalType<TYPES, I>>),

/// Message with a quorum vote.
Vote(QuorumVote<TYPES, Commitment<I::Leaf>>),
Vote(YesVote<TYPES, I::Leaf, QuorumMembership<TYPES, I>>),

/// Message with a view sync vote.
ViewSyncVote(ViewSyncVote<TYPES>),
Expand Down Expand Up @@ -383,7 +389,7 @@ pub trait SequencingMessageType<TYPES: NodeType, I: NodeImplementation<TYPES>>:
}

/// Messages for sequencing consensus.
#[derive(Clone, Debug, Deserialize, Serialize, Hash, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(bound(deserialize = "", serialize = ""))]
pub struct SequencingMessage<
TYPES: NodeType,
Expand All @@ -409,7 +415,7 @@ impl<
// this should match replica upon receipt
p.data.get_view_number()
}
GeneralConsensusMessage::Vote(vote_message) => vote_message.get_view(),
GeneralConsensusMessage::Vote(vote_message) => vote_message.get_view_number(),
GeneralConsensusMessage::InternalTrigger(trigger) => match trigger {
InternalTrigger::Timeout(time) => *time,
},
Expand Down
90 changes: 90 additions & 0 deletions crates/types/src/simple_certificate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#![allow(dead_code)]
#![allow(clippy::missing_docs_in_private_items)]
#![allow(missing_docs)]

use std::marker::PhantomData;

use commit::Commitment;
use ethereum_types::U256;

use crate::{
simple_vote::{Voteable, YesData},
traits::{
election::Membership, node_implementation::NodeType, signature_key::SignatureKey,
state::ConsensusTime,
},
vote2::Certificate2,
};

/// A certificate which can be created by aggregating many simple votes on the commitment.
#[derive(Eq, Hash, PartialEq, Debug, Clone)]
pub struct SimpleCertificate<TYPES: NodeType, VOTEABLE: Voteable, MEMBERSHIP: Membership<TYPES>> {
bfish713 marked this conversation as resolved.
Show resolved Hide resolved
/// commitment to previous leaf which all the votes in this certificate are voting on
pub leaf_commitment: VOTEABLE,
bfish713 marked this conversation as resolved.
Show resolved Hide resolved
/// commitment of all the votes this cert should be signed over
pub vote_commitment: Commitment<VOTEABLE>,
/// Which view this QC relates to
pub view_number: TYPES::Time,
/// assembled signature for certificate aggregation
pub signatures: <TYPES::SignatureKey as SignatureKey>::QCType,
/// If this QC is for the genesis block
pub is_genesis: bool,
/// phantom data for `MEMBERSHIP` and `TYPES`
_pd: PhantomData<(TYPES, MEMBERSHIP)>,
}

impl<TYPES: NodeType, VOTEABLE: Voteable + 'static, MEMBERSHIP: Membership<TYPES>>
Certificate2<TYPES> for SimpleCertificate<TYPES, VOTEABLE, MEMBERSHIP>
{
type Voteable = VOTEABLE;
type Membership = MEMBERSHIP;

fn create_signed_certificate(
vote_commitment: Commitment<VOTEABLE>,
data: Self::Voteable,
sig: <TYPES::SignatureKey as SignatureKey>::QCType,
view: TYPES::Time,
) -> Self {
SimpleCertificate {
leaf_commitment: data,
vote_commitment,
view_number: view,
signatures: sig,
is_genesis: false,
_pd: PhantomData,
}
}
fn is_valid_cert(
&self,
vote_commitment: Commitment<VOTEABLE>,
membership: &MEMBERSHIP,
) -> bool {
if vote_commitment != self.vote_commitment {
return false;
}
if self.is_genesis && self.view_number == TYPES::Time::genesis() {
return true;
}
let real_qc_pp = <TYPES::SignatureKey as SignatureKey>::get_public_parameter(
membership.get_committee_qc_stake_table(),
U256::from(membership.success_threshold().get()),
);
<TYPES::SignatureKey as SignatureKey>::check(
&real_qc_pp,
vote_commitment.as_ref(),
&self.signatures,
)
}
fn threshold(membership: &MEMBERSHIP) -> u64 {
membership.success_threshold().into()
}
fn get_data(&self) -> &Self::Voteable {
&self.leaf_commitment
}
fn get_data_commitment(&self) -> Commitment<Self::Voteable> {
self.vote_commitment
}
}

// Type aliases for simple use of all the main votes. We should never see `SimpleVote` outside this file
pub type QuorumCertificate2<TYPES, LEAF, M> = SimpleCertificate<TYPES, YesData<LEAF>, M>;
Loading