|
|
@ -56,9 +56,9 @@ x * TestHalt1 - if we see +2/3 precommits after timing out into new round, we sh |
|
|
|
// ProposeSuite
|
|
|
|
|
|
|
|
func TestStateProposerSelection0(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
|
newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) |
|
|
@ -82,7 +82,7 @@ func TestStateProposerSelection0(t *testing.T) { |
|
|
|
ensureNewProposal(proposalCh, height, round) |
|
|
|
|
|
|
|
rs := cs1.GetRoundState() |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:]...) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:]...) |
|
|
|
|
|
|
|
// Wait for new round so next validator is set.
|
|
|
|
ensureNewRound(newRoundCh, height+1, 0) |
|
|
@ -98,9 +98,9 @@ func TestStateProposerSelection0(t *testing.T) { |
|
|
|
|
|
|
|
// Now let's do it all again, but starting from round 2 instead of 0
|
|
|
|
func TestStateProposerSelection2(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) // test needs more work for more than 3 validators
|
|
|
|
cs1, vss := randState(config, 4) // test needs more work for more than 3 validators
|
|
|
|
height := cs1.Height |
|
|
|
newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) |
|
|
|
|
|
|
@ -128,7 +128,7 @@ func TestStateProposerSelection2(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
rs := cs1.GetRoundState() |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, rs.ProposalBlockParts.Header(), vss[1:]...) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, rs.ProposalBlockParts.Header(), vss[1:]...) |
|
|
|
ensureNewRound(newRoundCh, height, i+round+1) // wait for the new round event each round
|
|
|
|
incrementRound(vss[1:]...) |
|
|
|
} |
|
|
@ -137,9 +137,9 @@ func TestStateProposerSelection2(t *testing.T) { |
|
|
|
|
|
|
|
// a non-validator should timeout into the prevote round
|
|
|
|
func TestStateEnterProposeNoPrivValidator(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs, _ := randState(1) |
|
|
|
cs, _ := randState(config, 1) |
|
|
|
cs.SetPrivValidator(nil) |
|
|
|
height, round := cs.Height, cs.Round |
|
|
|
|
|
|
@ -158,9 +158,9 @@ func TestStateEnterProposeNoPrivValidator(t *testing.T) { |
|
|
|
|
|
|
|
// a validator should not timeout of the prevote round (TODO: unless the block is really big!)
|
|
|
|
func TestStateEnterProposeYesPrivValidator(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs, _ := randState(1) |
|
|
|
cs, _ := randState(config, 1) |
|
|
|
height, round := cs.Height, cs.Round |
|
|
|
|
|
|
|
// Listen for propose timeout event
|
|
|
@ -190,9 +190,9 @@ func TestStateEnterProposeYesPrivValidator(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestStateBadProposal(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(2) |
|
|
|
cs1, vss := randState(config, 2) |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
vs2 := vss[1] |
|
|
|
|
|
|
@ -240,19 +240,19 @@ func TestStateBadProposal(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, round, vss[0], nil) |
|
|
|
|
|
|
|
// add bad prevote from vs2 and wait for it
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
|
|
|
|
// wait for precommit
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
validatePrecommit(t, cs1, round, -1, vss[0], nil, nil) |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
} |
|
|
|
|
|
|
|
func TestStateOversizedBlock(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(2) |
|
|
|
cs1, vss := randState(config, 2) |
|
|
|
cs1.state.ConsensusParams.Block.MaxBytes = 2000 |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
vs2 := vss[1] |
|
|
@ -302,11 +302,11 @@ func TestStateOversizedBlock(t *testing.T) { |
|
|
|
// precommit on it
|
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
validatePrevote(t, cs1, round, vss[0], nil) |
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
validatePrecommit(t, cs1, round, -1, vss[0], nil, nil) |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
@ -314,9 +314,9 @@ func TestStateOversizedBlock(t *testing.T) { |
|
|
|
|
|
|
|
// propose, prevote, and precommit a block
|
|
|
|
func TestStateFullRound1(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs, vss := randState(1) |
|
|
|
cs, vss := randState(config, 1) |
|
|
|
height, round := cs.Height, cs.Round |
|
|
|
|
|
|
|
// NOTE: buffer capacity of 0 ensures we can validate prevote and last commit
|
|
|
@ -356,9 +356,9 @@ func TestStateFullRound1(t *testing.T) { |
|
|
|
|
|
|
|
// nil is proposed, so prevote and precommit nil
|
|
|
|
func TestStateFullRoundNil(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs, vss := randState(1) |
|
|
|
cs, vss := randState(config, 1) |
|
|
|
height, round := cs.Height, cs.Round |
|
|
|
|
|
|
|
voteCh := subscribeUnBuffered(cs.eventBus, types.EventQueryVote) |
|
|
@ -376,9 +376,9 @@ func TestStateFullRoundNil(t *testing.T) { |
|
|
|
// run through propose, prevote, precommit commit with two validators
|
|
|
|
// where the first validator has to wait for votes from the second
|
|
|
|
func TestStateFullRound2(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(2) |
|
|
|
cs1, vss := randState(config, 2) |
|
|
|
vs2 := vss[1] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -395,7 +395,7 @@ func TestStateFullRound2(t *testing.T) { |
|
|
|
propBlockHash, propPartSetHeader := rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header() |
|
|
|
|
|
|
|
// prevote arrives from vs2:
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propPartSetHeader, vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propPartSetHeader, vs2) |
|
|
|
ensurePrevote(voteCh, height, round) // prevote
|
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) // precommit
|
|
|
@ -405,7 +405,7 @@ func TestStateFullRound2(t *testing.T) { |
|
|
|
// we should be stuck in limbo waiting for more precommits
|
|
|
|
|
|
|
|
// precommit arrives from vs2:
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, propBlockHash, propPartSetHeader, vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash, propPartSetHeader, vs2) |
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
|
|
|
|
// wait to finish commit, propose in next height
|
|
|
@ -418,9 +418,9 @@ func TestStateFullRound2(t *testing.T) { |
|
|
|
// two validators, 4 rounds.
|
|
|
|
// two vals take turns proposing. val1 locks on first one, precommits nil on everything else
|
|
|
|
func TestStateLockNoPOL(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(2) |
|
|
|
cs1, vss := randState(config, 2) |
|
|
|
vs2 := vss[1] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -451,7 +451,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
|
|
|
|
// we should now be stuck in limbo forever, waiting for more prevotes
|
|
|
|
// prevote arrives from vs2:
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, thePartSetHeader, vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, thePartSetHeader, vs2) |
|
|
|
ensurePrevote(voteCh, height, round) // prevote
|
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) // precommit
|
|
|
@ -463,7 +463,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
hash := make([]byte, len(theBlockHash)) |
|
|
|
copy(hash, theBlockHash) |
|
|
|
hash[0] = (hash[0] + 1) % 255 |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, hash, thePartSetHeader, vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, hash, thePartSetHeader, vs2) |
|
|
|
ensurePrecommit(voteCh, height, round) // precommit
|
|
|
|
|
|
|
|
// (note we're entering precommit for a second time this round)
|
|
|
@ -496,7 +496,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, round, vss[0], rs.LockedBlock.Hash()) |
|
|
|
|
|
|
|
// add a conflicting prevote from the other validator
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
|
|
|
|
// now we're going to enter prevote again, but with invalid args
|
|
|
@ -509,7 +509,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
validatePrecommit(t, cs1, round, 0, vss[0], nil, theBlockHash) |
|
|
|
|
|
|
|
// add conflicting precommit from vs2
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
|
|
|
|
// (note we're entering precommit for a second time this round, but with invalid args
|
|
|
@ -539,7 +539,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) // prevote
|
|
|
|
validatePrevote(t, cs1, round, vss[0], rs.LockedBlock.Hash()) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) |
|
|
@ -548,6 +548,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
validatePrecommit(t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but be locked on proposal
|
|
|
|
|
|
|
|
signAddVotes( |
|
|
|
config, |
|
|
|
cs1, |
|
|
|
tmproto.PrecommitType, |
|
|
|
hash, |
|
|
@ -557,7 +558,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) |
|
|
|
|
|
|
|
cs2, _ := randState(2) // needed so generated block is different than locked block
|
|
|
|
cs2, _ := randState(config, 2) // needed so generated block is different than locked block
|
|
|
|
// before we time out into new round, set next proposal block
|
|
|
|
prop, propBlock := decideProposal(cs2, vs2, vs2.Height, vs2.Round+1) |
|
|
|
if prop == nil || propBlock == nil { |
|
|
@ -585,7 +586,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, 3, vss[0], cs1.LockedBlock.Hash()) |
|
|
|
|
|
|
|
// prevote for proposed block
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) |
|
|
@ -593,6 +594,7 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
validatePrecommit(t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but locked on proposal
|
|
|
|
|
|
|
|
signAddVotes( |
|
|
|
config, |
|
|
|
cs1, |
|
|
|
tmproto.PrecommitType, |
|
|
|
propBlock.Hash(), |
|
|
@ -606,9 +608,9 @@ func TestStateLockNoPOL(t *testing.T) { |
|
|
|
// in round two: v1 prevotes the same block that the node is locked on
|
|
|
|
// the others prevote a new block hence v1 changes lock and precommits the new block with the others
|
|
|
|
func TestStateLockPOLRelock(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -642,14 +644,14 @@ func TestStateLockPOLRelock(t *testing.T) { |
|
|
|
|
|
|
|
ensurePrevote(voteCh, height, round) // prevote
|
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) // our precommit
|
|
|
|
// the proposed block should now be locked and our precommit added
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], theBlockHash, theBlockHash) |
|
|
|
|
|
|
|
// add precommits from the rest
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
// before we timeout to the new round set the new proposal
|
|
|
|
cs2 := newState(cs1.state, vs2, counter.NewApplication(true)) |
|
|
@ -690,14 +692,14 @@ func TestStateLockPOLRelock(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, round, vss[0], theBlockHash) |
|
|
|
|
|
|
|
// now lets add prevotes from everyone else for the new block
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// we should have unlocked and locked on the new block, sending a precommit for this new block
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], propBlockHash, propBlockHash) |
|
|
|
|
|
|
|
// more prevote creating a majority on the new block and this is then committed
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3) |
|
|
|
ensureNewBlockHeader(newBlockCh, height, propBlockHash) |
|
|
|
|
|
|
|
ensureNewRound(newRoundCh, height+1, 0) |
|
|
@ -705,9 +707,9 @@ func TestStateLockPOLRelock(t *testing.T) { |
|
|
|
|
|
|
|
// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
|
|
|
|
func TestStateLockPOLUnlock(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -741,15 +743,15 @@ func TestStateLockPOLUnlock(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
validatePrevote(t, cs1, round, vss[0], theBlockHash) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// the proposed block should now be locked and our precommit added
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], theBlockHash, theBlockHash) |
|
|
|
|
|
|
|
// add precommits from the rest
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs4) |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) |
|
|
|
|
|
|
|
// before we time out into new round, set next proposal block
|
|
|
|
prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) |
|
|
@ -780,7 +782,7 @@ func TestStateLockPOLUnlock(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
validatePrevote(t, cs1, round, vss[0], lockedBlockHash) |
|
|
|
// now lets add prevotes from everyone else for nil (a polka!)
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
// the polka makes us unlock and precommit nil
|
|
|
|
ensureNewUnlock(unlockCh, height, round) |
|
|
@ -790,7 +792,7 @@ func TestStateLockPOLUnlock(t *testing.T) { |
|
|
|
// NOTE: since we don't relock on nil, the lock round is -1
|
|
|
|
validatePrecommit(t, cs1, round, -1, vss[0], nil, nil) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3) |
|
|
|
ensureNewRound(newRoundCh, height, round+1) |
|
|
|
} |
|
|
|
|
|
|
@ -799,9 +801,9 @@ func TestStateLockPOLUnlock(t *testing.T) { |
|
|
|
// v1 should unlock and precommit nil. In the third round another block is proposed, all vals
|
|
|
|
// prevote and now v1 can lock onto the third block and precommit that
|
|
|
|
func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -831,14 +833,14 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { |
|
|
|
|
|
|
|
ensurePrevote(voteCh, height, round) // prevote
|
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, firstBlockHash, firstBlockParts, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, firstBlockHash, firstBlockParts, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) // our precommit
|
|
|
|
// the proposed block should now be locked and our precommit added
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], firstBlockHash, firstBlockHash) |
|
|
|
|
|
|
|
// add precommits from the rest
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
// before we timeout to the new round set the new proposal
|
|
|
|
cs2 := newState(cs1.state, vs2, counter.NewApplication(true)) |
|
|
@ -871,7 +873,7 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, round, vss[0], firstBlockHash) |
|
|
|
|
|
|
|
// now lets add prevotes from everyone else for the new block
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, secondBlockHash, secondBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, secondBlockHash, secondBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// we should have unlocked and locked on the new block, sending a precommit for this new block
|
|
|
@ -882,7 +884,7 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
// more prevote creating a majority on the new block and this is then committed
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
// before we timeout to the new round set the new proposal
|
|
|
|
cs3 := newState(cs1.state, vs3, counter.NewApplication(true)) |
|
|
@ -915,7 +917,7 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { |
|
|
|
// we are no longer locked to the first block so we should be able to prevote
|
|
|
|
validatePrevote(t, cs1, round, vss[0], thirdPropBlockHash) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, thirdPropBlockHash, thirdPropBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, thirdPropBlockHash, thirdPropBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// we have a majority, now vs1 can change lock to the third block
|
|
|
@ -927,9 +929,9 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { |
|
|
|
// then a polka at round 2 that we lock on
|
|
|
|
// then we see the polka from round 1 but shouldn't unlock
|
|
|
|
func TestStateLockPOLSafety1(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -956,12 +958,14 @@ func TestStateLockPOLSafety1(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, round, vss[0], propBlock.Hash()) |
|
|
|
|
|
|
|
// the others sign a polka but we don't see it
|
|
|
|
prevotes := signVotes(tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2, vs3, vs4) |
|
|
|
prevotes := signVotes(config, tmproto.PrevoteType, |
|
|
|
propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), |
|
|
|
vs2, vs3, vs4) |
|
|
|
|
|
|
|
t.Logf("old prop hash %v", fmt.Sprintf("%X", propBlock.Hash())) |
|
|
|
|
|
|
|
// we do see them precommit nil
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
// cs1 precommit nil
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
@ -1001,13 +1005,13 @@ func TestStateLockPOLSafety1(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, round, vss[0], propBlockHash) |
|
|
|
|
|
|
|
// now we see the others prevote for it, so we should lock on it
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// we should have precommitted
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], propBlockHash, propBlockHash) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) |
|
|
|
|
|
|
@ -1048,9 +1052,9 @@ func TestStateLockPOLSafety1(t *testing.T) { |
|
|
|
// What we want:
|
|
|
|
// dont see P0, lock on P1 at R1, dont unlock using P0 at R2
|
|
|
|
func TestStateLockPOLSafety2(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -1073,7 +1077,7 @@ func TestStateLockPOLSafety2(t *testing.T) { |
|
|
|
propBlockID0 := types.BlockID{Hash: propBlockHash0, PartSetHeader: propBlockParts0.Header()} |
|
|
|
|
|
|
|
// the others sign a polka but we don't see it
|
|
|
|
prevotes := signVotes(tmproto.PrevoteType, propBlockHash0, propBlockParts0.Header(), vs2, vs3, vs4) |
|
|
|
prevotes := signVotes(config, tmproto.PrevoteType, propBlockHash0, propBlockParts0.Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
// the block for round 1
|
|
|
|
prop1, propBlock1 := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) |
|
|
@ -1096,15 +1100,15 @@ func TestStateLockPOLSafety2(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
validatePrevote(t, cs1, round, vss[0], propBlockHash1) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlockHash1, propBlockParts1.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash1, propBlockParts1.Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// the proposed block should now be locked and our precommit added
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], propBlockHash1, propBlockHash1) |
|
|
|
|
|
|
|
// add precommits from the rest
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs4) |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, propBlockHash1, propBlockParts1.Header(), vs3) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash1, propBlockParts1.Header(), vs3) |
|
|
|
|
|
|
|
incrementRound(vs2, vs3, vs4) |
|
|
|
|
|
|
@ -1147,9 +1151,9 @@ func TestStateLockPOLSafety2(t *testing.T) { |
|
|
|
// What we want:
|
|
|
|
// P0 proposes B0 at R3.
|
|
|
|
func TestProposeValidBlock(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -1178,13 +1182,13 @@ func TestProposeValidBlock(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, round, vss[0], propBlockHash) |
|
|
|
|
|
|
|
// the others sign a polka
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlock.MakePartSet(partSize).Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlock.MakePartSet(partSize).Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// we should have precommitted
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], propBlockHash, propBlockHash) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) |
|
|
|
|
|
|
@ -1201,7 +1205,7 @@ func TestProposeValidBlock(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
validatePrevote(t, cs1, round, vss[0], propBlockHash) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensureNewUnlock(unlockCh, height, round) |
|
|
|
|
|
|
@ -1212,7 +1216,7 @@ func TestProposeValidBlock(t *testing.T) { |
|
|
|
incrementRound(vs2, vs3, vs4) |
|
|
|
incrementRound(vs2, vs3, vs4) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
round += 2 // moving to the next round
|
|
|
|
|
|
|
@ -1239,9 +1243,9 @@ func TestProposeValidBlock(t *testing.T) { |
|
|
|
// What we want:
|
|
|
|
// P0 miss to lock B but set valid block to B after receiving delayed prevote.
|
|
|
|
func TestSetValidBlockOnDelayedPrevote(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -1270,10 +1274,10 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { |
|
|
|
validatePrevote(t, cs1, round, vss[0], propBlockHash) |
|
|
|
|
|
|
|
// vs2 send prevote for propBlock
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2) |
|
|
|
|
|
|
|
// vs3 send prevote nil
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs3) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs3) |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) |
|
|
|
|
|
|
@ -1288,7 +1292,7 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { |
|
|
|
assert.True(t, rs.ValidRound == -1) |
|
|
|
|
|
|
|
// vs2 send (delayed) prevote for propBlock
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs4) |
|
|
|
|
|
|
|
ensureNewValidBlock(validBlockCh, height, round) |
|
|
|
|
|
|
@ -1303,9 +1307,9 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { |
|
|
|
// P0 miss to lock B as Proposal Block is missing, but set valid block to B after
|
|
|
|
// receiving delayed Block Proposal.
|
|
|
|
func TestSetValidBlockOnDelayedProposal(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -1337,7 +1341,7 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) { |
|
|
|
propBlockParts := propBlock.MakePartSet(partSize) |
|
|
|
|
|
|
|
// vs2, vs3 and vs4 send prevote for propBlock
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
ensureNewValidBlock(validBlockCh, height, round) |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) |
|
|
@ -1361,9 +1365,9 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) { |
|
|
|
// What we want:
|
|
|
|
// P0 waits for timeoutPrecommit before starting next round
|
|
|
|
func TestWaitingTimeoutOnNilPolka(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -1374,7 +1378,7 @@ func TestWaitingTimeoutOnNilPolka(t *testing.T) { |
|
|
|
startTestRound(cs1, height, round) |
|
|
|
ensureNewRound(newRoundCh, height, round) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) |
|
|
|
ensureNewRound(newRoundCh, height, round+1) |
|
|
@ -1384,9 +1388,9 @@ func TestWaitingTimeoutOnNilPolka(t *testing.T) { |
|
|
|
// What we want:
|
|
|
|
// P0 waits for timeoutPropose in the next round before entering prevote
|
|
|
|
func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -1404,7 +1408,7 @@ func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
|
|
|
|
incrementRound(vss[1:]...) |
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
round++ // moving to the next round
|
|
|
|
ensureNewRound(newRoundCh, height, round) |
|
|
@ -1422,9 +1426,9 @@ func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { |
|
|
|
// What we want:
|
|
|
|
// P0 jump to higher round, precommit and start precommit wait
|
|
|
|
func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
|
|
|
@ -1442,7 +1446,7 @@ func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
|
|
|
|
incrementRound(vss[1:]...) |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
round++ // moving to the next round
|
|
|
|
ensureNewRound(newRoundCh, height, round) |
|
|
@ -1460,9 +1464,9 @@ func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { |
|
|
|
// What we want:
|
|
|
|
// P0 wait for timeoutPropose to expire before sending prevote.
|
|
|
|
func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, int32(1) |
|
|
|
|
|
|
@ -1478,7 +1482,7 @@ func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { |
|
|
|
ensureNewRound(newRoundCh, height, round) |
|
|
|
|
|
|
|
incrementRound(vss[1:]...) |
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds()) |
|
|
|
|
|
|
@ -1489,9 +1493,9 @@ func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { |
|
|
|
// What we want:
|
|
|
|
// P0 emit NewValidBlock event upon receiving 2/3+ Precommit for B but hasn't received block B yet
|
|
|
|
func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, int32(1) |
|
|
|
|
|
|
@ -1511,7 +1515,7 @@ func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { |
|
|
|
ensureNewRound(newRoundCh, height, round) |
|
|
|
|
|
|
|
// vs2, vs3 and vs4 send precommit for propBlock
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
ensureNewValidBlock(validBlockCh, height, round) |
|
|
|
|
|
|
|
rs := cs1.GetRoundState() |
|
|
@ -1525,9 +1529,9 @@ func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { |
|
|
|
// P0 receives 2/3+ Precommit for B for round 0, while being in round 1. It emits NewValidBlock event.
|
|
|
|
// After receiving block, it executes block and moves to the next height.
|
|
|
|
func TestCommitFromPreviousRound(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, int32(1) |
|
|
|
|
|
|
@ -1546,7 +1550,7 @@ func TestCommitFromPreviousRound(t *testing.T) { |
|
|
|
ensureNewRound(newRoundCh, height, round) |
|
|
|
|
|
|
|
// vs2, vs3 and vs4 send precommit for propBlock for the previous round
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensureNewValidBlock(validBlockCh, height, round) |
|
|
|
|
|
|
@ -1580,10 +1584,10 @@ func (n *fakeTxNotifier) Notify() { |
|
|
|
// and third precommit arrives which leads to the commit of that header and the correct
|
|
|
|
// start of the next round
|
|
|
|
func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
config.Consensus.SkipTimeoutCommit = false |
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
cs1.txNotifier = &fakeTxNotifier{ch: make(chan struct{})} |
|
|
|
|
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
@ -1612,15 +1616,15 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
validatePrevote(t, cs1, round, vss[0], theBlockHash) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// the proposed block should now be locked and our precommit added
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], theBlockHash, theBlockHash) |
|
|
|
|
|
|
|
// add precommits
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) |
|
|
|
|
|
|
|
// wait till timeout occurs
|
|
|
|
ensurePrecommitTimeout(precommitTimeoutCh) |
|
|
@ -1628,7 +1632,7 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { |
|
|
|
ensureNewRound(newRoundCh, height, round+1) |
|
|
|
|
|
|
|
// majority is now reached
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs4) |
|
|
|
|
|
|
|
ensureNewBlockHeader(newBlockHeader, height, theBlockHash) |
|
|
|
|
|
|
@ -1643,10 +1647,10 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
config.Consensus.SkipTimeoutCommit = false |
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
|
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
@ -1674,15 +1678,15 @@ func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) { |
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
validatePrevote(t, cs1, round, vss[0], theBlockHash) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], theBlockHash, theBlockHash) |
|
|
|
|
|
|
|
// add precommits
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) |
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs4) |
|
|
|
|
|
|
|
ensureNewBlockHeader(newBlockHeader, height, theBlockHash) |
|
|
|
|
|
|
@ -1787,9 +1791,9 @@ func TestStateSlashingPrecommits(t *testing.T) { |
|
|
|
// 4 vals.
|
|
|
|
// we receive a final precommit after going into next round, but others might have gone to commit already!
|
|
|
|
func TestStateHalt1(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs1, vss := randState(4) |
|
|
|
cs1, vss := randState(config, 4) |
|
|
|
vs2, vs3, vs4 := vss[1], vss[2], vss[3] |
|
|
|
height, round := cs1.Height, cs1.Round |
|
|
|
partSize := types.BlockPartSizeBytes |
|
|
@ -1814,17 +1818,17 @@ func TestStateHalt1(t *testing.T) { |
|
|
|
|
|
|
|
ensurePrevote(voteCh, height, round) |
|
|
|
|
|
|
|
signAddVotes(cs1, tmproto.PrevoteType, propBlock.Hash(), propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
signAddVotes(config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlockParts.Header(), vs2, vs3, vs4) |
|
|
|
|
|
|
|
ensurePrecommit(voteCh, height, round) |
|
|
|
// the proposed block should now be locked and our precommit added
|
|
|
|
validatePrecommit(t, cs1, round, round, vss[0], propBlock.Hash(), propBlock.Hash()) |
|
|
|
|
|
|
|
// add precommits from the rest
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) // didnt receive proposal
|
|
|
|
signAddVotes(cs1, tmproto.PrecommitType, propBlock.Hash(), propBlockParts.Header(), vs3) |
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) // didnt receive proposal
|
|
|
|
signAddVotes(config, cs1, tmproto.PrecommitType, propBlock.Hash(), propBlockParts.Header(), vs3) |
|
|
|
// we receive this later, but vs3 might receive it earlier and with ours will go to commit!
|
|
|
|
precommit4 := signVote(vs4, tmproto.PrecommitType, propBlock.Hash(), propBlockParts.Header()) |
|
|
|
precommit4 := signVote(vs4, config, tmproto.PrecommitType, propBlock.Hash(), propBlockParts.Header()) |
|
|
|
|
|
|
|
incrementRound(vs2, vs3, vs4) |
|
|
|
|
|
|
@ -1856,10 +1860,10 @@ func TestStateHalt1(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestStateOutputsBlockPartsStats(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
// create dummy peer
|
|
|
|
cs, _ := randState(1) |
|
|
|
cs, _ := randState(config, 1) |
|
|
|
peer := p2pmock.NewPeer(nil) |
|
|
|
|
|
|
|
// 1) new block part
|
|
|
@ -1901,15 +1905,15 @@ func TestStateOutputsBlockPartsStats(t *testing.T) { |
|
|
|
} |
|
|
|
|
|
|
|
func TestStateOutputVoteStats(t *testing.T) { |
|
|
|
configSetup(t) |
|
|
|
config := configSetup(t) |
|
|
|
|
|
|
|
cs, vss := randState(2) |
|
|
|
cs, vss := randState(config, 2) |
|
|
|
// create dummy peer
|
|
|
|
peer := p2pmock.NewPeer(nil) |
|
|
|
|
|
|
|
randBytes := tmrand.Bytes(tmhash.Size) |
|
|
|
|
|
|
|
vote := signVote(vss[1], tmproto.PrecommitType, randBytes, types.PartSetHeader{}) |
|
|
|
vote := signVote(vss[1], config, tmproto.PrecommitType, randBytes, types.PartSetHeader{}) |
|
|
|
|
|
|
|
voteMessage := &VoteMessage{vote} |
|
|
|
cs.handleMsg(msgInfo{voteMessage, peer.ID()}) |
|
|
@ -1923,7 +1927,7 @@ func TestStateOutputVoteStats(t *testing.T) { |
|
|
|
|
|
|
|
// sending the vote for the bigger height
|
|
|
|
incrementHeight(vss[1]) |
|
|
|
vote = signVote(vss[1], tmproto.PrecommitType, randBytes, types.PartSetHeader{}) |
|
|
|
vote = signVote(vss[1], config, tmproto.PrecommitType, randBytes, types.PartSetHeader{}) |
|
|
|
|
|
|
|
cs.handleMsg(msgInfo{&VoteMessage{vote}, peer.ID()}) |
|
|
|
|
|
|
|