diff --git a/CHANGELOG.md b/CHANGELOG.md index 07165ada9..5b1cd54e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ BREAKING CHANGES: - Introduce EventDataInner for serializing events - remove all use of go-wire around user interfaces - rpc responses no longer have type information :) +- [types] Do not include the `Accum` field when computing the hash of a validator. This makes the ValidatorSetHash unique for a given validator set, rather than changing with every block (as the Accum changes) FEATURES: diff --git a/types/validator.go b/types/validator.go index 595c52ff1..0c782321e 100644 --- a/types/validator.go +++ b/types/validator.go @@ -12,13 +12,14 @@ import ( ) // Volatile state for each Validator -// TODO: make non-volatile identity -// - Remove Accum - it can be computed, and now valset becomes identifying +// NOTE: The Accum is not included in Validator.Hash(); +// make sure to update that method if changes are made here type Validator struct { Address data.Bytes `json:"address"` PubKey crypto.PubKey `json:"pub_key"` VotingPower int64 `json:"voting_power"` - Accum int64 `json:"accum"` + + Accum int64 `json:"accum"` } func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { @@ -69,8 +70,18 @@ func (v *Validator) String() string { v.Accum) } +// Hash computes the unique ID of a validator with a given voting power. +// It exludes the Accum value, which changes with every round. func (v *Validator) Hash() []byte { - return wire.BinaryRipemd160(v) + return wire.BinaryRipemd160(struct { + Address data.Bytes + PubKey crypto.PubKey + VotingPower int64 + }{ + v.Address, + v.PubKey, + v.VotingPower, + }) } //------------------------------------- diff --git a/types/validator_set.go b/types/validator_set.go index 214e073d0..b374df576 100644 --- a/types/validator_set.go +++ b/types/validator_set.go @@ -21,7 +21,6 @@ import ( // NOTE: Not goroutine-safe. // NOTE: All get/set to validators should copy the value for safety. // TODO: consider validator Accum overflow -// TODO: move valset into an iavl tree where key is 'blockbonded|pubkey' type ValidatorSet struct { // NOTE: persisted via reflect, must be exported. Validators []*Validator `json:"validators"` diff --git a/types/vote_set_test.go b/types/vote_set_test.go index 6ef075927..84e13ac17 100644 --- a/types/vote_set_test.go +++ b/types/vote_set_test.go @@ -11,7 +11,6 @@ import ( ) // NOTE: privValidators are in order -// TODO: Move it out? func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *ValidatorSet, []*PrivValidator) { valSet, privValidators := RandValidatorSet(numValidators, votingPower) return NewVoteSet("test_chain_id", height, round, type_, valSet), valSet, privValidators