pub trait InvalidJustificationSoundness:
UnforgeableSignatures
+ VoteConstructionSites
+ MisbehaviourProof { }Expand description
Lemma (Attested justifications are never honestly invalid). No correct validator is named
by an accepted InvalidJustification proof, when the proof is adjudicated against the
committee of the vote’s own epoch (MisbehaviourProof).
Proof. An accepted proof exhibits v’s signature over a VoteValue whose justification
commitment is opening.commitment(), together with an opening on which check_cited_quorum
fails. By UnforgeableSignatures a correct v produced that signature, so it is one of the
five sites of VoteConstructionSites. Take them in turn.
ChainManager::create_timeout_vote,ChainManager::vote_fallback, and the fast branch ofChainManager::create_voteall sign a commitment ofNone. A proof requiresSome(opening.commitment()), so its signature check fails and it is not accepted.- The non-fast branch of
ChainManager::create_vote, on a regular retry. It signsunlocking_round = Some(c.round)andSome(c.full_justification_commitment()), whose opening isc‘s own quorum.check_cited_quorumthen asks exactly the four things that verifyingcalready established: that the opening’svalue_hashis the voted block’s hash (given byBlockProposal::check_invariants, which bindscto the proposed block); thatunlocking_round == Some(opening.round)andopening.round < round(the first by construction, the second bycheck_invariants’content.round > certificate.round); that the opening’s own unlocking round and previous commitment are both present or both absent (fromLiteCertificate::check, where aValidatedcertificate’sunlocking_roundequals its chain’s top and its commitment isNoneexactly when the chain is empty); and that the opening’s signatures form a quorum over the reconstructedValidatedpayload — which is verbatim the checkLiteCertificate::checkperformed onc, thefirst_roundcomponent beingfalsefor everyValidatedBlockCertificate. A fresh or fast-retry proposal signsNoneand is covered by the first case. ChainManager::create_final_vote. It signsunlocking_round = None,Some(validated.full_justification_commitment())— orNonein the chain’s first round, again covered above — in the roundvalidated.round. Forkind = Confirmedcheck_cited_quorumrequiresopening.round == round, which holds since the vote’s round isvalidated.round; the remaining conditions are as in the previous case,validatedhaving been verified by the caller (ConfirmationNeedsValidatedCertificate). ∎