Browse Source

test: add evidence hash testvectors (#6536)

## Description

Trying to debug a possible hashing issue, writing test vectors on 0.34 and then porting them to master to double-check it's not a hashing issue.
callum/config
Marko 4 years ago
committed by GitHub
parent
commit
39ddfc24f4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 131 additions and 16 deletions
  1. +79
    -16
      types/evidence_test.go
  2. +24
    -0
      types/validator_set_test.go
  3. +18
    -0
      types/validator_test.go
  4. +10
    -0
      types/vote_set_test.go

+ 79
- 16
types/evidence_test.go View File

@ -2,6 +2,7 @@ package types
import (
"context"
"encoding/hex"
"math"
mrand "math/rand"
"testing"
@ -11,6 +12,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/tmhash"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
@ -281,22 +283,6 @@ func TestEvidenceProto(t *testing.T) {
v := makeVote(t, val, chainID, math.MaxInt32, math.MaxInt64, 1, 0x01, blockID, defaultVoteTime)
v2 := makeVote(t, val, chainID, math.MaxInt32, math.MaxInt64, 2, 0x01, blockID2, defaultVoteTime)
// -------- SignedHeaders --------
const height int64 = 37
var (
header1 = makeHeaderRandom()
header2 = makeHeaderRandom()
)
header1.Height = height
header1.LastBlockID = blockID
header1.ChainID = chainID
header2.Height = height
header2.LastBlockID = blockID
header2.ChainID = chainID
tests := []struct {
testName string
evidence Evidence
@ -328,3 +314,80 @@ func TestEvidenceProto(t *testing.T) {
})
}
}
func TestEvidenceVectors(t *testing.T) {
// Votes for duplicateEvidence
val := NewMockPV()
val.PrivKey = ed25519.GenPrivKeyFromSecret([]byte("it's a secret")) // deterministic key
blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
blockID2 := makeBlockID(tmhash.Sum([]byte("blockhash2")), math.MaxInt32, tmhash.Sum([]byte("partshash")))
const chainID = "mychain"
v := makeVote(t, val, chainID, math.MaxInt32, math.MaxInt64, 1, 0x01, blockID, defaultVoteTime)
v2 := makeVote(t, val, chainID, math.MaxInt32, math.MaxInt64, 2, 0x01, blockID2, defaultVoteTime)
// Data for LightClientAttackEvidence
height := int64(5)
commonHeight := height - 1
nValidators := 10
voteSet, valSet, privVals := deterministicVoteSet(height, 1, tmproto.PrecommitType, 1)
header := &Header{
Version: version.Consensus{Block: 1, App: 1},
ChainID: chainID,
Height: height,
Time: time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC),
LastBlockID: BlockID{},
LastCommitHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"),
DataHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"),
ValidatorsHash: valSet.Hash(),
NextValidatorsHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"),
ConsensusHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"),
AppHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"),
LastResultsHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"),
EvidenceHash: []byte("f2564c78071e26643ae9b3e2a19fa0dc10d4d9e873aa0be808660123f11a1e78"),
ProposerAddress: []byte("2915b7b15f979e48ebc61774bb1d86ba3136b7eb"),
}
blockID3 := makeBlockID(header.Hash(), math.MaxInt32, tmhash.Sum([]byte("partshash")))
commit, err := makeCommit(blockID3, height, 1, voteSet, privVals, defaultVoteTime)
require.NoError(t, err)
lcae := &LightClientAttackEvidence{
ConflictingBlock: &LightBlock{
SignedHeader: &SignedHeader{
Header: header,
Commit: commit,
},
ValidatorSet: valSet,
},
CommonHeight: commonHeight,
TotalVotingPower: valSet.TotalVotingPower(),
Timestamp: header.Time,
ByzantineValidators: valSet.Validators[:nValidators/2],
}
// assert.NoError(t, lcae.ValidateBasic())
testCases := []struct {
testName string
evList EvidenceList
expBytes string
}{
{"duplicateVoteEvidence",
EvidenceList{&DuplicateVoteEvidence{VoteA: v2, VoteB: v}},
"a9ce28d13bb31001fc3e5b7927051baf98f86abdbd64377643a304164c826923",
},
{"LightClientAttackEvidence",
EvidenceList{lcae},
"2f8782163c3905b26e65823ababc977fe54e97b94e60c0360b1e4726b668bb8e",
},
{"LightClientAttackEvidence & DuplicateVoteEvidence",
EvidenceList{&DuplicateVoteEvidence{VoteA: v2, VoteB: v}, lcae},
"eedb4b47d6dbc9d43f53da8aa50bb826e8d9fc7d897da777c8af6a04aa74163e",
},
}
for _, tc := range testCases {
tc := tc
hash := tc.evList.Hash()
require.Equal(t, tc.expBytes, hex.EncodeToString(hash), tc.testName)
}
}

+ 24
- 0
types/validator_set_test.go View File

@ -1592,3 +1592,27 @@ func BenchmarkValidatorSet_VerifyCommitLightTrusting_Ed25519(b *testing.B) {
})
}
}
// Testing Utils
// deterministicValidatorSet returns a deterministic validator set (size: +numValidators+),
// where each validator has a power of 50
//
// EXPOSED FOR TESTING.
func deterministicValidatorSet() (*ValidatorSet, []PrivValidator) {
var (
valz = make([]*Validator, 10)
privValidators = make([]PrivValidator, 10)
)
for i := 0; i < 10; i++ {
// val, privValidator := DeterministicValidator(ed25519.PrivKey([]byte(deterministicKeys[i])))
val, privValidator := deterministicValidator(ed25519.GenPrivKeyFromSecret([]byte(fmt.Sprintf("key: %x", i))))
valz[i] = val
privValidators[i] = privValidator
}
sort.Sort(PrivValidatorsByAddress(privValidators))
return NewValidatorSet(valz), privValidators
}

+ 18
- 0
types/validator_test.go View File

@ -2,10 +2,12 @@ package types
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
)
func TestValidatorProtoBuf(t *testing.T) {
@ -98,3 +100,19 @@ func TestValidatorValidateBasic(t *testing.T) {
}
}
}
// Testing util functions
// deterministicValidator returns a deterministic validator, useful for testing.
// UNSTABLE
func deterministicValidator(key crypto.PrivKey) (*Validator, PrivValidator) {
privVal := NewMockPV()
privVal.PrivKey = key
var votePower int64 = 50
pubKey, err := privVal.GetPubKey(context.TODO())
if err != nil {
panic(fmt.Errorf("could not retrieve pubkey %w", err))
}
val := NewValidator(pubKey, votePower)
return val, privVal
}

+ 10
- 0
types/vote_set_test.go View File

@ -488,6 +488,16 @@ func randVoteSet(
return NewVoteSet("test_chain_id", height, round, signedMsgType, valSet), valSet, privValidators
}
func deterministicVoteSet(
height int64,
round int32,
signedMsgType tmproto.SignedMsgType,
votingPower int64,
) (*VoteSet, *ValidatorSet, []PrivValidator) {
valSet, privValidators := deterministicValidatorSet()
return NewVoteSet("test_chain_id", height, round, signedMsgType, valSet), valSet, privValidators
}
func randValidatorPrivValSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) {
var (
valz = make([]*Validator, numValidators)


Loading…
Cancel
Save