Browse Source

fix validator set proposer priorities in light client provider (#5307)

pull/5314/head
Callum Waters 4 years ago
committed by GitHub
parent
commit
86707862d4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 1 deletions
  1. +2
    -0
      CHANGELOG_PENDING.md
  2. +1
    -1
      light/provider/http/http.go
  3. +33
    -0
      types/validator_set.go
  4. +18
    -0
      types/validator_set_test.go

+ 2
- 0
CHANGELOG_PENDING.md View File

@ -22,3 +22,5 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
- [blockchain] \#5249 Fix fast sync halt with initial height > 1 (@erikgrinaker)
- [statesync] \#5302 Fix genesis state propagation to state sync routine (@erikgrinaker)
- [light] [\#5307](https://github.com/tendermint/tendermint/pull/5307) persist correct proposer priority in light client validator sets (@cmwaters)

+ 1
- 1
light/provider/http/http.go View File

@ -119,7 +119,7 @@ func (p *http) ValidatorSet(height int64) (*types.ValidatorSet, error) {
page++
}
return types.NewValidatorSet(vals), nil
return types.ValidatorSetFromExistingValidators(vals)
}
// ReportEvidence calls `/broadcast_evidence` endpoint.


+ 33
- 0
types/validator_set.go View File

@ -822,6 +822,24 @@ func (vals *ValidatorSet) VerifyCommitLightTrusting(chainID string, commit *Comm
return ErrNotEnoughVotingPowerSigned{Got: talliedVotingPower, Needed: votingPowerNeeded}
}
// findPreviousProposer reverses the compare proposer priority function to find the validator
// with the lowest proposer priority which would have been the previous proposer.
//
// Is used when recreating a validator set from an existing array of validators.
func (vals *ValidatorSet) findPreviousProposer() *Validator {
var previousProposer *Validator
for _, val := range vals.Validators {
if previousProposer == nil {
previousProposer = val
continue
}
if previousProposer == previousProposer.CompareProposerPriority(val) {
previousProposer = val
}
}
return previousProposer
}
//-----------------
// IsErrNotEnoughVotingPowerSigned returns true if err is
@ -966,6 +984,21 @@ func ValidatorSetFromProto(vp *tmproto.ValidatorSet) (*ValidatorSet, error) {
return vals, vals.ValidateBasic()
}
// ValidatorSetFromExistingValidators takes an existing array of validators and rebuilds
// the exact same validator set that corresponds to it without changing the proposer priority or power
func ValidatorSetFromExistingValidators(valz []*Validator) (*ValidatorSet, error) {
if len(valz) == 0 {
return nil, errors.New("no validators given")
}
vals := &ValidatorSet{
Validators: valz,
}
vals.Proposer = vals.findPreviousProposer()
vals.updateTotalVotingPower()
sort.Sort(ValidatorsByVotingPower(vals.Validators))
return vals, nil
}
//----------------------------------------
// RandValidatorSet returns a randomized validator set (size: +numValidators+),


+ 18
- 0
types/validator_set_test.go View File

@ -1425,6 +1425,24 @@ func verifyValSetUpdatePriorityOrder(t *testing.T, valSet *ValidatorSet, cfg tes
}
}
func TestNewValidatorSetFromExistingValidators(t *testing.T) {
size := 5
vals := make([]*Validator, size)
for i := 0; i < size; i++ {
pv := NewMockPV()
vals[i] = pv.ExtractIntoValidator(int64(i + 1))
}
valSet := NewValidatorSet(vals)
valSet.IncrementProposerPriority(5)
newValSet := NewValidatorSet(valSet.Validators)
existingValSet, err := ValidatorSetFromExistingValidators(valSet.Validators)
require.NoError(t, err)
assert.NotEqual(t, valSet, newValSet)
assert.Equal(t, valSet, existingValSet)
assert.Equal(t, valSet.CopyIncrementProposerPriority(3), existingValSet.CopyIncrementProposerPriority(3))
}
func TestValSetUpdateOverflowRelated(t *testing.T) {
testCases := []testVSetCfg{
{


Loading…
Cancel
Save