tendermint/types/vote_test.go
Ismail Khoffi fc073746a0 privval: Switch to amino encoding in SignBytes (#2459)
* switch to amino for SignBytes and add Reply with error message

- currently only Vote is done

* switch Reply type in socket for other messages

 - add error description on error

* add TODOs regarding error handling

* address comments from peer review session (thx @xla)

 - contains all changes besides the test-coverage / error'ing branches

* increase test coverage:

 - add tests for each newly introduced error'ing code path

* return error if received wrong response

* add test for wrong response branches (ErrUnexpectedResponse)

* update CHANGELOG_PENDING and related documentation (spec)

* fix typo: s/CanonicallockID/CanonicalBlockID

* fixes from review
2018-09-28 19:57:29 -04:00

150 lines
3.6 KiB
Go

package types
import (
"math"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
tmtime "github.com/tendermint/tendermint/types/time"
)
func examplePrevote() *Vote {
return exampleVote(VoteTypePrevote)
}
func examplePrecommit() *Vote {
return exampleVote(VoteTypePrecommit)
}
func exampleVote(t byte) *Vote {
var stamp, err = time.Parse(TimeFormat, "2017-12-25T03:00:01.234Z")
if err != nil {
panic(err)
}
return &Vote{
ValidatorAddress: tmhash.Sum([]byte("validator_address")),
ValidatorIndex: 56789,
Height: 12345,
Round: 2,
Timestamp: stamp,
Type: t,
BlockID: BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
PartsHeader: PartSetHeader{
Total: 1000000,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
},
},
}
}
func TestVoteSignable(t *testing.T) {
vote := examplePrecommit()
signBytes := vote.SignBytes("test_chain_id")
expected, err := cdc.MarshalBinary(CanonicalizeVote("test_chain_id", vote))
require.NoError(t, err)
require.Equal(t, expected, signBytes, "Got unexpected sign bytes for Vote.")
}
func TestVoteVerifySignature(t *testing.T) {
privVal := NewMockPV()
pubkey := privVal.GetPubKey()
vote := examplePrecommit()
signBytes := vote.SignBytes("test_chain_id")
// sign it
err := privVal.SignVote("test_chain_id", vote)
require.NoError(t, err)
// verify the same vote
valid := pubkey.VerifyBytes(vote.SignBytes("test_chain_id"), vote.Signature)
require.True(t, valid)
// serialize, deserialize and verify again....
precommit := new(Vote)
bs, err := cdc.MarshalBinary(vote)
require.NoError(t, err)
err = cdc.UnmarshalBinary(bs, &precommit)
require.NoError(t, err)
// verify the transmitted vote
newSignBytes := precommit.SignBytes("test_chain_id")
require.Equal(t, string(signBytes), string(newSignBytes))
valid = pubkey.VerifyBytes(newSignBytes, precommit.Signature)
require.True(t, valid)
}
func TestIsVoteTypeValid(t *testing.T) {
tc := []struct {
name string
in byte
out bool
}{
{"Prevote", VoteTypePrevote, true},
{"Precommit", VoteTypePrecommit, true},
{"InvalidType", byte(3), false},
}
for _, tt := range tc {
tt := tt
t.Run(tt.name, func(st *testing.T) {
if rs := IsVoteTypeValid(tt.in); rs != tt.out {
t.Errorf("Got unexpected Vote type. Expected:\n%v\nGot:\n%v", rs, tt.out)
}
})
}
}
func TestVoteVerify(t *testing.T) {
privVal := NewMockPV()
pubkey := privVal.GetPubKey()
vote := examplePrevote()
vote.ValidatorAddress = pubkey.Address()
err := vote.Verify("test_chain_id", ed25519.GenPrivKey().PubKey())
if assert.Error(t, err) {
assert.Equal(t, ErrVoteInvalidValidatorAddress, err)
}
err = vote.Verify("test_chain_id", pubkey)
if assert.Error(t, err) {
assert.Equal(t, ErrVoteInvalidSignature, err)
}
}
func TestMaxVoteBytes(t *testing.T) {
vote := &Vote{
ValidatorAddress: tmhash.Sum([]byte("validator_address")),
ValidatorIndex: math.MaxInt64,
Height: math.MaxInt64,
Round: math.MaxInt64,
Timestamp: tmtime.Now(),
Type: VoteTypePrevote,
BlockID: BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
PartsHeader: PartSetHeader{
Total: math.MaxInt64,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
},
},
}
privVal := NewMockPV()
err := privVal.SignVote("test_chain_id", vote)
require.NoError(t, err)
bz, err := cdc.MarshalBinary(vote)
require.NoError(t, err)
assert.EqualValues(t, MaxVoteBytes, len(bz))
}