github.com/vipernet-xyz/tm@v0.34.24/types/validator_set.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"math"
     8  	"math/big"
     9  	"sort"
    10  	"strings"
    11  
    12  	"github.com/vipernet-xyz/tm/crypto/merkle"
    13  	tmmath "github.com/vipernet-xyz/tm/libs/math"
    14  	tmproto "github.com/vipernet-xyz/tm/proto/tendermint/types"
    15  )
    16  
    17  const (
    18  	// MaxTotalVotingPower - the maximum allowed total voting power.
    19  	// It needs to be sufficiently small to, in all cases:
    20  	// 1. prevent clipping in incrementProposerPriority()
    21  	// 2. let (diff+diffMax-1) not overflow in IncrementProposerPriority()
    22  	// (Proof of 1 is tricky, left to the reader).
    23  	// It could be higher, but this is sufficiently large for our purposes,
    24  	// and leaves room for defensive purposes.
    25  	MaxTotalVotingPower = int64(math.MaxInt64) / 8
    26  
    27  	// PriorityWindowSizeFactor - is a constant that when multiplied with the
    28  	// total voting power gives the maximum allowed distance between validator
    29  	// priorities.
    30  	PriorityWindowSizeFactor = 2
    31  )
    32  
    33  // ErrTotalVotingPowerOverflow is returned if the total voting power of the
    34  // resulting validator set exceeds MaxTotalVotingPower.
    35  var ErrTotalVotingPowerOverflow = fmt.Errorf("total voting power of resulting valset exceeds max %d",
    36  	MaxTotalVotingPower)
    37  
    38  // ValidatorSet represent a set of *Validator at a given height.
    39  //
    40  // The validators can be fetched by address or index.
    41  // The index is in order of .VotingPower, so the indices are fixed for all
    42  // rounds of a given blockchain height - ie. the validators are sorted by their
    43  // voting power (descending). Secondary index - .Address (ascending).
    44  //
    45  // On the other hand, the .ProposerPriority of each validator and the
    46  // designated .GetProposer() of a set changes every round, upon calling
    47  // .IncrementProposerPriority().
    48  //
    49  // NOTE: Not goroutine-safe.
    50  // NOTE: All get/set to validators should copy the value for safety.
    51  type ValidatorSet struct {
    52  	// NOTE: persisted via reflect, must be exported.
    53  	Validators []*Validator `json:"validators"`
    54  	Proposer   *Validator   `json:"proposer"`
    55  
    56  	// cached (unexported)
    57  	totalVotingPower int64
    58  }
    59  
    60  // NewValidatorSet initializes a ValidatorSet by copying over the values from
    61  // `valz`, a list of Validators. If valz is nil or empty, the new ValidatorSet
    62  // will have an empty list of Validators.
    63  //
    64  // The addresses of validators in `valz` must be unique otherwise the function
    65  // panics.
    66  //
    67  // Note the validator set size has an implied limit equal to that of the
    68  // MaxVotesCount - commits by a validator set larger than this will fail
    69  // validation.
    70  func NewValidatorSet(valz []*Validator) *ValidatorSet {
    71  	vals := &ValidatorSet{}
    72  	err := vals.updateWithChangeSet(valz, false)
    73  	if err != nil {
    74  		panic(fmt.Sprintf("Cannot create validator set: %v", err))
    75  	}
    76  	if len(valz) > 0 {
    77  		vals.IncrementProposerPriority(1)
    78  	}
    79  	return vals
    80  }
    81  
    82  func (vals *ValidatorSet) ValidateBasic() error {
    83  	if vals.IsNilOrEmpty() {
    84  		return errors.New("validator set is nil or empty")
    85  	}
    86  
    87  	for idx, val := range vals.Validators {
    88  		if err := val.ValidateBasic(); err != nil {
    89  			return fmt.Errorf("invalid validator #%d: %w", idx, err)
    90  		}
    91  	}
    92  
    93  	if err := vals.Proposer.ValidateBasic(); err != nil {
    94  		return fmt.Errorf("proposer failed validate basic, error: %w", err)
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  // IsNilOrEmpty returns true if validator set is nil or empty.
   101  func (vals *ValidatorSet) IsNilOrEmpty() bool {
   102  	return vals == nil || len(vals.Validators) == 0
   103  }
   104  
   105  // CopyIncrementProposerPriority increments ProposerPriority and updates the
   106  // proposer on a copy, and returns it.
   107  func (vals *ValidatorSet) CopyIncrementProposerPriority(times int32) *ValidatorSet {
   108  	copy := vals.Copy()
   109  	copy.IncrementProposerPriority(times)
   110  	return copy
   111  }
   112  
   113  // IncrementProposerPriority increments ProposerPriority of each validator and
   114  // updates the proposer. Panics if validator set is empty.
   115  // `times` must be positive.
   116  func (vals *ValidatorSet) IncrementProposerPriority(times int32) {
   117  	if vals.IsNilOrEmpty() {
   118  		panic("empty validator set")
   119  	}
   120  	if times <= 0 {
   121  		panic("Cannot call IncrementProposerPriority with non-positive times")
   122  	}
   123  
   124  	// Cap the difference between priorities to be proportional to 2*totalPower by
   125  	// re-normalizing priorities, i.e., rescale all priorities by multiplying with:
   126  	//  2*totalVotingPower/(maxPriority - minPriority)
   127  	diffMax := PriorityWindowSizeFactor * vals.TotalVotingPower()
   128  	vals.RescalePriorities(diffMax)
   129  	vals.shiftByAvgProposerPriority()
   130  
   131  	var proposer *Validator
   132  	// Call IncrementProposerPriority(1) times times.
   133  	for i := int32(0); i < times; i++ {
   134  		proposer = vals.incrementProposerPriority()
   135  	}
   136  
   137  	vals.Proposer = proposer
   138  }
   139  
   140  // RescalePriorities rescales the priorities such that the distance between the
   141  // maximum and minimum is smaller than `diffMax`. Panics if validator set is
   142  // empty.
   143  func (vals *ValidatorSet) RescalePriorities(diffMax int64) {
   144  	if vals.IsNilOrEmpty() {
   145  		panic("empty validator set")
   146  	}
   147  	// NOTE: This check is merely a sanity check which could be
   148  	// removed if all tests would init. voting power appropriately;
   149  	// i.e. diffMax should always be > 0
   150  	if diffMax <= 0 {
   151  		return
   152  	}
   153  
   154  	// Calculating ceil(diff/diffMax):
   155  	// Re-normalization is performed by dividing by an integer for simplicity.
   156  	// NOTE: This may make debugging priority issues easier as well.
   157  	diff := computeMaxMinPriorityDiff(vals)
   158  	ratio := (diff + diffMax - 1) / diffMax
   159  	if diff > diffMax {
   160  		for _, val := range vals.Validators {
   161  			val.ProposerPriority /= ratio
   162  		}
   163  	}
   164  }
   165  
   166  func (vals *ValidatorSet) incrementProposerPriority() *Validator {
   167  	for _, val := range vals.Validators {
   168  		// Check for overflow for sum.
   169  		newPrio := safeAddClip(val.ProposerPriority, val.VotingPower)
   170  		val.ProposerPriority = newPrio
   171  	}
   172  	// Decrement the validator with most ProposerPriority.
   173  	mostest := vals.getValWithMostPriority()
   174  	// Mind the underflow.
   175  	mostest.ProposerPriority = safeSubClip(mostest.ProposerPriority, vals.TotalVotingPower())
   176  
   177  	return mostest
   178  }
   179  
   180  // Should not be called on an empty validator set.
   181  func (vals *ValidatorSet) computeAvgProposerPriority() int64 {
   182  	n := int64(len(vals.Validators))
   183  	sum := big.NewInt(0)
   184  	for _, val := range vals.Validators {
   185  		sum.Add(sum, big.NewInt(val.ProposerPriority))
   186  	}
   187  	avg := sum.Div(sum, big.NewInt(n))
   188  	if avg.IsInt64() {
   189  		return avg.Int64()
   190  	}
   191  
   192  	// This should never happen: each val.ProposerPriority is in bounds of int64.
   193  	panic(fmt.Sprintf("Cannot represent avg ProposerPriority as an int64 %v", avg))
   194  }
   195  
   196  // Compute the difference between the max and min ProposerPriority of that set.
   197  func computeMaxMinPriorityDiff(vals *ValidatorSet) int64 {
   198  	if vals.IsNilOrEmpty() {
   199  		panic("empty validator set")
   200  	}
   201  	max := int64(math.MinInt64)
   202  	min := int64(math.MaxInt64)
   203  	for _, v := range vals.Validators {
   204  		if v.ProposerPriority < min {
   205  			min = v.ProposerPriority
   206  		}
   207  		if v.ProposerPriority > max {
   208  			max = v.ProposerPriority
   209  		}
   210  	}
   211  	diff := max - min
   212  	if diff < 0 {
   213  		return -1 * diff
   214  	}
   215  	return diff
   216  }
   217  
   218  func (vals *ValidatorSet) getValWithMostPriority() *Validator {
   219  	var res *Validator
   220  	for _, val := range vals.Validators {
   221  		res = res.CompareProposerPriority(val)
   222  	}
   223  	return res
   224  }
   225  
   226  func (vals *ValidatorSet) shiftByAvgProposerPriority() {
   227  	if vals.IsNilOrEmpty() {
   228  		panic("empty validator set")
   229  	}
   230  	avgProposerPriority := vals.computeAvgProposerPriority()
   231  	for _, val := range vals.Validators {
   232  		val.ProposerPriority = safeSubClip(val.ProposerPriority, avgProposerPriority)
   233  	}
   234  }
   235  
   236  // Makes a copy of the validator list.
   237  func validatorListCopy(valsList []*Validator) []*Validator {
   238  	if valsList == nil {
   239  		return nil
   240  	}
   241  	valsCopy := make([]*Validator, len(valsList))
   242  	for i, val := range valsList {
   243  		valsCopy[i] = val.Copy()
   244  	}
   245  	return valsCopy
   246  }
   247  
   248  // Copy each validator into a new ValidatorSet.
   249  func (vals *ValidatorSet) Copy() *ValidatorSet {
   250  	return &ValidatorSet{
   251  		Validators:       validatorListCopy(vals.Validators),
   252  		Proposer:         vals.Proposer,
   253  		totalVotingPower: vals.totalVotingPower,
   254  	}
   255  }
   256  
   257  // HasAddress returns true if address given is in the validator set, false -
   258  // otherwise.
   259  func (vals *ValidatorSet) HasAddress(address []byte) bool {
   260  	for _, val := range vals.Validators {
   261  		if bytes.Equal(val.Address, address) {
   262  			return true
   263  		}
   264  	}
   265  	return false
   266  }
   267  
   268  // GetByAddress returns an index of the validator with address and validator
   269  // itself (copy) if found. Otherwise, -1 and nil are returned.
   270  func (vals *ValidatorSet) GetByAddress(address []byte) (index int32, val *Validator) {
   271  	for idx, val := range vals.Validators {
   272  		if bytes.Equal(val.Address, address) {
   273  			return int32(idx), val.Copy()
   274  		}
   275  	}
   276  	return -1, nil
   277  }
   278  
   279  // GetByIndex returns the validator's address and validator itself (copy) by
   280  // index.
   281  // It returns nil values if index is less than 0 or greater or equal to
   282  // len(ValidatorSet.Validators).
   283  func (vals *ValidatorSet) GetByIndex(index int32) (address []byte, val *Validator) {
   284  	if index < 0 || int(index) >= len(vals.Validators) {
   285  		return nil, nil
   286  	}
   287  	val = vals.Validators[index]
   288  	return val.Address, val.Copy()
   289  }
   290  
   291  // Size returns the length of the validator set.
   292  func (vals *ValidatorSet) Size() int {
   293  	return len(vals.Validators)
   294  }
   295  
   296  // Forces recalculation of the set's total voting power.
   297  // Panics if total voting power is bigger than MaxTotalVotingPower.
   298  func (vals *ValidatorSet) updateTotalVotingPower() {
   299  	sum := int64(0)
   300  	for _, val := range vals.Validators {
   301  		// mind overflow
   302  		sum = safeAddClip(sum, val.VotingPower)
   303  		if sum > MaxTotalVotingPower {
   304  			panic(fmt.Sprintf(
   305  				"Total voting power should be guarded to not exceed %v; got: %v",
   306  				MaxTotalVotingPower,
   307  				sum))
   308  		}
   309  	}
   310  
   311  	vals.totalVotingPower = sum
   312  }
   313  
   314  // TotalVotingPower returns the sum of the voting powers of all validators.
   315  // It recomputes the total voting power if required.
   316  func (vals *ValidatorSet) TotalVotingPower() int64 {
   317  	if vals.totalVotingPower == 0 {
   318  		vals.updateTotalVotingPower()
   319  	}
   320  	return vals.totalVotingPower
   321  }
   322  
   323  // GetProposer returns the current proposer. If the validator set is empty, nil
   324  // is returned.
   325  func (vals *ValidatorSet) GetProposer() (proposer *Validator) {
   326  	if len(vals.Validators) == 0 {
   327  		return nil
   328  	}
   329  	if vals.Proposer == nil {
   330  		vals.Proposer = vals.findProposer()
   331  	}
   332  	return vals.Proposer.Copy()
   333  }
   334  
   335  func (vals *ValidatorSet) findProposer() *Validator {
   336  	var proposer *Validator
   337  	for _, val := range vals.Validators {
   338  		if proposer == nil || !bytes.Equal(val.Address, proposer.Address) {
   339  			proposer = proposer.CompareProposerPriority(val)
   340  		}
   341  	}
   342  	return proposer
   343  }
   344  
   345  // Hash returns the Merkle root hash build using validators (as leaves) in the
   346  // set.
   347  func (vals *ValidatorSet) Hash() []byte {
   348  	bzs := make([][]byte, len(vals.Validators))
   349  	for i, val := range vals.Validators {
   350  		bzs[i] = val.Bytes()
   351  	}
   352  	return merkle.HashFromByteSlices(bzs)
   353  }
   354  
   355  // Iterate will run the given function over the set.
   356  func (vals *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) {
   357  	for i, val := range vals.Validators {
   358  		stop := fn(i, val.Copy())
   359  		if stop {
   360  			break
   361  		}
   362  	}
   363  }
   364  
   365  // Checks changes against duplicates, splits the changes in updates and
   366  // removals, sorts them by address.
   367  //
   368  // Returns:
   369  // updates, removals - the sorted lists of updates and removals
   370  // err - non-nil if duplicate entries or entries with negative voting power are seen
   371  //
   372  // No changes are made to 'origChanges'.
   373  func processChanges(origChanges []*Validator) (updates, removals []*Validator, err error) {
   374  	// Make a deep copy of the changes and sort by address.
   375  	changes := validatorListCopy(origChanges)
   376  	sort.Sort(ValidatorsByAddress(changes))
   377  
   378  	removals = make([]*Validator, 0, len(changes))
   379  	updates = make([]*Validator, 0, len(changes))
   380  	var prevAddr Address
   381  
   382  	// Scan changes by address and append valid validators to updates or removals lists.
   383  	for _, valUpdate := range changes {
   384  		if bytes.Equal(valUpdate.Address, prevAddr) {
   385  			err = fmt.Errorf("duplicate entry %v in %v", valUpdate, changes)
   386  			return nil, nil, err
   387  		}
   388  
   389  		switch {
   390  		case valUpdate.VotingPower < 0:
   391  			err = fmt.Errorf("voting power can't be negative: %d", valUpdate.VotingPower)
   392  			return nil, nil, err
   393  		case valUpdate.VotingPower > MaxTotalVotingPower:
   394  			err = fmt.Errorf("to prevent clipping/overflow, voting power can't be higher than %d, got %d",
   395  				MaxTotalVotingPower, valUpdate.VotingPower)
   396  			return nil, nil, err
   397  		case valUpdate.VotingPower == 0:
   398  			removals = append(removals, valUpdate)
   399  		default:
   400  			updates = append(updates, valUpdate)
   401  		}
   402  
   403  		prevAddr = valUpdate.Address
   404  	}
   405  
   406  	return updates, removals, err
   407  }
   408  
   409  // verifyUpdates verifies a list of updates against a validator set, making sure the allowed
   410  // total voting power would not be exceeded if these updates would be applied to the set.
   411  //
   412  // Inputs:
   413  // updates - a list of proper validator changes, i.e. they have been verified by processChanges for duplicates
   414  //
   415  //	and invalid values.
   416  //
   417  // vals - the original validator set. Note that vals is NOT modified by this function.
   418  // removedPower - the total voting power that will be removed after the updates are verified and applied.
   419  //
   420  // Returns:
   421  // tvpAfterUpdatesBeforeRemovals -  the new total voting power if these updates would be applied without the removals.
   422  //
   423  //	Note that this will be < 2 * MaxTotalVotingPower in case high power validators are removed and
   424  //	validators are added/ updated with high power values.
   425  //
   426  // err - non-nil if the maximum allowed total voting power would be exceeded
   427  func verifyUpdates(
   428  	updates []*Validator,
   429  	vals *ValidatorSet,
   430  	removedPower int64,
   431  ) (tvpAfterUpdatesBeforeRemovals int64, err error) {
   432  
   433  	delta := func(update *Validator, vals *ValidatorSet) int64 {
   434  		_, val := vals.GetByAddress(update.Address)
   435  		if val != nil {
   436  			return update.VotingPower - val.VotingPower
   437  		}
   438  		return update.VotingPower
   439  	}
   440  
   441  	updatesCopy := validatorListCopy(updates)
   442  	sort.Slice(updatesCopy, func(i, j int) bool {
   443  		return delta(updatesCopy[i], vals) < delta(updatesCopy[j], vals)
   444  	})
   445  
   446  	tvpAfterRemovals := vals.TotalVotingPower() - removedPower
   447  	for _, upd := range updatesCopy {
   448  		tvpAfterRemovals += delta(upd, vals)
   449  		if tvpAfterRemovals > MaxTotalVotingPower {
   450  			return 0, ErrTotalVotingPowerOverflow
   451  		}
   452  	}
   453  	return tvpAfterRemovals + removedPower, nil
   454  }
   455  
   456  func numNewValidators(updates []*Validator, vals *ValidatorSet) int {
   457  	numNewValidators := 0
   458  	for _, valUpdate := range updates {
   459  		if !vals.HasAddress(valUpdate.Address) {
   460  			numNewValidators++
   461  		}
   462  	}
   463  	return numNewValidators
   464  }
   465  
   466  // computeNewPriorities computes the proposer priority for the validators not present in the set based on
   467  // 'updatedTotalVotingPower'.
   468  // Leaves unchanged the priorities of validators that are changed.
   469  //
   470  // 'updates' parameter must be a list of unique validators to be added or updated.
   471  //
   472  // 'updatedTotalVotingPower' is the total voting power of a set where all updates would be applied but
   473  //
   474  //	not the removals. It must be < 2*MaxTotalVotingPower and may be close to this limit if close to
   475  //	MaxTotalVotingPower will be removed. This is still safe from overflow since MaxTotalVotingPower is maxInt64/8.
   476  //
   477  // No changes are made to the validator set 'vals'.
   478  func computeNewPriorities(updates []*Validator, vals *ValidatorSet, updatedTotalVotingPower int64) {
   479  	for _, valUpdate := range updates {
   480  		address := valUpdate.Address
   481  		_, val := vals.GetByAddress(address)
   482  		if val == nil {
   483  			// add val
   484  			// Set ProposerPriority to -C*totalVotingPower (with C ~= 1.125) to make sure validators can't
   485  			// un-bond and then re-bond to reset their (potentially previously negative) ProposerPriority to zero.
   486  			//
   487  			// Contract: updatedVotingPower < 2 * MaxTotalVotingPower to ensure ProposerPriority does
   488  			// not exceed the bounds of int64.
   489  			//
   490  			// Compute ProposerPriority = -1.125*totalVotingPower == -(updatedVotingPower + (updatedVotingPower >> 3)).
   491  			valUpdate.ProposerPriority = -(updatedTotalVotingPower + (updatedTotalVotingPower >> 3))
   492  		} else {
   493  			valUpdate.ProposerPriority = val.ProposerPriority
   494  		}
   495  	}
   496  
   497  }
   498  
   499  // Merges the vals' validator list with the updates list.
   500  // When two elements with same address are seen, the one from updates is selected.
   501  // Expects updates to be a list of updates sorted by address with no duplicates or errors,
   502  // must have been validated with verifyUpdates() and priorities computed with computeNewPriorities().
   503  func (vals *ValidatorSet) applyUpdates(updates []*Validator) {
   504  	existing := vals.Validators
   505  	sort.Sort(ValidatorsByAddress(existing))
   506  
   507  	merged := make([]*Validator, len(existing)+len(updates))
   508  	i := 0
   509  
   510  	for len(existing) > 0 && len(updates) > 0 {
   511  		if bytes.Compare(existing[0].Address, updates[0].Address) < 0 { // unchanged validator
   512  			merged[i] = existing[0]
   513  			existing = existing[1:]
   514  		} else {
   515  			// Apply add or update.
   516  			merged[i] = updates[0]
   517  			if bytes.Equal(existing[0].Address, updates[0].Address) {
   518  				// Validator is present in both, advance existing.
   519  				existing = existing[1:]
   520  			}
   521  			updates = updates[1:]
   522  		}
   523  		i++
   524  	}
   525  
   526  	// Add the elements which are left.
   527  	for j := 0; j < len(existing); j++ {
   528  		merged[i] = existing[j]
   529  		i++
   530  	}
   531  	// OR add updates which are left.
   532  	for j := 0; j < len(updates); j++ {
   533  		merged[i] = updates[j]
   534  		i++
   535  	}
   536  
   537  	vals.Validators = merged[:i]
   538  }
   539  
   540  // Checks that the validators to be removed are part of the validator set.
   541  // No changes are made to the validator set 'vals'.
   542  func verifyRemovals(deletes []*Validator, vals *ValidatorSet) (votingPower int64, err error) {
   543  	removedVotingPower := int64(0)
   544  	for _, valUpdate := range deletes {
   545  		address := valUpdate.Address
   546  		_, val := vals.GetByAddress(address)
   547  		if val == nil {
   548  			return removedVotingPower, fmt.Errorf("failed to find validator %X to remove", address)
   549  		}
   550  		removedVotingPower += val.VotingPower
   551  	}
   552  	if len(deletes) > len(vals.Validators) {
   553  		panic("more deletes than validators")
   554  	}
   555  	return removedVotingPower, nil
   556  }
   557  
   558  // Removes the validators specified in 'deletes' from validator set 'vals'.
   559  // Should not fail as verification has been done before.
   560  // Expects vals to be sorted by address (done by applyUpdates).
   561  func (vals *ValidatorSet) applyRemovals(deletes []*Validator) {
   562  	existing := vals.Validators
   563  
   564  	merged := make([]*Validator, len(existing)-len(deletes))
   565  	i := 0
   566  
   567  	// Loop over deletes until we removed all of them.
   568  	for len(deletes) > 0 {
   569  		if bytes.Equal(existing[0].Address, deletes[0].Address) {
   570  			deletes = deletes[1:]
   571  		} else { // Leave it in the resulting slice.
   572  			merged[i] = existing[0]
   573  			i++
   574  		}
   575  		existing = existing[1:]
   576  	}
   577  
   578  	// Add the elements which are left.
   579  	for j := 0; j < len(existing); j++ {
   580  		merged[i] = existing[j]
   581  		i++
   582  	}
   583  
   584  	vals.Validators = merged[:i]
   585  }
   586  
   587  // Main function used by UpdateWithChangeSet() and NewValidatorSet().
   588  // If 'allowDeletes' is false then delete operations (identified by validators with voting power 0)
   589  // are not allowed and will trigger an error if present in 'changes'.
   590  // The 'allowDeletes' flag is set to false by NewValidatorSet() and to true by UpdateWithChangeSet().
   591  func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes bool) error {
   592  	if len(changes) == 0 {
   593  		return nil
   594  	}
   595  
   596  	// Check for duplicates within changes, split in 'updates' and 'deletes' lists (sorted).
   597  	updates, deletes, err := processChanges(changes)
   598  	if err != nil {
   599  		return err
   600  	}
   601  
   602  	if !allowDeletes && len(deletes) != 0 {
   603  		return fmt.Errorf("cannot process validators with voting power 0: %v", deletes)
   604  	}
   605  
   606  	// Check that the resulting set will not be empty.
   607  	if numNewValidators(updates, vals) == 0 && len(vals.Validators) == len(deletes) {
   608  		return errors.New("applying the validator changes would result in empty set")
   609  	}
   610  
   611  	// Verify that applying the 'deletes' against 'vals' will not result in error.
   612  	// Get the voting power that is going to be removed.
   613  	removedVotingPower, err := verifyRemovals(deletes, vals)
   614  	if err != nil {
   615  		return err
   616  	}
   617  
   618  	// Verify that applying the 'updates' against 'vals' will not result in error.
   619  	// Get the updated total voting power before removal. Note that this is < 2 * MaxTotalVotingPower
   620  	tvpAfterUpdatesBeforeRemovals, err := verifyUpdates(updates, vals, removedVotingPower)
   621  	if err != nil {
   622  		return err
   623  	}
   624  
   625  	// Compute the priorities for updates.
   626  	computeNewPriorities(updates, vals, tvpAfterUpdatesBeforeRemovals)
   627  
   628  	// Apply updates and removals.
   629  	vals.applyUpdates(updates)
   630  	vals.applyRemovals(deletes)
   631  
   632  	vals.updateTotalVotingPower() // will panic if total voting power > MaxTotalVotingPower
   633  
   634  	// Scale and center.
   635  	vals.RescalePriorities(PriorityWindowSizeFactor * vals.TotalVotingPower())
   636  	vals.shiftByAvgProposerPriority()
   637  
   638  	sort.Sort(ValidatorsByVotingPower(vals.Validators))
   639  
   640  	return nil
   641  }
   642  
   643  // UpdateWithChangeSet attempts to update the validator set with 'changes'.
   644  // It performs the following steps:
   645  //   - validates the changes making sure there are no duplicates and splits them in updates and deletes
   646  //   - verifies that applying the changes will not result in errors
   647  //   - computes the total voting power BEFORE removals to ensure that in the next steps the priorities
   648  //     across old and newly added validators are fair
   649  //   - computes the priorities of new validators against the final set
   650  //   - applies the updates against the validator set
   651  //   - applies the removals against the validator set
   652  //   - performs scaling and centering of priority values
   653  //
   654  // If an error is detected during verification steps, it is returned and the validator set
   655  // is not changed.
   656  func (vals *ValidatorSet) UpdateWithChangeSet(changes []*Validator) error {
   657  	return vals.updateWithChangeSet(changes, true)
   658  }
   659  
   660  // VerifyCommit verifies +2/3 of the set had signed the given commit.
   661  //
   662  // It checks all the signatures! While it's safe to exit as soon as we have
   663  // 2/3+ signatures, doing so would impact incentivization logic in the ABCI
   664  // application that depends on the LastCommitInfo sent in BeginBlock, which
   665  // includes which validators signed. For instance, Gaia incentivizes proposers
   666  // with a bonus for including more than +2/3 of the signatures.
   667  func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID,
   668  	height int64, commit *Commit) error {
   669  
   670  	if vals.Size() != len(commit.Signatures) {
   671  		return NewErrInvalidCommitSignatures(vals.Size(), len(commit.Signatures))
   672  	}
   673  
   674  	// Validate Height and BlockID.
   675  	if height != commit.Height {
   676  		return NewErrInvalidCommitHeight(height, commit.Height)
   677  	}
   678  	if !blockID.Equals(commit.BlockID) {
   679  		return fmt.Errorf("invalid commit -- wrong block ID: want %v, got %v",
   680  			blockID, commit.BlockID)
   681  	}
   682  
   683  	talliedVotingPower := int64(0)
   684  	votingPowerNeeded := vals.TotalVotingPower() * 2 / 3
   685  	for idx, commitSig := range commit.Signatures {
   686  		if commitSig.Absent() {
   687  			continue // OK, some signatures can be absent.
   688  		}
   689  
   690  		// The vals and commit have a 1-to-1 correspondance.
   691  		// This means we don't need the validator address or to do any lookup.
   692  		val := vals.Validators[idx]
   693  
   694  		// Validate signature.
   695  		voteSignBytes := commit.VoteSignBytes(chainID, int32(idx))
   696  		if !val.PubKey.VerifySignature(voteSignBytes, commitSig.Signature) {
   697  			return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)
   698  		}
   699  		// Good!
   700  		if commitSig.ForBlock() {
   701  			talliedVotingPower += val.VotingPower
   702  		}
   703  		// else {
   704  		// It's OK. We include stray signatures (~votes for nil) to measure
   705  		// validator availability.
   706  		// }
   707  	}
   708  
   709  	if got, needed := talliedVotingPower, votingPowerNeeded; got <= needed {
   710  		return ErrNotEnoughVotingPowerSigned{Got: got, Needed: needed}
   711  	}
   712  
   713  	return nil
   714  }
   715  
   716  // LIGHT CLIENT VERIFICATION METHODS
   717  
   718  // VerifyCommitLight verifies +2/3 of the set had signed the given commit.
   719  //
   720  // This method is primarily used by the light client and does not check all the
   721  // signatures.
   722  func (vals *ValidatorSet) VerifyCommitLight(chainID string, blockID BlockID,
   723  	height int64, commit *Commit) error {
   724  
   725  	if vals.Size() != len(commit.Signatures) {
   726  		return NewErrInvalidCommitSignatures(vals.Size(), len(commit.Signatures))
   727  	}
   728  
   729  	// Validate Height and BlockID.
   730  	if height != commit.Height {
   731  		return NewErrInvalidCommitHeight(height, commit.Height)
   732  	}
   733  	if !blockID.Equals(commit.BlockID) {
   734  		return fmt.Errorf("invalid commit -- wrong block ID: want %v, got %v",
   735  			blockID, commit.BlockID)
   736  	}
   737  
   738  	talliedVotingPower := int64(0)
   739  	votingPowerNeeded := vals.TotalVotingPower() * 2 / 3
   740  	for idx, commitSig := range commit.Signatures {
   741  		// No need to verify absent or nil votes.
   742  		if !commitSig.ForBlock() {
   743  			continue
   744  		}
   745  
   746  		// The vals and commit have a 1-to-1 correspondance.
   747  		// This means we don't need the validator address or to do any lookup.
   748  		val := vals.Validators[idx]
   749  
   750  		// Validate signature.
   751  		voteSignBytes := commit.VoteSignBytes(chainID, int32(idx))
   752  		if !val.PubKey.VerifySignature(voteSignBytes, commitSig.Signature) {
   753  			return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)
   754  		}
   755  
   756  		talliedVotingPower += val.VotingPower
   757  
   758  		// return as soon as +2/3 of the signatures are verified
   759  		if talliedVotingPower > votingPowerNeeded {
   760  			return nil
   761  		}
   762  	}
   763  
   764  	return ErrNotEnoughVotingPowerSigned{Got: talliedVotingPower, Needed: votingPowerNeeded}
   765  }
   766  
   767  // VerifyCommitLightTrusting verifies that trustLevel of the validator set signed
   768  // this commit.
   769  //
   770  // NOTE the given validators do not necessarily correspond to the validator set
   771  // for this commit, but there may be some intersection.
   772  //
   773  // This method is primarily used by the light client and does not check all the
   774  // signatures.
   775  func (vals *ValidatorSet) VerifyCommitLightTrusting(chainID string, commit *Commit, trustLevel tmmath.Fraction) error {
   776  	// sanity check
   777  	if trustLevel.Denominator == 0 {
   778  		return errors.New("trustLevel has zero Denominator")
   779  	}
   780  
   781  	var (
   782  		talliedVotingPower int64
   783  		seenVals           = make(map[int32]int, len(commit.Signatures)) // validator index -> commit index
   784  	)
   785  
   786  	// Safely calculate voting power needed.
   787  	totalVotingPowerMulByNumerator, overflow := safeMul(vals.TotalVotingPower(), int64(trustLevel.Numerator))
   788  	if overflow {
   789  		return errors.New("int64 overflow while calculating voting power needed. please provide smaller trustLevel numerator")
   790  	}
   791  	votingPowerNeeded := totalVotingPowerMulByNumerator / int64(trustLevel.Denominator)
   792  
   793  	for idx, commitSig := range commit.Signatures {
   794  		// No need to verify absent or nil votes.
   795  		if !commitSig.ForBlock() {
   796  			continue
   797  		}
   798  
   799  		// We don't know the validators that committed this block, so we have to
   800  		// check for each vote if its validator is already known.
   801  		valIdx, val := vals.GetByAddress(commitSig.ValidatorAddress)
   802  
   803  		if val != nil {
   804  			// check for double vote of validator on the same commit
   805  			if firstIndex, ok := seenVals[valIdx]; ok {
   806  				secondIndex := idx
   807  				return fmt.Errorf("double vote from %v (%d and %d)", val, firstIndex, secondIndex)
   808  			}
   809  			seenVals[valIdx] = idx
   810  
   811  			// Validate signature.
   812  			voteSignBytes := commit.VoteSignBytes(chainID, int32(idx))
   813  			if !val.PubKey.VerifySignature(voteSignBytes, commitSig.Signature) {
   814  				return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)
   815  			}
   816  
   817  			talliedVotingPower += val.VotingPower
   818  
   819  			if talliedVotingPower > votingPowerNeeded {
   820  				return nil
   821  			}
   822  		}
   823  	}
   824  
   825  	return ErrNotEnoughVotingPowerSigned{Got: talliedVotingPower, Needed: votingPowerNeeded}
   826  }
   827  
   828  // findPreviousProposer reverses the compare proposer priority function to find the validator
   829  // with the lowest proposer priority which would have been the previous proposer.
   830  //
   831  // Is used when recreating a validator set from an existing array of validators.
   832  func (vals *ValidatorSet) findPreviousProposer() *Validator {
   833  	var previousProposer *Validator
   834  	for _, val := range vals.Validators {
   835  		if previousProposer == nil {
   836  			previousProposer = val
   837  			continue
   838  		}
   839  		if previousProposer == previousProposer.CompareProposerPriority(val) {
   840  			previousProposer = val
   841  		}
   842  	}
   843  	return previousProposer
   844  }
   845  
   846  //-----------------
   847  
   848  // IsErrNotEnoughVotingPowerSigned returns true if err is
   849  // ErrNotEnoughVotingPowerSigned.
   850  func IsErrNotEnoughVotingPowerSigned(err error) bool {
   851  	return errors.As(err, &ErrNotEnoughVotingPowerSigned{})
   852  }
   853  
   854  // ErrNotEnoughVotingPowerSigned is returned when not enough validators signed
   855  // a commit.
   856  type ErrNotEnoughVotingPowerSigned struct {
   857  	Got    int64
   858  	Needed int64
   859  }
   860  
   861  func (e ErrNotEnoughVotingPowerSigned) Error() string {
   862  	return fmt.Sprintf("invalid commit -- insufficient voting power: got %d, needed more than %d", e.Got, e.Needed)
   863  }
   864  
   865  //----------------
   866  
   867  // String returns a string representation of ValidatorSet.
   868  //
   869  // See StringIndented.
   870  func (vals *ValidatorSet) String() string {
   871  	return vals.StringIndented("")
   872  }
   873  
   874  // StringIndented returns an intended String.
   875  //
   876  // See Validator#String.
   877  func (vals *ValidatorSet) StringIndented(indent string) string {
   878  	if vals == nil {
   879  		return "nil-ValidatorSet"
   880  	}
   881  	var valStrings []string
   882  	vals.Iterate(func(index int, val *Validator) bool {
   883  		valStrings = append(valStrings, val.String())
   884  		return false
   885  	})
   886  	return fmt.Sprintf(`ValidatorSet{
   887  %s  Proposer: %v
   888  %s  Validators:
   889  %s    %v
   890  %s}`,
   891  		indent, vals.GetProposer().String(),
   892  		indent,
   893  		indent, strings.Join(valStrings, "\n"+indent+"    "),
   894  		indent)
   895  
   896  }
   897  
   898  //-------------------------------------
   899  
   900  // ValidatorsByVotingPower implements sort.Interface for []*Validator based on
   901  // the VotingPower and Address fields.
   902  type ValidatorsByVotingPower []*Validator
   903  
   904  func (valz ValidatorsByVotingPower) Len() int { return len(valz) }
   905  
   906  func (valz ValidatorsByVotingPower) Less(i, j int) bool {
   907  	if valz[i].VotingPower == valz[j].VotingPower {
   908  		return bytes.Compare(valz[i].Address, valz[j].Address) == -1
   909  	}
   910  	return valz[i].VotingPower > valz[j].VotingPower
   911  }
   912  
   913  func (valz ValidatorsByVotingPower) Swap(i, j int) {
   914  	valz[i], valz[j] = valz[j], valz[i]
   915  }
   916  
   917  // ValidatorsByAddress implements sort.Interface for []*Validator based on
   918  // the Address field.
   919  type ValidatorsByAddress []*Validator
   920  
   921  func (valz ValidatorsByAddress) Len() int { return len(valz) }
   922  
   923  func (valz ValidatorsByAddress) Less(i, j int) bool {
   924  	return bytes.Compare(valz[i].Address, valz[j].Address) == -1
   925  }
   926  
   927  func (valz ValidatorsByAddress) Swap(i, j int) {
   928  	valz[i], valz[j] = valz[j], valz[i]
   929  }
   930  
   931  // ToProto converts ValidatorSet to protobuf
   932  func (vals *ValidatorSet) ToProto() (*tmproto.ValidatorSet, error) {
   933  	if vals.IsNilOrEmpty() {
   934  		return &tmproto.ValidatorSet{}, nil // validator set should never be nil
   935  	}
   936  
   937  	vp := new(tmproto.ValidatorSet)
   938  	valsProto := make([]*tmproto.Validator, len(vals.Validators))
   939  	for i := 0; i < len(vals.Validators); i++ {
   940  		valp, err := vals.Validators[i].ToProto()
   941  		if err != nil {
   942  			return nil, err
   943  		}
   944  		valsProto[i] = valp
   945  	}
   946  	vp.Validators = valsProto
   947  
   948  	valProposer, err := vals.Proposer.ToProto()
   949  	if err != nil {
   950  		return nil, fmt.Errorf("toProto: validatorSet proposer error: %w", err)
   951  	}
   952  	vp.Proposer = valProposer
   953  
   954  	// NOTE: Sometimes we use the bytes of the proto form as a hash. This means that we need to
   955  	// be consistent with cached data
   956  	vp.TotalVotingPower = 0
   957  
   958  	return vp, nil
   959  }
   960  
   961  // ValidatorSetFromProto sets a protobuf ValidatorSet to the given pointer.
   962  // It returns an error if any of the validators from the set or the proposer
   963  // is invalid
   964  func ValidatorSetFromProto(vp *tmproto.ValidatorSet) (*ValidatorSet, error) {
   965  	if vp == nil {
   966  		return nil, errors.New("nil validator set") // validator set should never be nil, bigger issues are at play if empty
   967  	}
   968  	vals := new(ValidatorSet)
   969  
   970  	valsProto := make([]*Validator, len(vp.Validators))
   971  	for i := 0; i < len(vp.Validators); i++ {
   972  		v, err := ValidatorFromProto(vp.Validators[i])
   973  		if err != nil {
   974  			return nil, err
   975  		}
   976  		valsProto[i] = v
   977  	}
   978  	vals.Validators = valsProto
   979  
   980  	p, err := ValidatorFromProto(vp.GetProposer())
   981  	if err != nil {
   982  		return nil, fmt.Errorf("fromProto: validatorSet proposer error: %w", err)
   983  	}
   984  
   985  	vals.Proposer = p
   986  
   987  	// NOTE: We can't trust the total voting power given to us by other peers. If someone were to
   988  	// inject a non-zeo value that wasn't the correct voting power we could assume a wrong total
   989  	// power hence we need to recompute it.
   990  	// FIXME: We should look to remove TotalVotingPower from proto or add it in the validators hash
   991  	// so we don't have to do this
   992  	vals.TotalVotingPower()
   993  
   994  	return vals, vals.ValidateBasic()
   995  }
   996  
   997  // ValidatorSetFromExistingValidators takes an existing array of validators and
   998  // rebuilds the exact same validator set that corresponds to it without
   999  // changing the proposer priority or power if any of the validators fail
  1000  // validate basic then an empty set is returned.
  1001  func ValidatorSetFromExistingValidators(valz []*Validator) (*ValidatorSet, error) {
  1002  	if len(valz) == 0 {
  1003  		return nil, errors.New("validator set is empty")
  1004  	}
  1005  	for _, val := range valz {
  1006  		err := val.ValidateBasic()
  1007  		if err != nil {
  1008  			return nil, fmt.Errorf("can't create validator set: %w", err)
  1009  		}
  1010  	}
  1011  
  1012  	vals := &ValidatorSet{
  1013  		Validators: valz,
  1014  	}
  1015  	vals.Proposer = vals.findPreviousProposer()
  1016  	vals.updateTotalVotingPower()
  1017  	sort.Sort(ValidatorsByVotingPower(vals.Validators))
  1018  	return vals, nil
  1019  }
  1020  
  1021  //----------------------------------------
  1022  
  1023  // RandValidatorSet returns a randomized validator set (size: +numValidators+),
  1024  // where each validator has a voting power of +votingPower+.
  1025  //
  1026  // EXPOSED FOR TESTING.
  1027  func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) {
  1028  	var (
  1029  		valz           = make([]*Validator, numValidators)
  1030  		privValidators = make([]PrivValidator, numValidators)
  1031  	)
  1032  
  1033  	for i := 0; i < numValidators; i++ {
  1034  		val, privValidator := RandValidator(false, votingPower)
  1035  		valz[i] = val
  1036  		privValidators[i] = privValidator
  1037  	}
  1038  
  1039  	sort.Sort(PrivValidatorsByAddress(privValidators))
  1040  
  1041  	return NewValidatorSet(valz), privValidators
  1042  }
  1043  
  1044  // safe addition/subtraction/multiplication
  1045  
  1046  func safeAdd(a, b int64) (int64, bool) {
  1047  	if b > 0 && a > math.MaxInt64-b {
  1048  		return -1, true
  1049  	} else if b < 0 && a < math.MinInt64-b {
  1050  		return -1, true
  1051  	}
  1052  	return a + b, false
  1053  }
  1054  
  1055  func safeSub(a, b int64) (int64, bool) {
  1056  	if b > 0 && a < math.MinInt64+b {
  1057  		return -1, true
  1058  	} else if b < 0 && a > math.MaxInt64+b {
  1059  		return -1, true
  1060  	}
  1061  	return a - b, false
  1062  }
  1063  
  1064  func safeAddClip(a, b int64) int64 {
  1065  	c, overflow := safeAdd(a, b)
  1066  	if overflow {
  1067  		if b < 0 {
  1068  			return math.MinInt64
  1069  		}
  1070  		return math.MaxInt64
  1071  	}
  1072  	return c
  1073  }
  1074  
  1075  func safeSubClip(a, b int64) int64 {
  1076  	c, overflow := safeSub(a, b)
  1077  	if overflow {
  1078  		if b > 0 {
  1079  			return math.MinInt64
  1080  		}
  1081  		return math.MaxInt64
  1082  	}
  1083  	return c
  1084  }
  1085  
  1086  func safeMul(a, b int64) (int64, bool) {
  1087  	if a == 0 || b == 0 {
  1088  		return 0, false
  1089  	}
  1090  
  1091  	absOfB := b
  1092  	if b < 0 {
  1093  		absOfB = -b
  1094  	}
  1095  
  1096  	absOfA := a
  1097  	if a < 0 {
  1098  		absOfA = -a
  1099  	}
  1100  
  1101  	if absOfA > math.MaxInt64/absOfB {
  1102  		return 0, true
  1103  	}
  1104  
  1105  	return a * b, false
  1106  }