Pull out consensus liveness fix, which went to #1815

This commit is contained in:
Jae Kwon
2018-08-02 01:59:46 -07:00
parent 24ae878b9f
commit eb9b37e196
4 changed files with 38 additions and 209 deletions
+3 -28
View File
@@ -7,7 +7,6 @@ import (
"io/ioutil"
"os"
"path"
"reflect"
"sort"
"sync"
"testing"
@@ -18,14 +17,14 @@ import (
bc "github.com/tendermint/tendermint/blockchain"
cfg "github.com/tendermint/tendermint/config"
cstypes "github.com/tendermint/tendermint/consensus/types"
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
mempl "github.com/tendermint/tendermint/mempool"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/privval"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types"
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/abci/example/counter"
"github.com/tendermint/tendermint/abci/example/kvstore"
@@ -326,30 +325,6 @@ func ensureNewStep(stepCh <-chan interface{}) {
}
}
func ensureVote(voteCh chan interface{}, height int64, round int, voteType byte) {
timer := time.NewTimer(ensureTimeout)
select {
case <-timer.C:
break
case v := <-voteCh:
edv, ok := v.(types.EventDataVote)
if !ok {
panic(fmt.Sprintf("expected a *types.Vote, got %v. wrong subscription channel?",
reflect.TypeOf(v)))
}
vote := edv.Vote
if vote.Height != height {
panic(fmt.Sprintf("expected height %v, got %v", height, vote.Height))
}
if vote.Round != round {
panic(fmt.Sprintf("expected round %v, got %v", round, vote.Round))
}
if vote.Type != voteType {
panic(fmt.Sprintf("expected type %v, got %v", voteType, vote.Type))
}
}
}
//-------------------------------------------------------------------------------
// consensus nets
+6 -11
View File
@@ -1014,11 +1014,9 @@ func (cs *ConsensusState) enterPrevoteWait(height int64, round int) {
logger.Debug(cmn.Fmt("enterPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
return
}
/*
if !cs.Votes.Prevotes(round).HasTwoThirdsAny() {
cmn.PanicSanity(cmn.Fmt("enterPrevoteWait(%v/%v), but Prevotes does not have any +2/3 votes", height, round))
}
*/
if !cs.Votes.Prevotes(round).HasTwoThirdsAny() {
cmn.PanicSanity(cmn.Fmt("enterPrevoteWait(%v/%v), but Prevotes does not have any +2/3 votes", height, round))
}
logger.Info(cmn.Fmt("enterPrevoteWait(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step))
defer func() {
@@ -1587,7 +1585,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool,
if prevotes.HasTwoThirdsMajority() {
cs.enterPrecommit(height, vote.Round)
} else {
cs.enterPropose(height, vote.Round) // we can't prevote until we wait for the proposal.
cs.enterPrevote(height, vote.Round) // if the vote is ahead of us
cs.enterPrevoteWait(height, vote.Round)
}
} else if cs.Proposal != nil && 0 <= cs.Proposal.POLRound && cs.Proposal.POLRound == vote.Round {
@@ -1603,9 +1601,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool,
blockID, ok := precommits.TwoThirdsMajority()
if ok {
if len(blockID.Hash) == 0 {
cs.enterNewRound(height, vote.Round)
cs.enterPrecommit(height, vote.Round)
cs.enterPrecommitWait(height, vote.Round)
cs.enterNewRound(height, vote.Round+1)
} else {
cs.enterNewRound(height, vote.Round)
cs.enterPrecommit(height, vote.Round)
@@ -1621,8 +1617,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool,
}
} else if cs.Round <= vote.Round && precommits.HasTwoThirdsAny() {
cs.enterNewRound(height, vote.Round)
cs.enterPrevote(height, vote.Round)
cs.enterPrevoteWait(height, vote.Round)
cs.enterPrecommit(height, vote.Round)
cs.enterPrecommitWait(height, vote.Round)
}
default:
+11 -15
View File
@@ -64,22 +64,22 @@ func TestStateProposerSelection0(t *testing.T) {
startTestRound(cs1, height, round)
// Wait for new round so proposer is set.
// wait for new round so proposer is set
<-newRoundCh
// Commit a block and ensure proposer for the next height is correct.
// lets commit a block and ensure proposer for the next height is correct
prop := cs1.GetRoundState().Validators.GetProposer()
if !bytes.Equal(prop.Address, cs1.privValidator.GetAddress()) {
t.Fatalf("expected proposer to be validator %d. Got %X", 0, prop.Address)
}
// Wait for complete proposal.
// wait for complete proposal
<-proposalCh
rs := cs1.GetRoundState()
signAddVotes(cs1, types.VoteTypePrecommit, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:]...)
// Wait for new round so next validator is set.
// wait for new round so next validator is set
<-newRoundCh
prop = cs1.GetRoundState().Validators.GetProposer()
@@ -718,8 +718,6 @@ func TestStateLockPOLUnlock(t *testing.T) {
func TestStateLockPOLSafety1(t *testing.T) {
cs1, vss := randConsensusState(4)
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
h := cs1.GetRoundState().Height
r := cs1.GetRoundState().Round
partSize := cs1.state.ConsensusParams.BlockPartSizeBytes
@@ -736,7 +734,7 @@ func TestStateLockPOLSafety1(t *testing.T) {
rs := re.(types.EventDataRoundState).RoundState.(*cstypes.RoundState)
propBlock := rs.ProposalBlock
ensureVote(voteCh, h, r, types.VoteTypePrevote)
<-voteCh // prevote
validatePrevote(t, cs1, 0, vss[0], propBlock.Hash())
@@ -757,11 +755,6 @@ func TestStateLockPOLSafety1(t *testing.T) {
// we do see them precommit nil
signAddVotes(cs1, types.VoteTypePrecommit, nil, types.PartSetHeader{}, vs2, vs3, vs4)
ensureVote(voteCh, h, r, types.VoteTypePrecommit)
<-newRoundCh
t.Log("### ONTO ROUND 1")
prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1)
propBlockHash := propBlock.Hash()
propBlockParts := propBlock.MakePartSet(partSize)
@@ -772,6 +765,9 @@ func TestStateLockPOLSafety1(t *testing.T) {
if err := cs1.SetProposalAndBlock(prop, propBlock, propBlockParts, "some peer"); err != nil {
t.Fatal(err)
}
<-newRoundCh
t.Log("### ONTO ROUND 1")
/*Round2
// we timeout and prevote our lock
// a polka happened but we didn't see it!
@@ -792,13 +788,13 @@ func TestStateLockPOLSafety1(t *testing.T) {
}
t.Logf("new prop hash %v", fmt.Sprintf("%X", propBlockHash))
// go to prevote, prevote for proposal block
ensureVote(voteCh, h, r+1, types.VoteTypePrevote)
<-voteCh
validatePrevote(t, cs1, 1, vss[0], propBlockHash)
// now we see the others prevote for it, so we should lock on it
signAddVotes(cs1, types.VoteTypePrevote, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4)
ensureVote(voteCh, h, r+1, types.VoteTypePrecommit)
<-voteCh // precommit
// we should have precommitted
validatePrecommit(t, cs1, 1, 1, vss[0], propBlockHash, propBlockHash)
@@ -820,7 +816,7 @@ func TestStateLockPOLSafety1(t *testing.T) {
<-timeoutProposeCh
// finish prevote
ensureVote(voteCh, h, r+2, types.VoteTypePrevote)
<-voteCh
// we should prevote what we're locked on
validatePrevote(t, cs1, 2, vss[0], propBlockHash)