mirror of
https://github.com/tendermint/tendermint.git
synced 2026-05-02 13:25:45 +00:00
fix validator set proposer priorities in light client provider (#5307)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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+),
|
||||
|
||||
@@ -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{
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user