Skip to main content

linera_chain/data_types/proof/
objects.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Protocol objects: the definitions the rest of the specification is phrased in.
5//!
6//! These are definitions, not claims, so they carry no proof and no dependency edges. Each one
7//! pins a piece of specification vocabulary to the Rust item that realizes it, so that later
8//! statements can talk about "a validation vote in round `r`" while still being checkable
9//! against the implementation.
10
11/// **Definition (Signed vote payload).** A validator never signs a bare value; it signs a
12/// [`VoteValue`], the six-tuple
13///
14/// ```text
15/// (value_hash, round, kind, unlocking_round, first_round, justification_commitment)
16/// ```
17///
18/// where `kind` is a [`CertificateKind`]. [`VoteValue`] implements
19/// [`BcsSignable`](linera_base::crypto::BcsSignable), so the signed byte string is the BCS
20/// encoding of that tuple prefixed by the type name. Two payloads differing in any component are
21/// distinct signed messages, and a signature over one is not a signature over the other.
22///
23/// Throughout the specification, "a validator signed *X*" means: it produced a
24/// [`ValidatorSignature`](linera_base::crypto::ValidatorSignature) over the [`VoteValue`] whose
25/// components are *X*.
26///
27/// [`VoteValue`]: crate::data_types::VoteValue
28/// [`CertificateKind`]: crate::types::CertificateKind
29pub trait SignedVotePayload {}
30
31/// **Definition (Vote).** A *vote* by validator `v` is a [`Vote<T>`], or equivalently its
32/// projection [`LiteVote`], which keeps every signed field and drops only the value body. Its
33/// *round* is [`Vote::round`] and its *kind* is `T::KIND`. We say:
34///
35/// * a **validation vote**, when the kind is [`CertificateKind::Validated`] — the voter asserts
36///   the block is valid at this height;
37/// * a **confirmation vote**, when the kind is [`CertificateKind::Confirmed`] — the voter
38///   asserts the block is final;
39/// * a **timeout vote**, when the kind is [`CertificateKind::Timeout`] — the voter asserts its
40///   round timer for this height expired.
41///
42/// Votes are produced by exactly three constructors — [`Vote::new`],
43/// [`Vote::new_with_unlocking_round`] and [`Vote::new_with_first_round`] — each signing the
44/// [`SignedVotePayload`] built from its arguments. Which of them a correct validator may call,
45/// and when, is pinned down by [`VoteConstructionSites`].
46///
47/// [`Vote<T>`]: crate::data_types::Vote
48/// [`LiteVote`]: crate::data_types::LiteVote
49/// [`Vote::round`]: crate::data_types::Vote::round
50/// [`Vote::new`]: crate::data_types::Vote::new
51/// [`Vote::new_with_unlocking_round`]: crate::data_types::Vote::new_with_unlocking_round
52/// [`Vote::new_with_first_round`]: crate::data_types::Vote::new_with_first_round
53/// [`CertificateKind::Validated`]: crate::types::CertificateKind::Validated
54/// [`CertificateKind::Confirmed`]: crate::types::CertificateKind::Confirmed
55/// [`CertificateKind::Timeout`]: crate::types::CertificateKind::Timeout
56/// [`VoteConstructionSites`]: crate::manager::proof::voting::VoteConstructionSites
57pub trait ValidatorVote {}
58
59/// **Definition (Proposal).** A *proposal* is a [`BlockProposal`]: an owner's signature over a
60/// [`ProposalContent`] — a [`ProposedBlock`], a [`Round`](linera_base::data_types::Round) and an
61/// optional [`BlockExecutionOutcome`] — plus an optional [`OriginalProposal`] recording which
62/// earlier attempt it retries. The three retry shapes are:
63///
64/// * `original_proposal == None`: a **fresh proposal**, carrying no outcome;
65/// * [`OriginalProposal::Fast`]: a **fast retry**, re-proposing a block first proposed in
66///   [`Round::Fast`](linera_base::data_types::Round::Fast), carrying the super owner's original
67///   signature and no outcome;
68/// * [`OriginalProposal::Regular`]: a **regular retry**, re-proposing a block that already
69///   carries a [`ValidatedBlockCertificate`], carrying that certificate and the outcome it
70///   certifies.
71///
72/// [`BlockProposal::check_invariants`] enforces that exactly these three shapes are well-formed,
73/// that a retry's round is *strictly greater* than the round it retries, and that a regular
74/// retry's certificate certifies exactly the block and outcome being re-proposed. The
75/// specification uses all three facts.
76///
77/// [`BlockProposal`]: crate::data_types::BlockProposal
78/// [`BlockProposal::check_invariants`]: crate::data_types::BlockProposal::check_invariants
79/// [`ProposalContent`]: crate::data_types::ProposalContent
80/// [`ProposedBlock`]: crate::data_types::ProposedBlock
81/// [`BlockExecutionOutcome`]: crate::data_types::BlockExecutionOutcome
82/// [`OriginalProposal`]: crate::data_types::OriginalProposal
83/// [`OriginalProposal::Fast`]: crate::data_types::OriginalProposal::Fast
84/// [`OriginalProposal::Regular`]: crate::data_types::OriginalProposal::Regular
85/// [`ValidatedBlockCertificate`]: crate::types::ValidatedBlockCertificate
86pub trait SignedProposal {}
87
88/// **Definition (Certificate).** A *certificate* is a [`GenericCertificate<T>`] together with
89/// the [`JustificationChain`] its wrapper carries. The three instantiations are
90/// [`ValidatedBlockCertificate`], [`ConfirmedBlockCertificate`] and [`TimeoutCertificate`].
91///
92/// A certificate is **valid for a committee** when its `check` returns `Ok`. Both block
93/// certificate types delegate to [`LiteCertificate::check`], which verifies the signatures, the
94/// justification chain, and the binding between the two; [`TimeoutCertificate`], being a
95/// [`GenericCertificate`] alias, uses [`GenericCertificate::check`], which verifies the
96/// signatures and carries no chain. Unless said otherwise, "certificate" in this specification
97/// means one that is valid for the committee of its epoch; what that buys us is
98/// [`CertificateEmbedsQuorum`], [`CertificateSignaturesVerify`] and
99/// [`CertificateCarriesCorrectVote`].
100///
101/// [`GenericCertificate<T>`]: crate::types::GenericCertificate
102/// [`JustificationChain`]: crate::justification::JustificationChain
103/// [`ValidatedBlockCertificate`]: crate::types::ValidatedBlockCertificate
104/// [`ConfirmedBlockCertificate`]: crate::types::ConfirmedBlockCertificate
105/// [`TimeoutCertificate`]: crate::types::TimeoutCertificate
106/// [`LiteCertificate::check`]: crate::types::LiteCertificate::check
107/// [`GenericCertificate`]: crate::types::GenericCertificate
108/// [`GenericCertificate::check`]: crate::types::GenericCertificate::check
109/// [`CertificateSignaturesVerify`]: super::quorum::CertificateSignaturesVerify
110/// [`CertificateEmbedsQuorum`]: super::quorum::CertificateEmbedsQuorum
111/// [`CertificateCarriesCorrectVote`]: super::quorum::CertificateCarriesCorrectVote
112pub trait Certificate {}
113
114/// **Definition (Unlocking round).** The *unlocking round* of a validation vote,
115/// [`Vote::unlocking_round`], is the round a validator signs to assert: *"I have not cast a
116/// confirmation vote for a block other than this one in any round at or above this one."*
117/// `None` denotes the strongest form of that claim, covering every round.
118///
119/// The unlocking round exists for **fault attribution**, not for agreement: it makes a validator
120/// that breaks its lock convictable from the certificates alone, via
121/// [`extract_equivocations`]. The agreement argument in [`crate::manager::proof::safety`]
122/// deliberately does *not* rely on it, and reasons instead about the state a correct validator
123/// keeps in its [`ChainManager`] — so that agreement holds even where the attribution machinery
124/// is only as strong as the honest-construction obligations recorded in
125/// [`crate::justification`].
126///
127/// [`Vote::unlocking_round`]: crate::data_types::Vote::unlocking_round
128/// [`extract_equivocations`]: crate::justification::extract_equivocations
129/// [`ChainManager`]: crate::manager::ChainManager
130pub trait UnlockingRound {}
131
132/// **Definition (Justification commitment).** The *justification commitment* of a vote is the
133/// hash of the [`CommittedQuorum`] it cites, which — because that struct embeds the commitment
134/// of the quorum below it — transitively commits to the entire chain of validated quorums
135/// underneath. It is one of the six components of the [`SignedVotePayload`], so votes citing
136/// different chains are votes on different payloads and never aggregate into one certificate.
137///
138/// [`CommittedQuorum`]: crate::justification::CommittedQuorum
139pub trait JustificationCommitment {}