github.com/Finschia/ostracon@v1.1.5/types/validator_set.go (about)

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