pub enum ConsensusMessage {
Proposal {
block: Box<Block>,
proposer: String,
round: u64,
high_qc_view: u64,
timeout_certificate: Option<Vec<u8>>,
no_endorsement_certificate: Option<Vec<u8>>,
},
Vote {
block_hash: Hash,
voter: String,
vote_type: VoteType,
round: u64,
height: u64,
high_qc_view: u64,
signature: Vec<u8>,
public_key: Vec<u8>,
bls_signature: Vec<u8>,
},
Commit {
block_hash: Hash,
signatures: Vec<Vec<u8>>,
},
Timeout {
format_version: u8,
view: u64,
high_qc_view: u64,
finalized_height: u64,
voter: Address,
signature: Vec<u8>,
public_key: Vec<u8>,
},
NoEndorsement {
format_version: u8,
view: u64,
voter: Address,
signature: Vec<u8>,
public_key: Vec<u8>,
},
}Expand description
Consensus message types.
Uses serde’s default externally-tagged enum representation. See
MessagePayload above for the rationale — #[serde(tag = "...")] is
internally-tagged and incompatible with bincode 1.x.
Variants§
Proposal
Block proposal.
timeout_certificate is Some(_) only when the leader is recovering
from a view timeout — it carries the bincode-serialized
tenzro_consensus::timeout::TimeoutCertificate (2f+1 timeout signatures
from the previous view) so peers can verify the new view was
legitimately abandoned (Jolteon safe_to_extend, DiemBFT v4 §3.5).
high_qc_view is the proposer’s local highest-Prepare-QC view at the
moment of proposing (#171, Aptos SyncInfo pattern). Receivers adopt it
if higher than their own to fast-forward the lagging-replica case.
Must satisfy high_qc_view < block.header.view.
Fields
timeout_certificate: Option<Vec<u8>>bincode-serialized tenzro_consensus::timeout::TimeoutCertificate,
or None for the steady-state happy path.
no_endorsement_certificate: Option<Vec<u8>>bincode-serialized
tenzro_consensus::timeout::NoEndorsementCertificate. Carries f+1
no-endorsement signatures attesting that no Prepare-QC formed at
the timed-out view (MonadBFT, arXiv:2502.20692). Some(_) is
required when the leader is proposing a fresh block after a TC
— receivers reject an unaccompanied fresh block. None for the
steady-state happy path AND when the leader is reproposing the
existing high-tip block (the parent-hash match suffices).
Vote
Vote on a proposal
Carries a hybrid (Ed25519 + ML-DSA-65) signature and the voter’s
composite public key so peers can verify both legs without an
out-of-band registry lookup. The two opaque blobs are bincode-
serialized CompositeSignature / CompositePublicKey from
tenzro_crypto::composite.
high_qc_view is the voter’s local highest-Prepare-QC view at the
moment of voting (#171, Aptos SyncInfo). Bound into the vote’s signing
payload — must match the bound on the inner Vote or signature
verification fails.
Fields
Commit
Commit message
Timeout
Pacemaker timeout broadcast (DiemBFT v4 §3.5).
Sent on local view-timer expiry. Receivers at a strictly lower view
adopt view after verifying the sender’s hybrid signature — the
signature is the cryptographic gate (DiemBFT v4 §3.5
process_remote_timeout); no numeric jump cap is applied, since
stuck replicas may legitimately need to sync forward by many
thousands of views. This is the backward-sync channel that
prevents two honest replicas from drifting apart under partial
synchrony.
The two opaque blobs are bincode-serialized CompositeSignature /
CompositePublicKey from tenzro_crypto::composite, mirroring the
Vote variant. Format version is pinned by
tenzro_consensus::TIMEOUT_MSG_FORMAT_VERSION.
Fields
high_qc_view: u64Highest Prepare-QC view this voter has observed (≤ view - 1).
Aggregated by the receiver into the TC’s max_high_qc_view() so
the next leader can compute the Jolteon safe_to_extend predicate.
NoEndorsement
MonadBFT no-endorsement attestation broadcast (arXiv:2502.20692).
Sent on local view-timer expiry alongside the Timeout broadcast.
Aggregated by the receiver into a NoEndorsementCertificate (f+1
signatures) which the next leader attaches to a fresh block proposal
after the timed-out view. The f+1 threshold is the smallest set that
guarantees at least one honest signer — and any honest signer would
refuse to sign if it had observed a Prepare-QC at the timed-out view,
so the NEC is unforgeable evidence that no QC formed.
The two opaque blobs mirror the Vote / Timeout variants — bincode-
serialized CompositeSignature / CompositePublicKey. Format version
is pinned by tenzro_consensus::NO_ENDORSEMENT_MSG_FORMAT_VERSION.
Trait Implementations§
Source§impl Clone for ConsensusMessage
impl Clone for ConsensusMessage
Source§fn clone(&self) -> ConsensusMessage
fn clone(&self) -> ConsensusMessage
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ConsensusMessage
impl Debug for ConsensusMessage
Source§impl<'de> Deserialize<'de> for ConsensusMessage
impl<'de> Deserialize<'de> for ConsensusMessage
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for ConsensusMessage
impl RefUnwindSafe for ConsensusMessage
impl Send for ConsensusMessage
impl Sync for ConsensusMessage
impl Unpin for ConsensusMessage
impl UnsafeUnpin for ConsensusMessage
impl UnwindSafe for ConsensusMessage
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more