@ -74,7 +74,7 @@ func TestProposerSelection0(t *testing.T) {
<- proposalCh
rs := cs1 . GetRoundState ( )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil , vss [ 1 : ] ... )
signAddVotes ( cs1 , types . VoteTypePrecommit , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , vss [ 1 : ] ... )
// wait for new round so next validator is set
<- newRoundCh
@ -106,7 +106,7 @@ func TestProposerSelection2(t *testing.T) {
}
rs := cs1 . GetRoundState ( )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , rs . ProposalBlockParts . Header ( ) , nil , vss [ 1 : ] ... )
signAddVotes ( cs1 , types . VoteTypePrecommit , nil , rs . ProposalBlockParts . Header ( ) , vss [ 1 : ] ... )
<- newRoundCh // wait for the new round event each round
incrementRound ( vss [ 1 : ] ... )
@ -179,12 +179,12 @@ func TestEnterProposeYesPrivValidator(t *testing.T) {
func TestBadProposal ( t * testing . T ) {
cs1 , vss := randConsensusState ( 2 )
height , round := cs1 . Height , cs1 . Round
c s2 := vss [ 1 ]
v s2 := vss [ 1 ]
proposalCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringCompleteProposal ( ) , 1 )
voteCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringVote ( ) , 1 )
propBlock , _ := cs1 . createProposalBlock ( ) //changeProposer(t, cs1, c s2)
propBlock , _ := cs1 . createProposalBlock ( ) //changeProposer(t, cs1, v s2)
// make the second validator the proposer by incrementing round
round = round + 1
@ -198,9 +198,9 @@ func TestBadProposal(t *testing.T) {
stateHash [ 0 ] = byte ( ( stateHash [ 0 ] + 1 ) % 255 )
propBlock . AppHash = stateHash
propBlockParts := propBlock . MakePartSet ( )
proposal := types . NewProposal ( c s2. Height , round , propBlockParts . Header ( ) , - 1 )
if err := c s2. SignProposal ( config . GetString ( "chain_id" ) , proposal ) ; err != nil {
panic ( "failed to sign bad proposal: " + err . Error ( ) )
proposal := types . NewProposal ( v s2. Height , round , propBlockParts . Header ( ) , - 1 )
if err := v s2. SignProposal ( config . GetString ( "chain_id" ) , proposal ) ; err != nil {
t . Fatal ( "failed to sign bad proposal" , err )
}
// set the proposal block
@ -217,14 +217,15 @@ func TestBadProposal(t *testing.T) {
validatePrevote ( t , cs1 , round , vss [ 0 ] , nil )
// add bad prevote from cs2 and wait for it
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , voteCh )
// add bad prevote from vs2 and wait for it
signAddVotes ( cs1 , types . VoteTypePrevote , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , vs2 )
<- voteCh
// wait for precommit
<- voteCh
validatePrecommit ( t , cs1 , round , 0 , vss [ 0 ] , nil , nil )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , voteCh )
signAddVotes ( cs1 , types . VoteTypePrecommit , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , vs2 )
}
//----------------------------------------------------------------------------------------------------
@ -281,7 +282,7 @@ func TestFullRoundNil(t *testing.T) {
// where the first validator has to wait for votes from the second
func TestFullRound2 ( t * testing . T ) {
cs1 , vss := randConsensusState ( 2 )
c s2 := vss [ 1 ]
v s2 := vss [ 1 ]
height , round := cs1 . Height , cs1 . Round
voteCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringVote ( ) , 1 )
@ -296,8 +297,9 @@ func TestFullRound2(t *testing.T) {
rs := cs1 . GetRoundState ( )
propBlockHash , propPartsHeader := rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( )
// prevote arrives from cs2:
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlockHash , propPartsHeader , voteCh )
// prevote arrives from vs2:
signAddVotes ( cs1 , types . VoteTypePrevote , propBlockHash , propPartsHeader , vs2 )
<- voteCh
<- voteCh //precommit
@ -306,8 +308,9 @@ func TestFullRound2(t *testing.T) {
// we should be stuck in limbo waiting for more precommits
// precommit arrives from cs2:
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , propBlockHash , propPartsHeader , voteCh )
// precommit arrives from vs2:
signAddVotes ( cs1 , types . VoteTypePrecommit , propBlockHash , propPartsHeader , vs2 )
<- voteCh
// wait to finish commit, propose in next height
<- newBlockCh
@ -320,7 +323,7 @@ func TestFullRound2(t *testing.T) {
// two vals take turns proposing. val1 locks on first one, precommits nil on everything else
func TestLockNoPOL ( t * testing . T ) {
cs1 , vss := randConsensusState ( 2 )
c s2 := vss [ 1 ]
v s2 := vss [ 1 ]
height := cs1 . Height
timeoutProposeCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringTimeoutPropose ( ) , 1 )
@ -344,8 +347,9 @@ func TestLockNoPOL(t *testing.T) {
<- voteCh // prevote
// we should now be stuck in limbo forever, waiting for more prevotes
// prevote arrives from cs2:
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , voteCh )
// prevote arrives from vs2:
signAddVotes ( cs1 , types . VoteTypePrevote , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) , vs2 )
<- voteCh // prevote
<- voteCh // precommit
@ -358,7 +362,8 @@ func TestLockNoPOL(t *testing.T) {
hash := make ( [ ] byte , len ( theBlockHash ) )
copy ( hash , theBlockHash )
hash [ 0 ] = byte ( ( hash [ 0 ] + 1 ) % 255 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh )
signAddVotes ( cs1 , types . VoteTypePrecommit , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , vs2 )
<- voteCh // precommit
// (note we're entering precommit for a second time this round)
// but with invalid args. then we enterPrecommitWait, and the timeout to new round
@ -372,7 +377,7 @@ func TestLockNoPOL(t *testing.T) {
Round2 ( cs1 , B ) // B B2
* /
incrementRound ( c s2)
incrementRound ( v s2)
// now we're on a new round and not the proposer, so wait for timeout
re = <- timeoutProposeCh
@ -389,7 +394,8 @@ func TestLockNoPOL(t *testing.T) {
validatePrevote ( t , cs1 , 1 , vss [ 0 ] , rs . LockedBlock . Hash ( ) )
// add a conflicting prevote from the other validator
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh )
signAddVotes ( cs1 , types . VoteTypePrevote , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , vs2 )
<- voteCh
// now we're going to enter prevote again, but with invalid args
// and then prevote wait, which should timeout. then wait for precommit
@ -401,9 +407,10 @@ func TestLockNoPOL(t *testing.T) {
// we should precommit nil and be locked on the proposal
validatePrecommit ( t , cs1 , 1 , 0 , vss [ 0 ] , nil , theBlockHash )
// add conflicting precommit from c s2
// add conflicting precommit from v s2
// NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh )
signAddVotes ( cs1 , types . VoteTypePrecommit , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , vs2 )
<- voteCh
// (note we're entering precommit for a second time this round, but with invalid args
// then we enterPrecommitWait and timeout into NewRound
@ -412,10 +419,10 @@ func TestLockNoPOL(t *testing.T) {
<- newRoundCh
log . Notice ( "#### ONTO ROUND 2" )
/ *
Round3 ( c s2, _ ) // B, B2
Round3 ( v s2, _ ) // B, B2
* /
incrementRound ( c s2)
incrementRound ( v s2)
re = <- proposalCh
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
@ -429,28 +436,31 @@ func TestLockNoPOL(t *testing.T) {
validatePrevote ( t , cs1 , 2 , vss [ 0 ] , rs . LockedBlock . Hash ( ) )
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh )
signAddVotes ( cs1 , types . VoteTypePrevote , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , vs2 )
<- voteCh
<- timeoutWaitCh // prevote wait
<- voteCh // precommit
validatePrecommit ( t , cs1 , 2 , 0 , vss [ 0 ] , nil , theBlockHash ) // precommit nil but be locked on proposal
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh ) // NOTE: conflicting precommits at same height
validatePrecommit ( t , cs1 , 2 , 0 , vss [ 0 ] , nil , theBlockHash ) // precommit nil but be locked on proposal
signAddVotes ( cs1 , types . VoteTypePrecommit , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , vs2 ) // NOTE: conflicting precommits at same height
<- voteCh
<- timeoutWaitCh
// before we time out into new round, set next proposal block
prop , propBlock := decideProposal ( cs1 , cs2 , c s2. Height , c s2. Round + 1 )
prop , propBlock := decideProposal ( cs1 , vs2 , v s2. Height , v s2. Round + 1 )
if prop == nil || propBlock == nil {
panic ( "Failed to create proposal block with c s2")
t . Fatal ( "Failed to create proposal block with v s2")
}
incrementRound ( c s2)
incrementRound ( v s2)
<- newRoundCh
log . Notice ( "#### ONTO ROUND 3" )
/ *
Round4 ( c s2, C ) // B C // B C
Round4 ( v s2, C ) // B C // B C
* /
// now we're on a new round and not the proposer
@ -463,19 +473,22 @@ func TestLockNoPOL(t *testing.T) {
// prevote for locked block (not proposal)
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , cs1 . LockedBlock . Hash ( ) )
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , voteCh )
signAddVotes ( cs1 , types . VoteTypePrevote , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , vs2 )
<- voteCh
<- timeoutWaitCh
<- voteCh
validatePrecommit ( t , cs1 , 2 , 0 , vss [ 0 ] , nil , theBlockHash ) // precommit nil but locked on proposal
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , voteCh ) // NOTE: conflicting precommits at same height
validatePrecommit ( t , cs1 , 2 , 0 , vss [ 0 ] , nil , theBlockHash ) // precommit nil but locked on proposal
signAddVotes ( cs1 , types . VoteTypePrecommit , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , vs2 ) // NOTE: conflicting precommits at same height
<- voteCh
}
// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
func TestLockPOLRelock ( t * testing . T ) {
cs1 , vss := randConsensusState ( 4 )
cs2 , cs3 , c s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
vs2 , vs3 , v s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
timeoutProposeCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringTimeoutPropose ( ) , 1 )
timeoutWaitCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringTimeoutWait ( ) , 1 )
@ -484,14 +497,14 @@ func TestLockPOLRelock(t *testing.T) {
newRoundCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringNewRound ( ) , 1 )
newBlockCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringNewBlockHeader ( ) , 1 )
log . Debug ( "c s2 last round" , "lr" , c s2. PrivValidator . LastRound )
log . Debug ( "v s2 last round" , "lr" , v s2. PrivValidator . LastRound )
// everything done from perspective of cs1
/ *
Round1 ( cs1 , B ) // B B B B// B nil B nil
eg . cs2 and c s4 didn ' t see the 2 / 3 prevotes
eg . vs2 and v s4 didn ' t see the 2 / 3 prevotes
* /
// start round and wait for propose and prevote
@ -501,26 +514,27 @@ func TestLockPOLRelock(t *testing.T) {
re := <- proposalCh
rs := re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
theBlockHash := rs . ProposalBlock . Hash ( )
theBlockPartsHeader := rs . ProposalBlockParts . Header ( )
<- voteCh // prevote
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , theBlockHash , theBlockPartsHeader , voteCh , cs2 , cs3 , cs4 )
signAddVotes ( cs1 , types . VoteTypePrevote , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) , vs2 , vs3 , vs4 )
_ , _ , _ = <- voteCh , <- voteCh , <- voteCh // prevotes
<- voteCh // our precommit
// the proposed block should now be locked and our precommit added
validatePrecommit ( t , cs1 , 0 , 0 , vss [ 0 ] , theBlockHash , theBlockHash )
// add precommits from the rest
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , voteCh , cs2 , cs4 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , theBlockHash , theBlockPartsHeader , voteCh )
signAddVotes ( cs1 , types . VoteTypePrecommit , nil , types . PartSetHeader { } , vs2 , vs4 )
signAddVotes ( cs1 , types . VoteTypePrecommit , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) , vs3 )
_ , _ , _ = <- voteCh , <- voteCh , <- voteCh // precommits
// before we timeout to the new round set the new proposal
prop , propBlock := decideProposal ( cs1 , cs2 , c s2. Height , c s2. Round + 1 )
prop , propBlock := decideProposal ( cs1 , vs2 , v s2. Height , v s2. Round + 1 )
propBlockParts := propBlock . MakePartSet ( )
propBlockHash := propBlock . Hash ( )
incrementRound ( cs2 , cs3 , c s4)
incrementRound ( vs2 , vs3 , v s4)
// timeout to new round
<- timeoutWaitCh
@ -532,7 +546,7 @@ func TestLockPOLRelock(t *testing.T) {
log . Notice ( "### ONTO ROUND 1" )
/ *
Round2 ( c s2, C ) // B C C C // C C C _)
Round2 ( v s2, C ) // B C C C // C C C _)
cs1 changes lock !
* /
@ -550,7 +564,8 @@ func TestLockPOLRelock(t *testing.T) {
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , theBlockHash )
// now lets add prevotes from everyone else for the new block
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash , propBlockParts . Header ( ) , voteCh , cs2 , cs3 , cs4 )
signAddVotes ( cs1 , types . VoteTypePrevote , propBlockHash , propBlockParts . Header ( ) , vs2 , vs3 , vs4 )
_ , _ , _ = <- voteCh , <- voteCh , <- voteCh // prevotes
// now either we go to PrevoteWait or Precommit
select {
@ -564,7 +579,8 @@ func TestLockPOLRelock(t *testing.T) {
// we should have unlocked and locked on the new block
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash , propBlockHash )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , propBlockHash , propBlockParts . Header ( ) , voteCh , cs2 , cs3 )
signAddVotes ( cs1 , types . VoteTypePrecommit , propBlockHash , propBlockParts . Header ( ) , vs2 , vs3 )
_ , _ = <- voteCh , <- voteCh
be := <- newBlockCh
b := be . ( types . EventDataNewBlockHeader )
@ -582,7 +598,7 @@ func TestLockPOLRelock(t *testing.T) {
// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
func TestLockPOLUnlock ( t * testing . T ) {
cs1 , vss := randConsensusState ( 4 )
cs2 , cs3 , c s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
vs2 , vs3 , v s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
proposalCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringCompleteProposal ( ) , 1 )
timeoutProposeCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringTimeoutPropose ( ) , 1 )
@ -608,7 +624,7 @@ func TestLockPOLUnlock(t *testing.T) {
<- voteCh // prevote
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil , cs2 , cs3 , c s4)
signAddVotes ( cs1 , types . VoteTypePrevote , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) , vs2 , vs3 , v s4)
<- voteCh //precommit
@ -618,14 +634,14 @@ func TestLockPOLUnlock(t *testing.T) {
rs = cs1 . GetRoundState ( )
// add precommits from the rest
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , c s4)
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil )
signAddVotes ( cs1 , types . VoteTypePrecommit , nil , types . PartSetHeader { } , vs2 , v s4)
signAddVotes ( cs1 , types . VoteTypePrecommit , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) , vs3 )
// before we time out into new round, set next proposal block
prop , propBlock := decideProposal ( cs1 , cs2 , c s2. Height , c s2. Round + 1 )
prop , propBlock := decideProposal ( cs1 , vs2 , v s2. Height , v s2. Round + 1 )
propBlockParts := propBlock . MakePartSet ( )
incrementRound ( cs2 , cs3 , c s4)
incrementRound ( vs2 , vs3 , v s4)
// timeout to new round
re = <- timeoutWaitCh
@ -638,7 +654,7 @@ func TestLockPOLUnlock(t *testing.T) {
<- newRoundCh
log . Notice ( "#### ONTO ROUND 1" )
/ *
Round2 ( c s2, C ) // B nil nil nil // nil nil nil _
Round2 ( v s2, C ) // B nil nil nil // nil nil nil _
cs1 unlocks !
* /
@ -655,7 +671,7 @@ func TestLockPOLUnlock(t *testing.T) {
<- voteCh
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , lockedBlockHash )
// now lets add prevotes from everyone else for nil (a polka!)
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , nil , types . PartSetHeader { } , nil , cs2 , cs3 , c s4)
signAddVotes ( cs1 , types . VoteTypePrevote , nil , types . PartSetHeader { } , vs2 , vs3 , v s4)
// the polka makes us unlock and precommit nil
<- unlockCh
@ -665,7 +681,7 @@ func TestLockPOLUnlock(t *testing.T) {
// NOTE: since we don't relock on nil, the lock round is 0
validatePrecommit ( t , cs1 , 1 , 0 , vss [ 0 ] , nil , nil )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , c s3)
signAddVotes ( cs1 , types . VoteTypePrecommit , nil , types . PartSetHeader { } , vs2 , v s3)
<- newRoundCh
}
@ -675,7 +691,7 @@ func TestLockPOLUnlock(t *testing.T) {
// then we see the polka from round 1 but shouldn't unlock
func TestLockPOLSafety1 ( t * testing . T ) {
cs1 , vss := randConsensusState ( 4 )
cs2 , cs3 , c s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
vs2 , vs3 , v s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
proposalCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringCompleteProposal ( ) , 1 )
timeoutProposeCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringTimeoutPropose ( ) , 1 )
@ -695,7 +711,7 @@ func TestLockPOLSafety1(t *testing.T) {
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , propBlock . Hash ( ) )
// the others sign a polka but we don't see it
prevotes := signVoteMany ( types . VoteTypePrevote , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , cs2 , cs3 , c s4)
prevotes := signVotes ( types . VoteTypePrevote , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , vs2 , vs3 , v s4)
// before we time out into new round, set next proposer
// and next proposal block
@ -709,13 +725,13 @@ func TestLockPOLSafety1(t *testing.T) {
log . Warn ( "old prop" , "hash" , fmt . Sprintf ( "%X" , propBlock . Hash ( ) ) )
// we do see them precommit nil
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , cs3 , c s4)
signAddVotes ( cs1 , types . VoteTypePrecommit , nil , types . PartSetHeader { } , vs2 , vs3 , v s4)
prop , propBlock := decideProposal ( cs1 , cs2 , c s2. Height , c s2. Round + 1 )
prop , propBlock := decideProposal ( cs1 , vs2 , v s2. Height , v s2. Round + 1 )
propBlockHash := propBlock . Hash ( )
propBlockParts := propBlock . MakePartSet ( )
incrementRound ( cs2 , cs3 , c s4)
incrementRound ( vs2 , vs3 , v s4)
//XXX: this isnt gauranteed to get there before the timeoutPropose ...
cs1 . SetProposalAndBlock ( prop , propBlock , propBlockParts , "some peer" )
@ -746,18 +762,18 @@ func TestLockPOLSafety1(t *testing.T) {
validatePrevote ( t , cs1 , 1 , vss [ 0 ] , propBlockHash )
// now we see the others prevote for it, so we should lock on it
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash , propBlockParts . Header ( ) , nil , cs2 , cs3 , c s4)
signAddVotes ( cs1 , types . VoteTypePrevote , propBlockHash , propBlockParts . Header ( ) , vs2 , vs3 , v s4)
<- voteCh // precommit
// we should have precommitted
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash , propBlockHash )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , c s3)
signAddVotes ( cs1 , types . VoteTypePrecommit , nil , types . PartSetHeader { } , vs2 , v s3)
<- timeoutWaitCh
incrementRound ( cs2 , cs3 , c s4)
incrementRound ( vs2 , vs3 , v s4)
<- newRoundCh
@ -778,7 +794,7 @@ func TestLockPOLSafety1(t *testing.T) {
newStepCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringNewRoundStep ( ) , 1 )
// add prevotes from the earlier round
addVoteToFromMany ( cs1 , prevotes , cs2 , cs3 , cs4 )
addVotes ( cs1 , prevotes ... )
log . Warn ( "Done adding prevotes!" )
@ -794,7 +810,7 @@ func TestLockPOLSafety1(t *testing.T) {
// dont see P0, lock on P1 at R1, dont unlock using P0 at R2
func TestLockPOLSafety2 ( t * testing . T ) {
cs1 , vss := randConsensusState ( 4 )
cs2 , cs3 , c s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
vs2 , vs3 , v s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
proposalCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringCompleteProposal ( ) , 1 )
timeoutProposeCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringTimeoutPropose ( ) , 1 )
@ -810,14 +826,14 @@ func TestLockPOLSafety2(t *testing.T) {
propBlockParts0 := propBlock0 . MakePartSet ( )
// the others sign a polka but we don't see it
prevotes := signVoteMany ( types . VoteTypePrevote , propBlockHash0 , propBlockParts0 . Header ( ) , cs2 , cs3 , c s4)
prevotes := signVotes ( types . VoteTypePrevote , propBlockHash0 , propBlockParts0 . Header ( ) , vs2 , vs3 , v s4)
// the block for round 1
prop1 , propBlock1 := decideProposal ( cs1 , cs2 , c s2. Height , c s2. Round + 1 )
prop1 , propBlock1 := decideProposal ( cs1 , vs2 , v s2. Height , v s2. Round + 1 )
propBlockHash1 := propBlock1 . Hash ( )
propBlockParts1 := propBlock1 . MakePartSet ( )
incrementRound ( cs2 , cs3 , c s4)
incrementRound ( vs2 , vs3 , v s4)
cs1 . updateRoundStep ( 0 , RoundStepPrecommitWait )
@ -832,28 +848,30 @@ func TestLockPOLSafety2(t *testing.T) {
<- voteCh // prevote
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash1 , propBlockParts1 . Header ( ) , nil , cs2 , cs3 , c s4)
signAddVotes ( cs1 , types . VoteTypePrevote , propBlockHash1 , propBlockParts1 . Header ( ) , vs2 , vs3 , v s4)
<- voteCh // precommit
// the proposed block should now be locked and our precommit added
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash1 , propBlockHash1 )
// add precommits from the rest
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , c s4)
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , propBlockHash1 , propBlockParts1 . Header ( ) , nil )
signAddVotes ( cs1 , types . VoteTypePrecommit , nil , types . PartSetHeader { } , vs2 , v s4)
signAddVotes ( cs1 , types . VoteTypePrecommit , propBlockHash1 , propBlockParts1 . Header ( ) , vs3 )
incrementRound ( cs2 , cs3 , c s4)
incrementRound ( vs2 , vs3 , v s4)
// timeout of precommit wait to new round
<- timeoutWaitCh
// in round 2 we see the polkad block from round 0
newProp := types . NewProposal ( height , 2 , propBlockParts0 . Header ( ) , 0 )
if err := c s3. SignProposal ( config . GetString ( "chain_id" ) , newProp ) ; err != nil {
panic ( err )
if err := v s3. SignProposal ( config . GetString ( "chain_id" ) , newProp ) ; err != nil {
t . Fatal ( err )
}
cs1 . SetProposalAndBlock ( newProp , propBlock0 , propBlockParts0 , "some peer" )
addVoteToFromMany ( cs1 , prevotes , cs2 , cs3 , cs4 ) // add the pol votes
// Add the pol votes
addVotes ( cs1 , prevotes ... )
<- newRoundCh
log . Notice ( "### ONTO Round 2" )
@ -884,7 +902,7 @@ func TestLockPOLSafety2(t *testing.T) {
/ *
func TestSlashingPrevotes ( t * testing . T ) {
cs1 , vss := randConsensusState ( 2 )
c s2 := vss [ 1 ]
v s2 := vss [ 1 ]
proposalCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringCompleteProposal ( ) , 1 )
@ -904,7 +922,7 @@ func TestSlashingPrevotes(t *testing.T) {
// add one for a different block should cause us to go into prevote wait
hash := rs . ProposalBlock . Hash ( )
hash [ 0 ] = byte ( hash [ 0 ] + 1 ) % 255
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlockParts . Header ( ) , nil )
signAddVotes ( cs1 , types . VoteTypePrevote , hash , rs . ProposalBlockParts . Header ( ) , vs2 )
<- timeoutWaitCh
@ -912,14 +930,14 @@ func TestSlashingPrevotes(t *testing.T) {
// away and ignore more prevotes (and thus fail to slash!)
// add the conflicting vote
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil )
signAddVotes ( cs1 , types . VoteTypePrevote , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , vs2 )
// XXX: Check for existence of Dupeout info
}
func TestSlashingPrecommits ( t * testing . T ) {
cs1 , vss := randConsensusState ( 2 )
c s2 := vss [ 1 ]
v s2 := vss [ 1 ]
proposalCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringCompleteProposal ( ) , 1 )
@ -933,8 +951,8 @@ func TestSlashingPrecommits(t *testing.T) {
re := <- proposalCh
<- voteCh // prevote
// add prevote from c s2
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil )
// add prevote from v s2
signAddVotes ( cs1 , types . VoteTypePrevote , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , vs2 )
<- voteCh // precommit
@ -942,13 +960,13 @@ func TestSlashingPrecommits(t *testing.T) {
// add one for a different block should cause us to go into prevote wait
hash := rs . ProposalBlock . Hash ( )
hash [ 0 ] = byte ( hash [ 0 ] + 1 ) % 255
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlockParts . Header ( ) , nil )
signAddVotes ( cs1 , types . VoteTypePrecommit , hash , rs . ProposalBlockParts . Header ( ) , vs2 )
// NOTE: we have to send the vote for different block first so we don't just go into precommit round right
// away and ignore more prevotes (and thus fail to slash!)
// add precommit from c s2
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil )
// add precommit from v s2
signAddVotes ( cs1 , types . VoteTypePrecommit , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , vs2 )
// XXX: Check for existence of Dupeout info
}
@ -964,7 +982,7 @@ func TestSlashingPrecommits(t *testing.T) {
// we receive a final precommit after going into next round, but others might have gone to commit already!
func TestHalt1 ( t * testing . T ) {
cs1 , vss := randConsensusState ( 4 )
cs2 , cs3 , c s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
vs2 , vs3 , v s4 := vss [ 1 ] , vss [ 2 ] , vss [ 3 ]
proposalCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringCompleteProposal ( ) , 1 )
timeoutWaitCh := subscribeToEvent ( cs1 . evsw , "tester" , types . EventStringTimeoutWait ( ) , 1 )
@ -982,19 +1000,19 @@ func TestHalt1(t *testing.T) {
<- voteCh // prevote
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlock . Hash ( ) , propBlockParts . Header ( ) , nil , cs3 , c s4)
signAddVotes ( cs1 , types . VoteTypePrevote , propBlock . Hash ( ) , propBlockParts . Header ( ) , vs3 , v s4)
<- voteCh // precommit
// the proposed block should now be locked and our precommit added
validatePrecommit ( t , cs1 , 0 , 0 , vss [ 0 ] , propBlock . Hash ( ) , propBlock . Hash ( ) )
// add precommits from the rest
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , nil , types . PartSetHeader { } , nil ) // didnt receive proposal
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , propBlock . Hash ( ) , propBlockParts . Header ( ) , nil )
// we receive this later, but c s3 might receive it earlier and with ours will go to commit!
precommit4 := signVote ( c s4, types . VoteTypePrecommit , propBlock . Hash ( ) , propBlockParts . Header ( ) )
signAddVotes ( cs1 , types . VoteTypePrecommit , nil , types . PartSetHeader { } , vs2 ) // didnt receive proposal
signAddVotes ( cs1 , types . VoteTypePrecommit , propBlock . Hash ( ) , propBlockParts . Header ( ) , vs3 )
// we receive this later, but v s3 might receive it earlier and with ours will go to commit!
precommit4 := signVote ( v s4, types . VoteTypePrecommit , propBlock . Hash ( ) , propBlockParts . Header ( ) )
incrementRound ( cs2 , cs3 , c s4)
incrementRound ( vs2 , vs3 , v s4)
// timeout to new round
<- timeoutWaitCh
@ -1012,7 +1030,7 @@ func TestHalt1(t *testing.T) {
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , rs . LockedBlock . Hash ( ) )
// now we receive the precommit from the previous round
addVoteToFrom ( cs1 , cs4 , precommit4 )
addVotes ( cs1 , precommit4 )
// receiving that precommit should take us straight to commit
<- newBlockCh