@ -222,11 +222,7 @@ func TestLunaticValidatorEvidence(t *testing.T) {
header . Time = bTime
ev := & LunaticValidatorEvidence {
Header : header ,
Vote : vote ,
InvalidHeaderField : "AppHash" ,
}
ev := NewLunaticValidatorEvidence ( header , vote , "AppHash" )
assert . Equal ( t , header . Height , ev . Height ( ) )
assert . Equal ( t , defaultVoteTime , ev . Time ( ) )
@ -253,10 +249,7 @@ func TestPhantomValidatorEvidence(t *testing.T) {
vote = makeVote ( t , val , header . ChainID , 0 , header . Height , 0 , 2 , blockID , defaultVoteTime )
)
ev := & PhantomValidatorEvidence {
Vote : vote ,
LastHeightValidatorWasInSet : header . Height - 1 ,
}
ev := NewPhantomValidatorEvidence ( vote , header . Height - 1 )
assert . Equal ( t , header . Height , ev . Height ( ) )
assert . Equal ( t , defaultVoteTime , ev . Time ( ) )
@ -315,17 +308,17 @@ func TestConflictingHeadersEvidence(t *testing.T) {
} , height , 1 , voteSet2 , vals , time . Now ( ) )
require . NoError ( t , err )
ev := & ConflictingHeadersEvidence {
H1 : & SignedHeader {
Header : header1 ,
Commit : commit1 ,
} ,
H2 : & SignedHeader {
Header : header2 ,
Commit : commit2 ,
} ,
h1 := & SignedHeader {
Header : header1 ,
Commit : commit1 ,
}
h2 := & SignedHeader {
Header : header2 ,
Commit : commit2 ,
}
ev := NewConflictingHeadersEvidence ( h1 , h2 )
assert . Panics ( t , func ( ) {
ev . Address ( )
} )
@ -356,13 +349,11 @@ func TestPotentialAmnesiaEvidence(t *testing.T) {
blockID = makeBlockID ( tmhash . Sum ( [ ] byte ( "blockhash" ) ) , math . MaxInt32 , tmhash . Sum ( [ ] byte ( "partshash" ) ) )
blockID2 = makeBlockID ( tmhash . Sum ( [ ] byte ( "blockhash2" ) ) , math . MaxInt32 , tmhash . Sum ( [ ] byte ( "partshash" ) ) )
vote1 = makeVote ( t , val , chainID , 0 , height , 0 , 2 , blockID , defaultVoteTime )
vote2 = makeVote ( t , val , chainID , 0 , height , 1 , 2 , blockID2 , defaultVoteTime . Add ( 1 * time . Minute ) )
vote2 = makeVote ( t , val , chainID , 0 , height , 1 , 2 , blockID2 , defaultVoteTime . Add ( 1 * time . Second ) )
vote3 = makeVote ( t , val , chainID , 0 , height , 2 , 2 , blockID , defaultVoteTime )
)
ev := & PotentialAmnesiaEvidence {
VoteA : vote1 ,
VoteB : vote2 ,
}
ev := NewPotentialAmnesiaEvidence ( vote1 , vote2 )
assert . Equal ( t , height , ev . Height ( ) )
assert . Equal ( t , vote2 . Timestamp , ev . Time ( ) )
@ -379,6 +370,35 @@ func TestPotentialAmnesiaEvidence(t *testing.T) {
assert . True ( t , ev . Equal ( ev ) )
assert . NoError ( t , ev . ValidateBasic ( ) )
assert . NotEmpty ( t , ev . String ( ) )
ev2 := & PotentialAmnesiaEvidence {
VoteA : vote1 ,
VoteB : vote2 ,
HeightStamp : 5 ,
}
assert . True ( t , ev . Equal ( ev2 ) )
assert . Equal ( t , ev . Hash ( ) , ev2 . Hash ( ) )
ev3 := & PotentialAmnesiaEvidence {
VoteA : vote2 ,
VoteB : vote1 ,
}
assert . Error ( t , ev3 . ValidateBasic ( ) )
ev3 = NewPotentialAmnesiaEvidence ( vote2 , vote1 )
assert . True ( t , ev3 . Equal ( ev ) )
ev4 := & PotentialAmnesiaEvidence {
VoteA : vote3 ,
VoteB : vote2 ,
}
assert . NoError ( t , ev4 . ValidateBasic ( ) )
assert . NotEqual ( t , ev . Hash ( ) , ev4 . Hash ( ) )
assert . False ( t , ev . Equal ( ev4 ) )
}
func TestProofOfLockChange ( t * testing . T ) {
@ -390,7 +410,8 @@ func TestProofOfLockChange(t *testing.T) {
voteSet , valSet , privValidators , blockID := buildVoteSet ( height , 1 , 3 , 7 , 0 , tmproto . PrecommitType )
pubKey , err := privValidators [ 7 ] . GetPubKey ( )
require . NoError ( t , err )
polc := makePOLCFromVoteSet ( voteSet , pubKey , blockID )
polc , err := NewPOLCFromVoteSet ( voteSet , pubKey , blockID )
assert . NoError ( t , err )
assert . Equal ( t , height , polc . Height ( ) )
assert . NoError ( t , polc . ValidateBasic ( ) )
@ -410,34 +431,34 @@ func TestProofOfLockChange(t *testing.T) {
assert . Error ( t , err )
// test validate basic on a set of bad cases
var badPOLCs [ ] ProofOfLockChange
var badPOLCs [ ] * ProofOfLockChange
// 2: node has already voted in next round
pubKey , err = privValidators [ 0 ] . GetPubKey ( )
require . NoError ( t , err )
polc2 := make POLCFromVoteSet( voteSet , pubKey , blockID )
polc2 := new POLCFromVoteSet( voteSet , pubKey , blockID )
badPOLCs = append ( badPOLCs , polc2 )
// 3: one vote was from a different round
voteSet , _ , privValidators , blockID = buildVoteSet ( height , 1 , 3 , 7 , 0 , tmproto . PrecommitType )
pubKey , err = privValidators [ 7 ] . GetPubKey ( )
require . NoError ( t , err )
polc = make POLCFromVoteSet( voteSet , pubKey , blockID )
polc = new POLCFromVoteSet( voteSet , pubKey , blockID )
badVote := makeVote ( t , privValidators [ 8 ] , chainID , 8 , height , 2 , 2 , blockID , defaultVoteTime )
polc . Votes = append ( polc . Votes , * badVote )
polc . Votes = append ( polc . Votes , badVote )
badPOLCs = append ( badPOLCs , polc )
// 4: one vote was from a different height
polc = make POLCFromVoteSet( voteSet , pubKey , blockID )
polc = new POLCFromVoteSet( voteSet , pubKey , blockID )
badVote = makeVote ( t , privValidators [ 8 ] , chainID , 8 , height + 1 , 1 , 2 , blockID , defaultVoteTime )
polc . Votes = append ( polc . Votes , * badVote )
polc . Votes = append ( polc . Votes , badVote )
badPOLCs = append ( badPOLCs , polc )
// 5: one vote was from a different vote type
polc = make POLCFromVoteSet( voteSet , pubKey , blockID )
polc = new POLCFromVoteSet( voteSet , pubKey , blockID )
badVote = makeVote ( t , privValidators [ 8 ] , chainID , 8 , height , 1 , 1 , blockID , defaultVoteTime )
polc . Votes = append ( polc . Votes , * badVote )
polc . Votes = append ( polc . Votes , badVote )
badPOLCs = append ( badPOLCs , polc )
// 5: one of the votes was for a nil block
polc = make POLCFromVoteSet( voteSet , pubKey , blockID )
polc = new POLCFromVoteSet( voteSet , pubKey , blockID )
badVote = makeVote ( t , privValidators [ 8 ] , chainID , 8 , height , 1 , 2 , BlockID { } , defaultVoteTime )
polc . Votes = append ( polc . Votes , * badVote )
polc . Votes = append ( polc . Votes , badVote )
badPOLCs = append ( badPOLCs , polc )
for idx , polc := range badPOLCs {
@ -467,17 +488,17 @@ func TestAmnesiaEvidence(t *testing.T) {
vote2 = makeVote ( t , val , chainID , 7 , height , 1 , 2 , blockID ,
time . Now ( ) . Add ( time . Second ) )
vote3 = makeVote ( t , val , chainID , 7 , height , 2 , 2 , blockID2 , time . Now ( ) )
polc = make POLCFromVoteSet( voteSet , pubKey , blockID )
polc = new POLCFromVoteSet( voteSet , pubKey , blockID )
)
require . False ( t , polc . IsAbsent ( ) )
pe := PotentialAmnesiaEvidence {
pe := & PotentialAmnesiaEvidence {
VoteA : vote1 ,
VoteB : vote2 ,
}
emptyAmnesiaEvidence := Make AmnesiaEvidence( pe , EmptyPOLC ( ) )
emptyAmnesiaEvidence := New AmnesiaEvidence( pe , New EmptyPOLC( ) )
assert . NoError ( t , emptyAmnesiaEvidence . ValidateBasic ( ) )
violated , reason := emptyAmnesiaEvidence . ViolatedConsensus ( )
@ -486,7 +507,7 @@ func TestAmnesiaEvidence(t *testing.T) {
}
assert . NoError ( t , emptyAmnesiaEvidence . Verify ( chainID , pubKey ) )
completeAmnesiaEvidence := Make AmnesiaEvidence( pe , polc )
completeAmnesiaEvidence := New AmnesiaEvidence( pe , polc )
assert . NoError ( t , completeAmnesiaEvidence . ValidateBasic ( ) )
violated , reason = completeAmnesiaEvidence . ViolatedConsensus ( )
@ -497,40 +518,41 @@ func TestAmnesiaEvidence(t *testing.T) {
assert . NoError ( t , completeAmnesiaEvidence . Polc . ValidateVotes ( valSet , chainID ) )
assert . True ( t , completeAmnesiaEvidence . Equal ( emptyAmnesiaEvidence ) )
assert . Equal ( t , completeAmnesiaEvidence . Hash ( ) , emptyAmnesiaEvidence . Hash ( ) )
assert . NotEmpty ( t , completeAmnesiaEvidence . Hash ( ) )
assert . NotEmpty ( t , completeAmnesiaEvidence . Bytes ( ) )
pe2 := PotentialAmnesiaEvidence {
pe2 := & PotentialAmnesiaEvidence {
VoteA : vote3 ,
VoteB : vote2 ,
}
// validator has incorrectly voted for a previous round after voting for a later round
ae := Make AmnesiaEvidence( pe2 , EmptyPOLC ( ) )
ae := New AmnesiaEvidence( pe2 , New EmptyPOLC( ) )
assert . NoError ( t , ae . ValidateBasic ( ) )
violated , reason = ae . ViolatedConsensus ( )
if assert . True ( t , violated ) {
assert . Equal ( t , reason , "validator went back and voted on a previous round" )
}
var badAE [ ] AmnesiaEvidence
var badAE [ ] * AmnesiaEvidence
// 1) Polc is at an incorrect height
voteSet , _ , _ = buildVoteSetForBlock ( height + 1 , 1 , 2 , 7 , 0 , tmproto . PrecommitType , blockID )
polc = make POLCFromVoteSet( voteSet , pubKey , blockID )
badAE = append ( badAE , Make AmnesiaEvidence( pe , polc ) )
polc = new POLCFromVoteSet( voteSet , pubKey , blockID )
badAE = append ( badAE , New AmnesiaEvidence( pe , polc ) )
// 2) Polc is of a later round
voteSet , _ , _ = buildVoteSetForBlock ( height , 2 , 2 , 7 , 0 , tmproto . PrecommitType , blockID )
polc = make POLCFromVoteSet( voteSet , pubKey , blockID )
badAE = append ( badAE , Make AmnesiaEvidence( pe , polc ) )
polc = new POLCFromVoteSet( voteSet , pubKey , blockID )
badAE = append ( badAE , New AmnesiaEvidence( pe , polc ) )
// 3) Polc has a different public key
voteSet , _ , privValidators = buildVoteSetForBlock ( height , 1 , 2 , 7 , 0 , tmproto . PrecommitType , blockID )
pubKey2 , _ := privValidators [ 7 ] . GetPubKey ( )
polc = make POLCFromVoteSet( voteSet , pubKey2 , blockID )
badAE = append ( badAE , Make AmnesiaEvidence( pe , polc ) )
polc = new POLCFromVoteSet( voteSet , pubKey2 , blockID )
badAE = append ( badAE , New AmnesiaEvidence( pe , polc ) )
// 4) Polc has a different block ID
voteSet , _ , _ , blockID = buildVoteSet ( height , 1 , 2 , 7 , 0 , tmproto . PrecommitType )
polc = make POLCFromVoteSet( voteSet , pubKey , blockID )
badAE = append ( badAE , Make AmnesiaEvidence( pe , polc ) )
polc = new POLCFromVoteSet( voteSet , pubKey , blockID )
badAE = append ( badAE , New AmnesiaEvidence( pe , polc ) )
for idx , ae := range badAE {
t . Log ( ae . ValidateBasic ( ) )
@ -638,58 +660,56 @@ func TestEvidenceProto(t *testing.T) {
}
tests := [ ] struct {
testName string
evidence Evidence
wantErr bool
wantErr2 bool
testName string
evidence Evidence
toProtoErr bool
fromProtoErr bool
} {
{ "&DuplicateVoteEvidence empty fail" , & DuplicateVoteEvidence { } , false , true } ,
{ "&DuplicateVoteEvidence nil voteB" , & DuplicateVoteEvidence { VoteA : v , VoteB : nil } , false , true } ,
{ "&DuplicateVoteEvidence nil voteA" , & DuplicateVoteEvidence { VoteA : nil , VoteB : v } , false , true } ,
{ "&DuplicateVoteEvidence success" , & DuplicateVoteEvidence { VoteA : v2 , VoteB : v } , false , false } ,
{ "&ConflictingHeadersEvidence empty fail" , & ConflictingHeadersEvidence { } , false , true } ,
{ "&ConflictingHeadersEvidence nil H2" , & ConflictingHeadersEvidence { H1 : h1 , H2 : nil } , false , true } ,
{ "&ConflictingHeadersEvidence nil H1" , & ConflictingHeadersEvidence { H1 : nil , H2 : h2 } , false , true } ,
{ "ConflictingHeadersEvidence empty fail" , ConflictingHeadersEvidence { } , false , true } ,
{ "ConflictingHeadersEvidence nil H2" , ConflictingHeadersEvidence { H1 : h1 , H2 : nil } , false , true } ,
{ "ConflictingHeadersEvidence nil H1" , ConflictingHeadersEvidence { H1 : nil , H2 : h2 } , false , true } ,
{ "ConflictingHeadersEvidence success" , ConflictingHeadersEvidence { H1 : h1 , H2 : h2 } , false , false } ,
{ "LunaticValidatorEvidence empty fail" , LunaticValidatorEvidence { } , false , true } ,
{ "LunaticValidatorEvidence only header fail" , LunaticValidatorEvidence { Header : header1 } , false , true } ,
{ "LunaticValidatorEvidence only vote fail" , LunaticValidatorEvidence { Vote : v } , false , true } ,
{ "LunaticValidatorEvidence header & vote fail" , LunaticValidatorEvidence { Header : header1 , Vote : v } , false , true } ,
{ "LunaticValidatorEvidence success" , LunaticValidatorEvidence { Header : header1 ,
{ "nil fail" , nil , true , true } ,
{ "DuplicateVoteEvidence empty fail" , & DuplicateVoteEvidence { } , false , true } ,
{ "DuplicateVoteEvidence nil voteB" , & DuplicateVoteEvidence { VoteA : v , VoteB : nil } , false , true } ,
{ "DuplicateVoteEvidence nil voteA" , & DuplicateVoteEvidence { VoteA : nil , VoteB : v } , false , true } ,
{ "DuplicateVoteEvidence success" , & DuplicateVoteEvidence { VoteA : v2 , VoteB : v } , false , false } ,
{ "ConflictingHeadersEvidence empty fail" , & ConflictingHeadersEvidence { } , false , true } ,
{ "ConflictingHeadersEvidence nil H2" , & ConflictingHeadersEvidence { H1 : h1 , H2 : nil } , false , true } ,
{ "ConflictingHeadersEvidence nil H1" , & ConflictingHeadersEvidence { H1 : nil , H2 : h2 } , false , true } ,
{ "ConflictingHeadersEvidence success" , & ConflictingHeadersEvidence { H1 : h1 , H2 : h2 } , false , false } ,
{ "LunaticValidatorEvidence success" , & LunaticValidatorEvidence { Header : header1 ,
Vote : v , InvalidHeaderField : "ValidatorsHash" } , false , true } ,
{ "&LunaticValidatorEvidence empty fail" , & LunaticValidatorEvidence { } , false , true } ,
{ "LunaticValidatorEvidence only header fail" , & LunaticValidatorEvidence { Header : header1 } , false , true } ,
{ "LunaticValidatorEvidence only vote fail" , & LunaticValidatorEvidence { Vote : v } , false , true } ,
{ "LunaticValidatorEvidence header & vote fail" , & LunaticValidatorEvidence { Header : header1 , Vote : v } , false , true } ,
{ "&LunaticValidatorEvidence empty fail" , & LunaticValidatorEvidence { } , false , true } ,
{ "PotentialAmnesiaEvidence empty fail" , PotentialAmnesiaEvidence { } , false , true } ,
{ "PotentialAmnesiaEvidence nil VoteB" , PotentialAmnesiaEvidence { VoteA : v , VoteB : nil } , false , true } ,
{ "PotentialAmnesiaEvidence nil VoteA" , PotentialAmnesiaEvidence { VoteA : nil , VoteB : v2 } , false , true } ,
{ "&PotentialAmnesiaEvidence empty fail" , & PotentialAmnesiaEvidence { } , false , true } ,
{ "&PotentialAmnesiaEvidence nil VoteB" , & PotentialAmnesiaEvidence { VoteA : v , VoteB : nil } , false , true } ,
{ "&PotentialAmnesiaEvidence nil VoteA" , & PotentialAmnesiaEvidence { VoteA : nil , VoteB : v2 } , false , true } ,
{ "&PotentialAmnesiaEvidence success" , & PotentialAmnesiaEvidence { VoteA : v2 , VoteB : v } , false , false } ,
{ "&PhantomValidatorEvidence empty fail" , & PhantomValidatorEvidence { } , false , true } ,
{ "&PhantomValidatorEvidence nil LastHeightValidatorWasInSet" , & PhantomValidatorEvidence { Vote : v } , false , true } ,
{ "&PhantomValidatorEvidence nil Vote" , & PhantomValidatorEvidence { LastHeightValidatorWasInSet : 2 } , false , true } ,
{ "PhantomValidatorEvidence success" , PhantomValidatorEvidence { Vote : v2 , LastHeightValidatorWasInSet : 2 } ,
{ "LunaticValidatorEvidence empty fail" , & LunaticValidatorEvidence { } , false , true } ,
{ "PotentialAmnesiaEvidence empty fail" , & PotentialAmnesiaEvidence { } , false , true } ,
{ "PotentialAmnesiaEvidence nil VoteB" , & PotentialAmnesiaEvidence { VoteA : v , VoteB : nil } , false , true } ,
{ "PotentialAmnesiaEvidence nil VoteA" , & PotentialAmnesiaEvidence { VoteA : nil , VoteB : v2 } , false , true } ,
{ "PotentialAmnesiaEvidence success" , & PotentialAmnesiaEvidence { VoteA : v2 , VoteB : v } , false , false } ,
{ "PhantomValidatorEvidence empty fail" , & PhantomValidatorEvidence { } , false , true } ,
{ "PhantomValidatorEvidence nil LastHeightValidatorWasInSet" , & PhantomValidatorEvidence { Vote : v } , false , true } ,
{ "PhantomValidatorEvidence nil Vote" , & PhantomValidatorEvidence { LastHeightValidatorWasInSet : 2 } , false , true } ,
{ "PhantomValidatorEvidence success" , & PhantomValidatorEvidence { Vote : v2 , LastHeightValidatorWasInSet : 2 } ,
false , false } ,
{ "AmnesiaEvidence nil ProofOfLockChange" , & AmnesiaEvidence { PotentialAmnesiaEvidence : & PotentialAmnesiaEvidence { } ,
Polc : NewEmptyPOLC ( ) } , false , true } ,
{ "AmnesiaEvidence nil Polc" ,
& AmnesiaEvidence { PotentialAmnesiaEvidence : & PotentialAmnesiaEvidence { VoteA : v2 , VoteB : v } ,
Polc : & ProofOfLockChange { } } , false , false } ,
{ "AmnesiaEvidence success" , & AmnesiaEvidence { PotentialAmnesiaEvidence : & PotentialAmnesiaEvidence { VoteA : v2 , VoteB : v } ,
Polc : NewEmptyPOLC ( ) } , false , false } ,
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . testName , func ( t * testing . T ) {
pb , err := EvidenceToProto ( tt . evidence )
if tt . wantErr {
if tt . toProto Err {
assert . Error ( t , err , tt . testName )
return
}
assert . NoError ( t , err , tt . testName )
evi , err := EvidenceFromProto ( pb )
if tt . wantErr2 {
if tt . fromProtoErr {
assert . Error ( t , err , tt . testName )
return
}
@ -709,29 +729,31 @@ func TestProofOfLockChangeProtoBuf(t *testing.T) {
v2 := makeVote ( t , val2 , chainID , math . MaxInt32 , math . MaxInt64 , 1 , 0x01 , blockID , defaultVoteTime )
testCases := [ ] struct {
msg string
polc ProofOfLockChange
expErr bool
expErr2 bool
msg string
polc * ProofOfLockChange
toProtoErr bool
fromProtoErr bool
} {
{ "failure, empty key" , ProofOfLockChange { Votes : [ ] Vote { * v , * v2 } } , true , tru e} ,
{ "failure, empty votes" , ProofOfLockChange { PubKey : val3 . PrivKey . PubKey ( ) } , true , tru e} ,
{ "success empty ProofOfLockChange" , EmptyPOLC ( ) , false , false } ,
{ "success" , ProofOfLockChange { Votes : [ ] Vote { * v , * v2 } , PubKey : val3 . PrivKey . PubKey ( ) } , false , false } ,
{ "failure, empty key" , & ProofOfLockChange { Votes : [ ] * Vote { v , v2 } , PubKey : nil } , true , fals e} ,
{ "failure, empty votes" , & ProofOfLockChange { PubKey : val3 . PrivKey . PubKey ( ) } , true , fals e} ,
{ "success empty ProofOfLockChange" , New EmptyPOLC( ) , false , false } ,
{ "success" , & ProofOfLockChange { Votes : [ ] * Vote { v , v2 } , PubKey : val3 . PrivKey . PubKey ( ) } , false , false } ,
}
for _ , tc := range testCases {
tc := tc
pbpolc , err := tc . polc . ToProto ( )
if tc . exp Err {
if tc . toProto Err {
assert . Error ( t , err , tc . msg )
} else {
assert . NoError ( t , err , tc . msg )
}
c , err := ProofOfLockChangeFromProto ( pbpolc )
if ! tc . expErr2 {
if ! tc . fromProtoErr {
assert . NoError ( t , err , tc . msg )
assert . Equal ( t , & tc . polc , c , tc . msg )
if ! tc . toProtoErr {
assert . Equal ( t , tc . polc , c , tc . msg )
}
} else {
assert . Error ( t , err , tc . msg )
}