pub trait ProposalAccepted:
EventuallyCorrectLeader
+ RoundAdvancement
+ LockRecovery
+ ProposalGate
+ UnlockingRequiresHigherCertificate
+ LeaderEligibility { }Expand description
Lemma (A recovered proposal is accepted). Let r be a SingleLeader or Validator
round beginning after GST whose leader is the correct driver’s owner
(EventuallyCorrectLeader), let every correct validator be in round r
(RoundAdvancement), and let the driver have completed lock recovery
(LockRecovery). Then the proposal the driver submits in round r passes
ChainManager::check_proposed_block at every correct validator.
Proof. By ProposalGate acceptance is exactly check_proposed_block returning
Accept, so we take its guards in order, for a correct validator v in round r.
- Proposer eligibility.
try_handle_block_proposalrequireschain.manager.can_propose(&owner, r), which holds byLeaderEligibilitysince the driver isr’s leader; the driver selectsrthroughChainClient::round_for_new_proposal, which consults the sameChainManagerInfo::should_propose. - Round. The
SingleLeader(_) | Validator(_)arm requiresr == v.current_round(), which is the hypothesis. - Validation vote. Requires
r > v.validated_vote.round. ByVoteRoundBelowCurrentRoundany earlier validation vote ofvis in a round≤ v.current_round() = r, and= ris excluded: a vote in roundrneeds a proposal in roundraccepted byv, and byLeaderEligibilitythe only proposervaccepts inris the driver, which has made no other proposal inr. - Lock. Requires
r > v.locking_block.round(). A lock round aboverwould byRoundFloorputv.current_round()abover, contradicting the hypothesis; and a lock round equal torwould require aValidatedBlockCertificatein roundr, which byCertificateCarriesCorrectVotewould require a correct validator’s validation vote in roundr— excluded by the previous point. - Confirmed vote. This is the one that needs
LockRecovery. Ifvhas a confirmed vote in roundp, then byLockRecoverythe driver’s recovered lock has roundt ≥ pand certifies the same blockBthatvconfirmed ift = p. The driver proposesBas aRegularretry carrying that certificate (process_pending_block_innertakes theif let Some(locking) = info.manager.requested_lockingbranch and buildsBlockProposal::new_retry_regular). ByUnlockingRequiresHigherCertificatethe guard then requiresp ≤ twhen the blocks match, which holds. (Whent > pand the blocks differ, the guard requiresp < t, which also holds.)
A LockingBlock::Fast lock is retried as BlockProposal::new_retry_fast, and the same guard
requires v.confirmed_vote.round.is_fast() and a matching block, which holds because a fast
confirmation is the only confirmation possible below the fast round’s successor. ∎