Browse Source

types: create ValidateBasic() funcs for validator and validator set (#4905)

pull/4911/head
Callum Waters 5 years ago
committed by GitHub
parent
commit
8cd3dec102
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 158 additions and 1 deletions
  1. +2
    -1
      CHANGELOG_PENDING.md
  2. +19
    -0
      types/validator.go
  3. +18
    -0
      types/validator_set.go
  4. +58
    -0
      types/validator_set_test.go
  5. +61
    -0
      types/validator_test.go

+ 2
- 1
CHANGELOG_PENDING.md View File

@ -75,7 +75,8 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
- [p2p/conn] \#4795 Return err on `signChallenge()` instead of panic - [p2p/conn] \#4795 Return err on `signChallenge()` instead of panic
- [evidence] [\#4839](https://github.com/tendermint/tendermint/pull/4839) Reject duplicate evidence from being proposed (@cmwaters) - [evidence] [\#4839](https://github.com/tendermint/tendermint/pull/4839) Reject duplicate evidence from being proposed (@cmwaters)
- [rpc/core] [\#4844](https://github.com/tendermint/tendermint/pull/4844) Do not lock consensus state in `/validators`, `/consensus_params` and `/status` (@melekes) - [rpc/core] [\#4844](https://github.com/tendermint/tendermint/pull/4844) Do not lock consensus state in `/validators`, `/consensus_params` and `/status` (@melekes)
- [evidence] [\#4892](https://github.com/tendermint/tendermint/pull/4892) Remove redundant header from phantom validator evidence @cmwaters
- [evidence] [\#4892](https://github.com/tendermint/tendermint/pull/4892) Remove redundant header from phantom validator evidence (@cmwaters)
- [types] [\#4905](https://github.com/tendermint/tendermint/pull/4905) Add ValidateBasic to validator and validator set (@cmwaters)
### BUG FIXES: ### BUG FIXES:


+ 19
- 0
types/validator.go View File

@ -32,6 +32,25 @@ func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator {
} }
} }
func (v *Validator) ValidateBasic() error {
if v == nil {
return errors.New("nil validator")
}
if v.PubKey == nil {
return errors.New("validator does not have a public key")
}
if v.VotingPower < 0 {
return errors.New("validator has negative voting power")
}
if len(v.Address) != crypto.AddressSize {
return fmt.Errorf("validator address is the wrong size: %v", v.Address)
}
return nil
}
// Creates a new copy of the validator so we can mutate ProposerPriority. // Creates a new copy of the validator so we can mutate ProposerPriority.
// Panics if the validator is nil. // Panics if the validator is nil.
func (v *Validator) Copy() *Validator { func (v *Validator) Copy() *Validator {


+ 18
- 0
types/validator_set.go View File

@ -79,6 +79,24 @@ func NewValidatorSet(valz []*Validator) *ValidatorSet {
return vals return vals
} }
func (vals *ValidatorSet) ValidateBasic() error {
if vals.IsNilOrEmpty() {
return errors.New("validator set is nil or empty")
}
for idx, val := range vals.Validators {
if err := val.ValidateBasic(); err != nil {
return fmt.Errorf("invalid validator #%d: %w", idx, err)
}
}
if err := vals.Proposer.ValidateBasic(); err != nil {
return fmt.Errorf("proposer failed validate basic, error: %w", err)
}
return nil
}
// IsNilOrEmpty returns true if validator set is nil or empty. // IsNilOrEmpty returns true if validator set is nil or empty.
func (vals *ValidatorSet) IsNilOrEmpty() bool { func (vals *ValidatorSet) IsNilOrEmpty() bool {
return vals == nil || len(vals.Validators) == 0 return vals == nil || len(vals.Validators) == 0


+ 58
- 0
types/validator_set_test.go View File

@ -77,6 +77,64 @@ func TestValidatorSetBasic(t *testing.T) {
} }
func TestValidatorSetValidateBasic(t *testing.T) {
val, _ := RandValidator(false, 1)
badVal := &Validator{}
testCases := []struct {
vals ValidatorSet
err bool
msg string
}{
{
vals: ValidatorSet{},
err: true,
msg: "validator set is nil or empty",
},
{
vals: ValidatorSet{
Validators: []*Validator{},
},
err: true,
msg: "validator set is nil or empty",
},
{
vals: ValidatorSet{
Validators: []*Validator{val},
},
err: true,
msg: "proposer failed validate basic, error: nil validator",
},
{
vals: ValidatorSet{
Validators: []*Validator{badVal},
},
err: true,
msg: "invalid validator #0: validator does not have a public key",
},
{
vals: ValidatorSet{
Validators: []*Validator{val},
Proposer: val,
},
err: false,
msg: "",
},
}
for _, tc := range testCases {
err := tc.vals.ValidateBasic()
if tc.err {
if assert.Error(t, err) {
assert.Equal(t, tc.msg, err.Error())
}
} else {
assert.NoError(t, err)
}
}
}
func TestCopy(t *testing.T) { func TestCopy(t *testing.T) {
vset := randValidatorSet(10) vset := randValidatorSet(10)
vsetHash := vset.Hash() vsetHash := vset.Hash()


+ 61
- 0
types/validator_test.go View File

@ -3,6 +3,7 @@ package types
import ( import (
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -36,3 +37,63 @@ func TestValidatorProtoBuf(t *testing.T) {
} }
} }
} }
func TestValidatorValidateBasic(t *testing.T) {
priv := NewMockPV()
pubKey, _ := priv.GetPubKey()
testCases := []struct {
val *Validator
err bool
msg string
}{
{
val: NewValidator(pubKey, 1),
err: false,
msg: "",
},
{
val: nil,
err: true,
msg: "nil validator",
},
{
val: &Validator{
PubKey: nil,
},
err: true,
msg: "validator does not have a public key",
},
{
val: NewValidator(pubKey, -1),
err: true,
msg: "validator has negative voting power",
},
{
val: &Validator{
PubKey: pubKey,
Address: nil,
},
err: true,
msg: "validator address is the wrong size: ",
},
{
val: &Validator{
PubKey: pubKey,
Address: []byte{'a'},
},
err: true,
msg: "validator address is the wrong size: 61",
},
}
for _, tc := range testCases {
err := tc.val.ValidateBasic()
if tc.err {
if assert.Error(t, err) {
assert.Equal(t, tc.msg, err.Error())
}
} else {
assert.NoError(t, err)
}
}
}

Loading…
Cancel
Save