From d04a2c8a5d2e046dc4ca769bffd3b0d35b7c2075 Mon Sep 17 00:00:00 2001 From: William Banfield Date: Wed, 15 Dec 2021 14:13:03 -0500 Subject: [PATCH] add precommit case as well --- internal/consensus/state.go | 8 +++++++- internal/consensus/state_test.go | 32 +++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/internal/consensus/state.go b/internal/consensus/state.go index 8f383c2fb..79ae63b3b 100644 --- a/internal/consensus/state.go +++ b/internal/consensus/state.go @@ -1480,9 +1480,15 @@ func (cs *State) enterPrecommit(height int64, round int32) { cs.signAddVote(tmproto.PrecommitType, nil, types.PartSetHeader{}) return } - // At this point, +2/3 prevoted for a particular block. + // If the proposal time does not match the block time, precommit nil. + if !cs.Proposal.Timestamp.Equal(cs.ProposalBlock.Header.Time) { + logger.Debug("proposal timestamp not equal, prevoting nil") + cs.signAddVote(tmproto.PrecommitType, nil, types.PartSetHeader{}) + return + } + // If we're already locked on that block, precommit it, and update the LockedRound if cs.LockedBlock.HashesTo(blockID.Hash) { logger.Debug("precommit step; +2/3 prevoted locked block; relocking") diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index 95f250ddc..a23f6cc1e 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -2658,13 +2658,16 @@ func TestStateTimestamp_ProposalNotMatch(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - cs1, vss, err := makeState(ctx, config, logger, 2) + cs1, vss, err := makeState(ctx, config, logger, 4) require.NoError(t, err) height, round := cs1.Height, cs1.Round - vs2 := vss[1] + vs2, vs3, vs4 := vss[1], vss[2], vss[3] proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal) - voteCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryVote) + pv1, err := cs1.privValidator.GetPubKey(ctx) + require.NoError(t, err) + addr := pv1.Address() + voteCh := subscribeToVoter(ctx, t, cs1, addr) propBlock, _ := cs1.createProposalBlock() round++ @@ -2680,14 +2683,19 @@ func TestStateTimestamp_ProposalNotMatch(t *testing.T) { t.Fatal("failed to sign bad proposal", err) } proposal.Signature = p.Signature -require.NoError(t, cs1.SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer")) + require.NoError(t, cs1.SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer")) startTestRound(ctx, cs1, height, round) ensureProposal(t, proposalCh, height, round, blockID) + signAddVotes(ctx, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2, vs3, vs4) + // ensure that the validator prevotes nil. ensurePrevote(t, voteCh, height, round) validatePrevote(ctx, t, cs1, round, vss[0], nil) + + ensurePrecommit(t, voteCh, height, round) + validatePrecommit(ctx, t, cs1, round, -1, vss[0], nil, nil) } // TestStateTimestamp_ProposalMatch tests that a validator prevotes a @@ -2699,13 +2707,16 @@ func TestStateTimestamp_ProposalMatch(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - cs1, vss, err := makeState(ctx, config, logger, 2) + cs1, vss, err := makeState(ctx, config, logger, 4) require.NoError(t, err) height, round := cs1.Height, cs1.Round - vs2 := vss[1] + vs2, vs3, vs4 := vss[1], vss[2], vss[3] proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal) - voteCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryVote) + pv1, err := cs1.privValidator.GetPubKey(ctx) + require.NoError(t, err) + addr := pv1.Address() + voteCh := subscribeToVoter(ctx, t, cs1, addr) propBlock, _ := cs1.createProposalBlock() round++ @@ -2722,15 +2733,18 @@ func TestStateTimestamp_ProposalMatch(t *testing.T) { } proposal.Signature = p.Signature require.NoError(t, cs1.SetProposalAndBlock(proposal, propBlock, propBlockParts, "some peer")) - t.Fatal(err) - } startTestRound(ctx, cs1, height, round) ensureProposal(t, proposalCh, height, round, blockID) + signAddVotes(ctx, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vs2, vs3, vs4) + // ensure that the validator prevotes the block. ensurePrevote(t, voteCh, height, round) validatePrevote(ctx, t, cs1, round, vss[0], propBlock.Hash()) + + ensurePrecommit(t, voteCh, height, round) + validatePrecommit(ctx, t, cs1, round, 1, vss[0], propBlock.Hash(), propBlock.Hash()) } // subscribe subscribes test client to the given query and returns a channel with cap = 1.