[CORE-435] Prevote yes on recent valid POL Proposal#14
[CORE-435] Prevote yes on recent valid POL Proposal#14teddyding merged 3 commits intodydx-fork-v0.37.2from
Conversation
d5a6ff2 to
ddcc8d6
Compare
| } | ||
|
|
||
| // Determine if the proposed block has a sane, non-nil proof-of-lock. | ||
| if cs.Proposal.POLRound >= 0 && cs.Proposal.POLRound < cs.Round { |
There was a problem hiding this comment.
This new case only takes effect when LockedBlock == nil, due to line 1275
This is a conscious choice to bring minimal code changes to current CometBFT implementation in this PR
We only merge the LockedBlock fix above in a follow-up PR. See https://linear.app/dydx/issue/CORE-434/merge-locked-block-logic-fix
consensus/state.go
Outdated
| } | ||
|
|
||
| // Validate the proposed block is equal to our locked block. | ||
| if cs.ProposalBlock.HashesTo(cs.LockedBlock.Hash()) { |
There was a problem hiding this comment.
Currently this line won't be true due to line 1275
|
Can you help me understand Nvm, you explained this here:
|
|
Nit on PR title: |
nit: In the PR description's justification, should it read |
6250a78 to
ddcc8d6
Compare
| if ok && cs.ProposalBlock.HashesTo(blockID.Hash) { | ||
| // Validate the proof-of-lock round is at least as new as the possible locked round. | ||
| // (vr >= 0, vr > round_p, 2f+1 prevotes at round vr, lockedRound_p <= vr) execute 30. | ||
| if cs.Proposal.POLRound >= cs.LockedRound { |
There was a problem hiding this comment.
Before we merge the locked block fix, we will only reach here when LockedRound == -1 and LockedBlock == nil .
In the context of the recent liveness outage, this means that at round 1:
- validators who precommited and locked during round 0 will continue to vote for
B0(duet to line 1275) - validators who are not locked will also prevote for
B0since they will verify atPOLRound == 0, they also witnessed 2/3+ prevotes
|
TODO(CORE-436): Add unit test for logic change in a follow PR. The unit test setup is quite complicated and it should not block trying out the change in |
| if ok && cs.ProposalBlock.HashesTo(blockID.Hash) { | ||
| // Validate the proof-of-lock round is at least as new as the possible locked round. | ||
| // (vr >= 0, vr > round_p, 2f+1 prevotes at round vr, lockedRound_p <= vr) execute 30. | ||
| if cs.Proposal.POLRound >= cs.LockedRound { |
There was a problem hiding this comment.
can we add a comment that we are skipping valid(v) here?
| logger := cs.Logger.With("height", height, "round", round) | ||
|
|
||
| // If a block is locked, prevote that. | ||
| // TODO(CORE-434): Incorporate fix from Proposer-based Timestamp. |
There was a problem hiding this comment.
nit: do we have TODOs or tickets for unit tests?
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
* prevote any valid POL Proposal * add docmentation and reference to paper * add nits --------- Co-authored-by: Teddy Ding <teddy@dydx.exchange>
Description
If a proposal with a proof-of-lock (POL) is proposed, validate both of the following two lines:
Proposed Block = Locked BlockORPOL Round >= Locked Round(Line 29 of whitepaper algorithm)If these two things both evaluate to
true, then prevote the block without consulting the Application (i.e. without callingProcessProposal) to determine the validity of the block.If either of these two checks evaluate to
false, then prevote nil. Even if the block is valid, we don't prevote for the block. (Line 29/31 of whitepaper algorithm)This change is aimed at fixing the liveness issue experienced in public testnet 1.
Implementation
Unfortunately it looks more complicated than necessary primarily because we need the
Debugstatements to say different things in different cases, so there are two places to prevote the block and two places to prevote nil (rather than just having one each).Justification
It should be fine to not consult the Application to validate the block in the above case. To show this, let us first state that
ProcessProposalmay have both deterministic and non-deterministic validation.ProcessProposal(and therefore its deterministic checks) MUST have passed at least one honest validator. Therefore, there no need to run the deterministic checks locally.References
Based on some logic added for the PBTS here
This logic is also largely the same as lines 28-32 on page 6 of the Tendermint whitepaper, however we do not validate the block with the Application (i.e.
ProcessProposal) to determinevalid(v). As I have justified above, this check tovalid(v)is unnecessary assuming <2/3 Byzantine validators.