@ -8,6 +8,7 @@ import (
"github.com/tendermint/tendermint/config/tendermint_test"
"github.com/tendermint/tendermint/config/tendermint_test"
//"github.com/tendermint/go-events"
//"github.com/tendermint/go-events"
. "github.com/tendermint/go-common"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/types"
)
)
@ -67,21 +68,21 @@ func TestProposerSelection0(t *testing.T) {
// lets 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 . Proposer ( )
prop := cs1 . GetRoundState ( ) . Validators . Proposer ( )
if ! bytes . Equal ( prop . Address , cs1 . privValidator . Address ) {
if ! bytes . Equal ( prop . Address , cs1 . privValidator . Address ) {
t . Fatalf ( "expected proposer to be validator %d. Got %X" , 0 , prop . Address )
panic ( Fmt ( "expected proposer to be validator %d. Got %X" , 0 , prop . Address ) )
}
}
// wait for complete proposal
// wait for complete proposal
<- proposalCh
<- proposalCh
rs := cs1 . GetRoundState ( )
rs := cs1 . GetRoundState ( )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , vss [ 1 : ] ... )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil , vss [ 1 : ] ... )
// wait for new round so next validator is set
// wait for new round so next validator is set
<- newRoundCh
<- newRoundCh
prop = cs1 . GetRoundState ( ) . Validators . Proposer ( )
prop = cs1 . GetRoundState ( ) . Validators . Proposer ( )
if ! bytes . Equal ( prop . Address , vss [ 1 ] . Address ) {
if ! bytes . Equal ( prop . Address , vss [ 1 ] . Address ) {
t . Fatalf ( "expected proposer to be validator %d. Got %X" , 1 , prop . Address )
panic ( Fmt ( "expected proposer to be validator %d. Got %X" , 1 , prop . Address ) )
}
}
}
}
@ -102,11 +103,11 @@ func TestProposerSelection2(t *testing.T) {
for i := 0 ; i < len ( vss ) ; i ++ {
for i := 0 ; i < len ( vss ) ; i ++ {
prop := cs1 . GetRoundState ( ) . Validators . Proposer ( )
prop := cs1 . GetRoundState ( ) . Validators . Proposer ( )
if ! bytes . Equal ( prop . Address , vss [ ( i + 2 ) % len ( vss ) ] . Address ) {
if ! bytes . Equal ( prop . Address , vss [ ( i + 2 ) % len ( vss ) ] . Address ) {
t . Fatalf ( "expected proposer to be validator %d. Got %X" , ( i + 2 ) % len ( vss ) , prop . Address )
panic ( Fmt ( "expected proposer to be validator %d. Got %X" , ( i + 2 ) % len ( vss ) , prop . Address ) )
}
}
rs := cs1 . GetRoundState ( )
rs := cs1 . GetRoundState ( )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , rs . ProposalBlockParts . Header ( ) , vss [ 1 : ] ... )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , rs . ProposalBlockParts . Header ( ) , nil , vss [ 1 : ] ... )
<- newRoundCh // wait for the new round event each round
<- newRoundCh // wait for the new round event each round
incrementRound ( vss [ 1 : ] ... )
incrementRound ( vss [ 1 : ] ... )
@ -130,7 +131,7 @@ func TestEnterProposeNoPrivValidator(t *testing.T) {
select {
select {
case <- timeoutCh :
case <- timeoutCh :
case <- ticker . C :
case <- ticker . C :
t . Fatal ( "Expected EnterPropose to timeout" )
panic ( "Expected EnterPropose to timeout" )
}
}
@ -170,7 +171,7 @@ func TestEnterProposeYesPrivValidator(t *testing.T) {
ticker := time . NewTicker ( cs . timeoutParams . ensureProposeTimeout ( ) )
ticker := time . NewTicker ( cs . timeoutParams . ensureProposeTimeout ( ) )
select {
select {
case <- timeoutCh :
case <- timeoutCh :
t . Fatal ( "Expected EnterPropose not to timeout" )
panic ( "Expected EnterPropose not to timeout" )
case <- ticker . C :
case <- ticker . C :
}
}
@ -200,7 +201,7 @@ func TestBadProposal(t *testing.T) {
propBlockParts := propBlock . MakePartSet ( )
propBlockParts := propBlock . MakePartSet ( )
proposal := types . NewProposal ( cs2 . Height , round , propBlockParts . Header ( ) , - 1 )
proposal := types . NewProposal ( cs2 . Height , round , propBlockParts . Header ( ) , - 1 )
if err := cs2 . SignProposal ( config . GetString ( "chain_id" ) , proposal ) ; err != nil {
if err := cs2 . SignProposal ( config . GetString ( "chain_id" ) , proposal ) ; err != nil {
t . Fatal ( "failed to sign bad proposal" , err )
panic ( "failed to sign bad proposal: " + err . Error ( ) )
}
}
// set the proposal block
// set the proposal block
@ -218,14 +219,13 @@ func TestBadProposal(t *testing.T) {
validatePrevote ( t , cs1 , round , vss [ 0 ] , nil )
validatePrevote ( t , cs1 , round , vss [ 0 ] , nil )
// add bad prevote from cs2 and wait for it
// add bad prevote from cs2 and wait for it
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) )
<- voteCh
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , voteCh )
// wait for precommit
// wait for precommit
<- voteCh
<- voteCh
validatePrecommit ( t , cs1 , round , 0 , vss [ 0 ] , nil , nil )
validatePrecommit ( t , cs1 , round , 0 , vss [ 0 ] , nil , nil )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , voteCh )
}
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
@ -292,12 +292,11 @@ func TestFullRound2(t *testing.T) {
<- voteCh // prevote
<- voteCh // prevote
// we should be stuck in limbo waiting for more prevotes
// we should be stuck in limbo waiting for more prevotes
propBlockHash , propPartsHeader := cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( )
rs := cs1 . GetRoundState ( )
propBlockHash , propPartsHeader := rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( )
// prevote arrives from cs2:
// prevote arrives from cs2:
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlockHash , propPartsHeader )
<- voteCh
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlockHash , propPartsHeader , voteCh )
<- voteCh //precommit
<- voteCh //precommit
@ -307,8 +306,7 @@ func TestFullRound2(t *testing.T) {
// we should be stuck in limbo waiting for more precommits
// we should be stuck in limbo waiting for more precommits
// precommit arrives from cs2:
// precommit arrives from cs2:
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , propBlockHash , propPartsHeader )
<- voteCh
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , propBlockHash , propPartsHeader , voteCh )
// wait to finish commit, propose in next height
// wait to finish commit, propose in next height
<- newBlockCh
<- newBlockCh
@ -346,8 +344,7 @@ func TestLockNoPOL(t *testing.T) {
// we should now be stuck in limbo forever, waiting for more prevotes
// we should now be stuck in limbo forever, waiting for more prevotes
// prevote arrives from cs2:
// prevote arrives from cs2:
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) )
<- voteCh // prevote
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , voteCh )
<- voteCh // precommit
<- voteCh // precommit
@ -360,8 +357,7 @@ func TestLockNoPOL(t *testing.T) {
hash := make ( [ ] byte , len ( theBlockHash ) )
hash := make ( [ ] byte , len ( theBlockHash ) )
copy ( hash , theBlockHash )
copy ( hash , theBlockHash )
hash [ 0 ] = byte ( ( hash [ 0 ] + 1 ) % 255 )
hash [ 0 ] = byte ( ( hash [ 0 ] + 1 ) % 255 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) )
<- voteCh // precommit
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh )
// (note we're entering precommit for a second time this round)
// (note we're entering precommit for a second time this round)
// but with invalid args. then we enterPrecommitWait, and the timeout to new round
// but with invalid args. then we enterPrecommitWait, and the timeout to new round
@ -382,7 +378,7 @@ func TestLockNoPOL(t *testing.T) {
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
if rs . ProposalBlock != nil {
if rs . ProposalBlock != nil {
t . Fatal ( "Expected proposal block to be nil" )
panic ( "Expected proposal block to be nil" )
}
}
// wait to finish prevote
// wait to finish prevote
@ -392,8 +388,7 @@ func TestLockNoPOL(t *testing.T) {
validatePrevote ( t , cs1 , 1 , vss [ 0 ] , rs . LockedBlock . Hash ( ) )
validatePrevote ( t , cs1 , 1 , vss [ 0 ] , rs . LockedBlock . Hash ( ) )
// add a conflicting prevote from the other validator
// add a conflicting prevote from the other validator
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) )
<- voteCh
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh )
// now we're going to enter prevote again, but with invalid args
// now we're going to enter prevote again, but with invalid args
// and then prevote wait, which should timeout. then wait for precommit
// and then prevote wait, which should timeout. then wait for precommit
@ -407,8 +402,7 @@ func TestLockNoPOL(t *testing.T) {
// add conflicting precommit from cs2
// add conflicting precommit from cs2
// NOTE: in practice we should never get to a point where there are precommits for different blocks at the same round
// 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
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh )
// (note we're entering precommit for a second time this round, but with invalid args
// (note we're entering precommit for a second time this round, but with invalid args
// then we enterPrecommitWait and timeout into NewRound
// then we enterPrecommitWait and timeout into NewRound
@ -427,29 +421,27 @@ func TestLockNoPOL(t *testing.T) {
// now we're on a new round and are the proposer
// now we're on a new round and are the proposer
if ! bytes . Equal ( rs . ProposalBlock . Hash ( ) , rs . LockedBlock . Hash ( ) ) {
if ! bytes . Equal ( rs . ProposalBlock . Hash ( ) , rs . LockedBlock . Hash ( ) ) {
t . Fatalf ( "Expected proposal block to be locked block. Got %v, Expected %v" , rs . ProposalBlock , rs . LockedBlock )
panic ( Fmt ( "Expected proposal block to be locked block. Got %v, Expected %v" , rs . ProposalBlock , rs . LockedBlock ) )
}
}
<- voteCh // prevote
<- voteCh // prevote
validatePrevote ( t , cs1 , 2 , vss [ 0 ] , rs . LockedBlock . Hash ( ) )
validatePrevote ( t , cs1 , 2 , vss [ 0 ] , rs . LockedBlock . Hash ( ) )
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) )
<- voteCh
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlock . MakePartSet ( ) . Header ( ) , voteCh )
<- timeoutWaitCh // prevote wait
<- timeoutWaitCh // prevote wait
<- voteCh // precommit
<- 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 ( ) ) // NOTE: conflicting precommits at same height
<- voteCh
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
<- timeoutWaitCh
<- timeoutWaitCh
// before we time out into new round, set next proposal block
// before we time out into new round, set next proposal block
prop , propBlock := decideProposal ( cs1 , cs2 , cs2 . Height , cs2 . Round + 1 )
prop , propBlock := decideProposal ( cs1 , cs2 , cs2 . Height , cs2 . Round + 1 )
if prop == nil || propBlock == nil {
if prop == nil || propBlock == nil {
t . Fatal ( "Failed to create proposal block with cs2" )
panic ( "Failed to create proposal block with cs2" )
}
}
incrementRound ( cs2 )
incrementRound ( cs2 )
@ -470,15 +462,13 @@ func TestLockNoPOL(t *testing.T) {
// prevote for locked block (not proposal)
// prevote for locked block (not proposal)
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , cs1 . LockedBlock . Hash ( ) )
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , cs1 . LockedBlock . Hash ( ) )
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) )
<- voteCh
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , propBlock . Hash ( ) , propBlock . MakePartSet ( ) . Header ( ) , voteCh )
<- timeoutWaitCh
<- timeoutWaitCh
<- voteCh
<- 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 ( ) ) // NOTE: conflicting precommits at same height
<- 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
}
}
// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
// 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka
@ -510,20 +500,19 @@ func TestLockPOLRelock(t *testing.T) {
re := <- proposalCh
re := <- proposalCh
rs := re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
rs := re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
theBlockHash := rs . ProposalBlock . Hash ( )
theBlockHash := rs . ProposalBlock . Hash ( )
theBlockPartsHeader := rs . ProposalBlockParts . Header ( )
<- voteCh // prevote
<- voteCh // prevote
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) , cs2 , cs3 , cs4 )
_ , _ , _ = <- voteCh , <- voteCh , <- voteCh // prevotes
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , theBlockHash , theBlockPartsHeader , voteCh , cs2 , cs3 , cs4 )
<- voteCh // our precommit
<- voteCh // our precommit
// the proposed block should now be locked and our precommit added
// the proposed block should now be locked and our precommit added
validatePrecommit ( t , cs1 , 0 , 0 , vss [ 0 ] , theBlockHash , theBlockHash )
validatePrecommit ( t , cs1 , 0 , 0 , vss [ 0 ] , theBlockHash , theBlockHash )
// add precommits from the rest
// add precommits from the rest
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , cs2 , cs4 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) )
_ , _ , _ = <- voteCh , <- voteCh , <- voteCh // precommits
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , voteCh , cs2 , cs4 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , theBlockHash , theBlockPartsHeader , voteCh )
// before we timeout to the new round set the new proposal
// before we timeout to the new round set the new proposal
prop , propBlock := decideProposal ( cs1 , cs2 , cs2 . Height , cs2 . Round + 1 )
prop , propBlock := decideProposal ( cs1 , cs2 , cs2 . Height , cs2 . Round + 1 )
@ -560,12 +549,13 @@ func TestLockPOLRelock(t *testing.T) {
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , theBlockHash )
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , theBlockHash )
// now lets add prevotes from everyone else for the new block
// now lets add prevotes from everyone else for the new block
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash , propBlockParts . Header ( ) , cs2 , cs3 , cs4 )
_ , _ , _ = <- voteCh , <- voteCh , <- voteCh // prevotes
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash , propBlockParts . Header ( ) , voteCh , cs2 , cs3 , cs4 )
// now either we go to PrevoteWait or Precommit
// now either we go to PrevoteWait or Precommit
select {
select {
case <- timeoutWaitCh : // we're in PrevoteWait, go to Precommit
case <- timeoutWaitCh : // we're in PrevoteWait, go to Precommit
// XXX: there's no guarantee we see the polka, this might be a precommit for nil,
// in which case the test fails!
<- voteCh
<- voteCh
case <- voteCh : // we went straight to Precommit
case <- voteCh : // we went straight to Precommit
}
}
@ -573,19 +563,18 @@ func TestLockPOLRelock(t *testing.T) {
// we should have unlocked and locked on the new block
// we should have unlocked and locked on the new block
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash , propBlockHash )
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash , propBlockHash )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , propBlockHash , propBlockParts . Header ( ) , cs2 , cs3 )
_ , _ = <- voteCh , <- voteCh
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , propBlockHash , propBlockParts . Header ( ) , voteCh , cs2 , cs3 )
be := <- newBlockCh
be := <- newBlockCh
b := be . ( types . EventDataNewBlockHeader )
b := be . ( types . EventDataNewBlockHeader )
re = <- newRoundCh
re = <- newRoundCh
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
if rs . Height != 2 {
if rs . Height != 2 {
t . Fatal ( "Expected height to increment" )
panic ( "Expected height to increment" )
}
}
if ! bytes . Equal ( b . Header . Hash ( ) , propBlockHash ) {
if ! bytes . Equal ( b . Header . Hash ( ) , propBlockHash ) {
t . Fatal ( "Expected new block to be proposal block" )
panic ( "Expected new block to be proposal block" )
}
}
}
}
@ -618,16 +607,18 @@ func TestLockPOLUnlock(t *testing.T) {
<- voteCh // prevote
<- voteCh // prevote
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) , cs2 , cs3 , cs4 )
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil , cs2 , cs3 , cs4 )
<- voteCh //precommit
<- voteCh //precommit
// the proposed block should now be locked and our precommit added
// the proposed block should now be locked and our precommit added
validatePrecommit ( t , cs1 , 0 , 0 , vss [ 0 ] , theBlockHash , theBlockHash )
validatePrecommit ( t , cs1 , 0 , 0 , vss [ 0 ] , theBlockHash , theBlockHash )
rs = cs1 . GetRoundState ( )
// add precommits from the rest
// add precommits from the rest
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , cs2 , cs4 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , cs1 . ProposalBlock . Hash ( ) , cs1 . ProposalBlockParts . Header ( ) )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , cs4 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil )
// before we time out into new round, set next proposal block
// before we time out into new round, set next proposal block
prop , propBlock := decideProposal ( cs1 , cs2 , cs2 . Height , cs2 . Round + 1 )
prop , propBlock := decideProposal ( cs1 , cs2 , cs2 . Height , cs2 . Round + 1 )
@ -663,7 +654,7 @@ func TestLockPOLUnlock(t *testing.T) {
<- voteCh
<- voteCh
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , lockedBlockHash )
validatePrevote ( t , cs1 , 0 , vss [ 0 ] , lockedBlockHash )
// now lets add prevotes from everyone else for nil (a polka!)
// now lets add prevotes from everyone else for nil (a polka!)
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , nil , types . PartSetHeader { } , cs2 , cs3 , cs4 )
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , nil , types . PartSetHeader { } , nil , cs2 , cs3 , cs4 )
// the polka makes us unlock and precommit nil
// the polka makes us unlock and precommit nil
<- unlockCh
<- unlockCh
@ -673,7 +664,7 @@ func TestLockPOLUnlock(t *testing.T) {
// NOTE: since we don't relock on nil, the lock round is 0
// NOTE: since we don't relock on nil, the lock round is 0
validatePrecommit ( t , cs1 , 1 , 0 , vss [ 0 ] , nil , nil )
validatePrecommit ( t , cs1 , 1 , 0 , vss [ 0 ] , nil , nil )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , cs2 , cs3 )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , cs3 )
<- newRoundCh
<- newRoundCh
}
}
@ -711,13 +702,13 @@ func TestLockPOLSafety1(t *testing.T) {
_ , v1 := cs1 . Validators . GetByAddress ( vss [ 0 ] . Address )
_ , v1 := cs1 . Validators . GetByAddress ( vss [ 0 ] . Address )
v1 . VotingPower = 1
v1 . VotingPower = 1
if updated := cs1 . Validators . Update ( v1 ) ; ! updated {
if updated := cs1 . Validators . Update ( v1 ) ; ! updated {
t . Fatal ( "failed to update validator" )
panic ( "failed to update validator" )
} * /
} * /
log . Warn ( "old prop" , "hash" , fmt . Sprintf ( "%X" , propBlock . Hash ( ) ) )
log . Warn ( "old prop" , "hash" , fmt . Sprintf ( "%X" , propBlock . Hash ( ) ) )
// we do see them precommit nil
// we do see them precommit nil
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , cs2 , cs3 , cs4 )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , cs3 , cs4 )
prop , propBlock := decideProposal ( cs1 , cs2 , cs2 . Height , cs2 . Round + 1 )
prop , propBlock := decideProposal ( cs1 , cs2 , cs2 . Height , cs2 . Round + 1 )
propBlockHash := propBlock . Hash ( )
propBlockHash := propBlock . Hash ( )
@ -746,7 +737,7 @@ func TestLockPOLSafety1(t *testing.T) {
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
if rs . LockedBlock != nil {
if rs . LockedBlock != nil {
t . Fatal ( "we should not be locked!" )
panic ( "we should not be locked!" )
}
}
log . Warn ( "new prop" , "hash" , fmt . Sprintf ( "%X" , propBlockHash ) )
log . Warn ( "new prop" , "hash" , fmt . Sprintf ( "%X" , propBlockHash ) )
// go to prevote, prevote for proposal block
// go to prevote, prevote for proposal block
@ -754,14 +745,14 @@ func TestLockPOLSafety1(t *testing.T) {
validatePrevote ( t , cs1 , 1 , vss [ 0 ] , propBlockHash )
validatePrevote ( t , cs1 , 1 , vss [ 0 ] , propBlockHash )
// now we see the others prevote for it, so we should lock on it
// now we see the others prevote for it, so we should lock on it
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash , propBlockParts . Header ( ) , cs2 , cs3 , cs4 )
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash , propBlockParts . Header ( ) , nil , cs2 , cs3 , cs4 )
<- voteCh // precommit
<- voteCh // precommit
// we should have precommitted
// we should have precommitted
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash , propBlockHash )
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash , propBlockHash )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , cs2 , cs3 )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , cs3 )
<- timeoutWaitCh
<- timeoutWaitCh
@ -840,15 +831,15 @@ func TestLockPOLSafety2(t *testing.T) {
<- voteCh // prevote
<- voteCh // prevote
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash1 , propBlockParts1 . Header ( ) , cs2 , cs3 , cs4 )
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlockHash1 , propBlockParts1 . Header ( ) , nil , cs2 , cs3 , cs4 )
<- voteCh // precommit
<- voteCh // precommit
// the proposed block should now be locked and our precommit added
// the proposed block should now be locked and our precommit added
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash1 , propBlockHash1 )
validatePrecommit ( t , cs1 , 1 , 1 , vss [ 0 ] , propBlockHash1 , propBlockHash1 )
// add precommits from the rest
// add precommits from the rest
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , cs2 , cs4 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , propBlockHash1 , propBlockParts1 . Header ( ) )
signAddVoteToFromMany ( types . VoteTypePrecommit , cs1 , nil , types . PartSetHeader { } , nil , cs2 , cs4 )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , propBlockHash1 , propBlockParts1 . Header ( ) , nil )
incrementRound ( cs2 , cs3 , cs4 )
incrementRound ( cs2 , cs3 , cs4 )
@ -858,7 +849,7 @@ func TestLockPOLSafety2(t *testing.T) {
// in round 2 we see the polkad block from round 0
// in round 2 we see the polkad block from round 0
newProp := types . NewProposal ( height , 2 , propBlockParts0 . Header ( ) , 0 )
newProp := types . NewProposal ( height , 2 , propBlockParts0 . Header ( ) , 0 )
if err := cs3 . SignProposal ( config . GetString ( "chain_id" ) , newProp ) ; err != nil {
if err := cs3 . SignProposal ( config . GetString ( "chain_id" ) , newProp ) ; err != nil {
t . Fatal ( err )
panic ( err )
}
}
cs1 . SetProposalAndBlock ( newProp , propBlock0 , propBlockParts0 , "some peer" )
cs1 . SetProposalAndBlock ( newProp , propBlock0 , propBlockParts0 , "some peer" )
addVoteToFromMany ( cs1 , prevotes , cs2 , cs3 , cs4 ) // add the pol votes
addVoteToFromMany ( cs1 , prevotes , cs2 , cs3 , cs4 ) // add the pol votes
@ -877,7 +868,7 @@ func TestLockPOLSafety2(t *testing.T) {
select {
select {
case <- unlockCh :
case <- unlockCh :
t . Fatal ( "validator unlocked using an old polka" )
panic ( "validator unlocked using an old polka" )
case <- voteCh :
case <- voteCh :
// prevote our locked block
// prevote our locked block
}
}
@ -910,9 +901,9 @@ func TestSlashingPrevotes(t *testing.T) {
// we should now be stuck in limbo forever, waiting for more prevotes
// we should now be stuck in limbo forever, waiting for more prevotes
// add one for a different block should cause us to go into prevote wait
// add one for a different block should cause us to go into prevote wait
hash := cs1 . ProposalBlock . Hash ( )
hash := rs . ProposalBlock . Hash ( )
hash [ 0 ] = byte ( hash [ 0 ] + 1 ) % 255
hash [ 0 ] = byte ( hash [ 0 ] + 1 ) % 255
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlockParts . Header ( ) )
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , hash , rs . ProposalBlockParts . Header ( ) , nil )
<- timeoutWaitCh
<- timeoutWaitCh
@ -920,7 +911,7 @@ func TestSlashingPrevotes(t *testing.T) {
// away and ignore more prevotes (and thus fail to slash!)
// away and ignore more prevotes (and thus fail to slash!)
// add the conflicting vote
// add the conflicting vote
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) )
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil )
// XXX: Check for existence of Dupeout info
// XXX: Check for existence of Dupeout info
}
}
@ -942,7 +933,7 @@ func TestSlashingPrecommits(t *testing.T) {
<- voteCh // prevote
<- voteCh // prevote
// add prevote from cs2
// add prevote from cs2
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) )
signAddVoteToFrom ( types . VoteTypePrevote , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil )
<- voteCh // precommit
<- voteCh // precommit
@ -950,13 +941,13 @@ func TestSlashingPrecommits(t *testing.T) {
// add one for a different block should cause us to go into prevote wait
// add one for a different block should cause us to go into prevote wait
hash := rs . ProposalBlock . Hash ( )
hash := rs . ProposalBlock . Hash ( )
hash [ 0 ] = byte ( hash [ 0 ] + 1 ) % 255
hash [ 0 ] = byte ( hash [ 0 ] + 1 ) % 255
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlockParts . Header ( ) )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , hash , rs . ProposalBlockParts . Header ( ) , nil )
// NOTE: we have to send the vote for different block first so we don't just go into precommit round right
// 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!)
// away and ignore more prevotes (and thus fail to slash!)
// add precommit from cs2
// add precommit from cs2
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) )
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , rs . ProposalBlock . Hash ( ) , rs . ProposalBlockParts . Header ( ) , nil )
// XXX: Check for existence of Dupeout info
// XXX: Check for existence of Dupeout info
}
}
@ -990,15 +981,15 @@ func TestHalt1(t *testing.T) {
<- voteCh // prevote
<- voteCh // prevote
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlock . Hash ( ) , propBlockParts . Header ( ) , cs3 , cs4 )
signAddVoteToFromMany ( types . VoteTypePrevote , cs1 , propBlock . Hash ( ) , propBlockParts . Header ( ) , nil , cs3 , cs4 )
<- voteCh // precommit
<- voteCh // precommit
// the proposed block should now be locked and our precommit added
// the proposed block should now be locked and our precommit added
validatePrecommit ( t , cs1 , 0 , 0 , vss [ 0 ] , propBlock . Hash ( ) , propBlock . Hash ( ) )
validatePrecommit ( t , cs1 , 0 , 0 , vss [ 0 ] , propBlock . Hash ( ) , propBlock . Hash ( ) )
// add precommits from the rest
// add precommits from the rest
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs2 , nil , types . PartSetHeader { } ) // didnt receive proposal
signAddVoteToFrom ( types . VoteTypePrecommit , cs1 , cs3 , propBlock . Hash ( ) , propBlockParts . Header ( ) )
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 cs3 might receive it earlier and with ours will go to commit!
// we receive this later, but cs3 might receive it earlier and with ours will go to commit!
precommit4 := signVote ( cs4 , types . VoteTypePrecommit , propBlock . Hash ( ) , propBlockParts . Header ( ) )
precommit4 := signVote ( cs4 , types . VoteTypePrecommit , propBlock . Hash ( ) , propBlockParts . Header ( ) )
@ -1028,6 +1019,6 @@ func TestHalt1(t *testing.T) {
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
rs = re . ( types . EventDataRoundState ) . RoundState . ( * RoundState )
if rs . Height != 2 {
if rs . Height != 2 {
t . Fatal ( "expected height to increment" )
panic ( "expected height to increment" )
}
}
}
}