github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/consensus/bor/valset/validator_set.go (about)

     1  package valset
     2  
     3  // Tendermint leader selection algorithm
     4  
     5  import (
     6  	"bytes"
     7  	"fmt"
     8  	"math"
     9  	"math/big"
    10  	"sort"
    11  	"strings"
    12  
    13  	"github.com/ethereum/go-ethereum/common"
    14  	"github.com/ethereum/go-ethereum/log"
    15  )
    16  
    17  // MaxTotalVotingPower - the maximum allowed total voting power.
    18  // It needs to be sufficiently small to, in all cases:
    19  // 1. prevent clipping in incrementProposerPriority()
    20  // 2. let (diff+diffMax-1) not overflow in IncrementProposerPriority()
    21  // (Proof of 1 is tricky, left to the reader).
    22  // It could be higher, but this is sufficiently large for our purposes,
    23  // and leaves room for defensive purposes.
    24  // PriorityWindowSizeFactor - is a constant that when multiplied with the total voting power gives
    25  // the maximum allowed distance between validator priorities.
    26  
    27  const (
    28  	MaxTotalVotingPower      = int64(math.MaxInt64) / 8
    29  	PriorityWindowSizeFactor = 2
    30  )
    31  
    32  // ValidatorSet represent a set of *Validator at a given height.
    33  // The validators can be fetched by address or index.
    34  // The index is in order of .Address, so the indices are fixed
    35  // for all rounds of a given blockchain height - ie. the validators
    36  // are sorted by their address.
    37  // On the other hand, the .ProposerPriority of each validator and
    38  // the designated .GetProposer() of a set changes every round,
    39  // upon calling .IncrementProposerPriority().
    40  // NOTE: Not goroutine-safe.
    41  // NOTE: All get/set to validators should copy the value for safety.
    42  type ValidatorSet struct {
    43  	// NOTE: persisted via reflect, must be exported.
    44  	Validators []*Validator `json:"validators"`
    45  	Proposer   *Validator   `json:"proposer"`
    46  
    47  	// cached (unexported)
    48  	totalVotingPower int64
    49  	validatorsMap    map[common.Address]int // address -> index
    50  }
    51  
    52  // NewValidatorSet initializes a ValidatorSet by copying over the
    53  // values from `valz`, a list of Validators. If valz is nil or empty,
    54  // the new ValidatorSet will have an empty list of Validators.
    55  // The addresses of validators in `valz` must be unique otherwise the
    56  // function panics.
    57  func NewValidatorSet(valz []*Validator) *ValidatorSet {
    58  	vals := &ValidatorSet{validatorsMap: make(map[common.Address]int)}
    59  
    60  	err := vals.updateWithChangeSet(valz, false)
    61  	if err != nil {
    62  		panic(fmt.Sprintf("cannot create validator set: %s", err))
    63  	}
    64  
    65  	if len(valz) > 0 {
    66  		vals.IncrementProposerPriority(1)
    67  	}
    68  
    69  	return vals
    70  }
    71  
    72  // Nil or empty validator sets are invalid.
    73  func (vals *ValidatorSet) IsNilOrEmpty() bool {
    74  	return vals == nil || len(vals.Validators) == 0
    75  }
    76  
    77  // Increment ProposerPriority and update the proposer on a copy, and return it.
    78  func (vals *ValidatorSet) CopyIncrementProposerPriority(times int) *ValidatorSet {
    79  	validatorCopy := vals.Copy()
    80  	validatorCopy.IncrementProposerPriority(times)
    81  
    82  	return validatorCopy
    83  }
    84  
    85  // IncrementProposerPriority increments ProposerPriority of each validator and updates the
    86  // proposer. Panics if validator set is empty.
    87  // `times` must be positive.
    88  func (vals *ValidatorSet) IncrementProposerPriority(times int) {
    89  	if vals.IsNilOrEmpty() {
    90  		panic("empty validator set")
    91  	}
    92  
    93  	if times <= 0 {
    94  		panic("Cannot call IncrementProposerPriority with non-positive times")
    95  	}
    96  
    97  	// Cap the difference between priorities to be proportional to 2*totalPower by
    98  	// re-normalizing priorities, i.e., rescale all priorities by multiplying with:
    99  	//  2*totalVotingPower/(maxPriority - minPriority)
   100  	diffMax := PriorityWindowSizeFactor * vals.TotalVotingPower()
   101  	vals.RescalePriorities(diffMax)
   102  	vals.shiftByAvgProposerPriority()
   103  
   104  	var proposer *Validator
   105  	// Call IncrementProposerPriority(1) times times.
   106  	for i := 0; i < times; i++ {
   107  		proposer = vals.incrementProposerPriority()
   108  	}
   109  
   110  	vals.Proposer = proposer
   111  }
   112  
   113  func (vals *ValidatorSet) RescalePriorities(diffMax int64) {
   114  	if vals.IsNilOrEmpty() {
   115  		panic("empty validator set")
   116  	}
   117  	// NOTE: This check is merely a sanity check which could be
   118  	// removed if all tests would init. voting power appropriately;
   119  	// i.e. diffMax should always be > 0
   120  	if diffMax <= 0 {
   121  		return
   122  	}
   123  
   124  	// Calculating ceil(diff/diffMax):
   125  	// Re-normalization is performed by dividing by an integer for simplicity.
   126  	// NOTE: This may make debugging priority issues easier as well.
   127  	diff := computeMaxMinPriorityDiff(vals)
   128  	ratio := (diff + diffMax - 1) / diffMax
   129  
   130  	if diff > diffMax {
   131  		for _, val := range vals.Validators {
   132  			val.ProposerPriority = val.ProposerPriority / ratio
   133  		}
   134  	}
   135  }
   136  
   137  func (vals *ValidatorSet) incrementProposerPriority() *Validator {
   138  	for _, val := range vals.Validators {
   139  		// Check for overflow for sum.
   140  		newPrio := safeAddClip(val.ProposerPriority, val.VotingPower)
   141  		val.ProposerPriority = newPrio
   142  	}
   143  	// Decrement the validator with most ProposerPriority.
   144  	mostest := vals.getValWithMostPriority()
   145  	// Mind the underflow.
   146  	mostest.ProposerPriority = safeSubClip(mostest.ProposerPriority, vals.TotalVotingPower())
   147  
   148  	return mostest
   149  }
   150  
   151  // Should not be called on an empty validator set.
   152  func (vals *ValidatorSet) computeAvgProposerPriority() int64 {
   153  	n := int64(len(vals.Validators))
   154  	sum := big.NewInt(0)
   155  
   156  	for _, val := range vals.Validators {
   157  		sum.Add(sum, big.NewInt(val.ProposerPriority))
   158  	}
   159  
   160  	avg := sum.Div(sum, big.NewInt(n))
   161  
   162  	if avg.IsInt64() {
   163  		return avg.Int64()
   164  	}
   165  
   166  	// This should never happen: each val.ProposerPriority is in bounds of int64.
   167  	panic(fmt.Sprintf("Cannot represent avg ProposerPriority as an int64 %v", avg))
   168  }
   169  
   170  // Compute the difference between the max and min ProposerPriority of that set.
   171  func computeMaxMinPriorityDiff(vals *ValidatorSet) int64 {
   172  	if vals.IsNilOrEmpty() {
   173  		panic("empty validator set")
   174  	}
   175  
   176  	max := int64(math.MinInt64)
   177  	min := int64(math.MaxInt64)
   178  
   179  	for _, v := range vals.Validators {
   180  		if v.ProposerPriority < min {
   181  			min = v.ProposerPriority
   182  		}
   183  
   184  		if v.ProposerPriority > max {
   185  			max = v.ProposerPriority
   186  		}
   187  	}
   188  
   189  	diff := max - min
   190  
   191  	if diff < 0 {
   192  		return -1 * diff
   193  	} else {
   194  		return diff
   195  	}
   196  }
   197  
   198  func (vals *ValidatorSet) getValWithMostPriority() *Validator {
   199  	var res *Validator
   200  	for _, val := range vals.Validators {
   201  		res = res.Cmp(val)
   202  	}
   203  
   204  	return res
   205  }
   206  
   207  func (vals *ValidatorSet) shiftByAvgProposerPriority() {
   208  	if vals.IsNilOrEmpty() {
   209  		panic("empty validator set")
   210  	}
   211  
   212  	avgProposerPriority := vals.computeAvgProposerPriority()
   213  
   214  	for _, val := range vals.Validators {
   215  		val.ProposerPriority = safeSubClip(val.ProposerPriority, avgProposerPriority)
   216  	}
   217  }
   218  
   219  // Makes a copy of the validator list.
   220  func validatorListCopy(valsList []*Validator) []*Validator {
   221  	if valsList == nil {
   222  		return nil
   223  	}
   224  
   225  	valsCopy := make([]*Validator, len(valsList))
   226  
   227  	for i, val := range valsList {
   228  		valsCopy[i] = val.Copy()
   229  	}
   230  
   231  	return valsCopy
   232  }
   233  
   234  // Copy each validator into a new ValidatorSet.
   235  func (vals *ValidatorSet) Copy() *ValidatorSet {
   236  	valCopy := validatorListCopy(vals.Validators)
   237  	validatorsMap := make(map[common.Address]int, len(vals.Validators))
   238  
   239  	for i, val := range valCopy {
   240  		validatorsMap[val.Address] = i
   241  	}
   242  
   243  	return &ValidatorSet{
   244  		Validators:       validatorListCopy(vals.Validators),
   245  		Proposer:         vals.Proposer,
   246  		totalVotingPower: vals.totalVotingPower,
   247  		validatorsMap:    validatorsMap,
   248  	}
   249  }
   250  
   251  // HasAddress returns true if address given is in the validator set, false -
   252  // otherwise.
   253  func (vals *ValidatorSet) HasAddress(address common.Address) bool {
   254  	_, ok := vals.validatorsMap[address]
   255  
   256  	return ok
   257  }
   258  
   259  // GetByAddress returns an index of the validator with address and validator
   260  // itself if found. Otherwise, -1 and nil are returned.
   261  func (vals *ValidatorSet) GetByAddress(address common.Address) (index int, val *Validator) {
   262  	idx, ok := vals.validatorsMap[address]
   263  	if ok {
   264  		return idx, vals.Validators[idx].Copy()
   265  	}
   266  
   267  	return -1, nil
   268  }
   269  
   270  // GetByIndex returns the validator's address and validator itself by index.
   271  // It returns nil values if index is less than 0 or greater or equal to
   272  // len(ValidatorSet.Validators).
   273  func (vals *ValidatorSet) GetByIndex(index int) (address common.Address, val *Validator) {
   274  	if index < 0 || index >= len(vals.Validators) {
   275  		return common.Address{}, nil
   276  	}
   277  
   278  	val = vals.Validators[index]
   279  
   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  // Force recalculation of the set's total voting power.
   289  func (vals *ValidatorSet) UpdateTotalVotingPower() error {
   290  	sum := int64(0)
   291  	for _, val := range vals.Validators {
   292  		// mind overflow
   293  		sum = safeAddClip(sum, val.VotingPower)
   294  		if sum > MaxTotalVotingPower {
   295  			return &TotalVotingPowerExceededError{sum, vals.Validators}
   296  		}
   297  	}
   298  
   299  	vals.totalVotingPower = sum
   300  
   301  	return nil
   302  }
   303  
   304  // TotalVotingPower returns the sum of the voting powers of all validators.
   305  // It recomputes the total voting power if required.
   306  func (vals *ValidatorSet) TotalVotingPower() int64 {
   307  	if vals.totalVotingPower == 0 {
   308  		log.Debug("invoking updateTotalVotingPower before returning it")
   309  
   310  		if err := vals.UpdateTotalVotingPower(); err != nil {
   311  			// Can/should we do better?
   312  			panic(err)
   313  		}
   314  	}
   315  
   316  	return vals.totalVotingPower
   317  }
   318  
   319  // GetProposer returns the current proposer. If the validator set is empty, nil
   320  // is returned.
   321  func (vals *ValidatorSet) GetProposer() (proposer *Validator) {
   322  	if len(vals.Validators) == 0 {
   323  		return nil
   324  	}
   325  
   326  	if vals.Proposer == nil {
   327  		vals.Proposer = vals.findProposer()
   328  	}
   329  
   330  	return vals.Proposer.Copy()
   331  }
   332  
   333  func (vals *ValidatorSet) findProposer() *Validator {
   334  	var proposer *Validator
   335  	for _, val := range vals.Validators {
   336  		if proposer == nil || val.Address != proposer.Address {
   337  			proposer = proposer.Cmp(val)
   338  		}
   339  	}
   340  
   341  	return proposer
   342  }
   343  
   344  // Hash returns the Merkle root hash build using validators (as leaves) in the
   345  // set.
   346  // func (vals *ValidatorSet) Hash() []byte {
   347  // 	if len(vals.Validators) == 0 {
   348  // 		return nil
   349  // 	}
   350  // 	bzs := make([][]byte, len(vals.Validators))
   351  // 	for i, val := range vals.Validators {
   352  // 		bzs[i] = val.Bytes()
   353  // 	}
   354  // 	return merkle.SimpleHashFromByteSlices(bzs)
   355  // }
   356  
   357  // Iterate will run the given function over the set.
   358  func (vals *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) {
   359  	for i, val := range vals.Validators {
   360  		stop := fn(i, val.Copy())
   361  		if stop {
   362  			break
   363  		}
   364  	}
   365  }
   366  
   367  // Checks changes against duplicates, splits the changes in updates and removals, sorts them by address.
   368  //
   369  // Returns:
   370  // updates, removals - the sorted lists of updates and removals
   371  // err - non-nil if duplicate entries or entries with negative voting power are seen
   372  //
   373  // No changes are made to 'origChanges'.
   374  func processChanges(origChanges []*Validator) (updates, removals []*Validator, err error) {
   375  	// Make a deep copy of the changes and sort by address.
   376  	changes := validatorListCopy(origChanges)
   377  	sort.Sort(ValidatorsByAddress(changes))
   378  
   379  	sliceCap := len(changes) / 2
   380  	if sliceCap == 0 {
   381  		sliceCap = 1
   382  	}
   383  
   384  	removals = make([]*Validator, 0, sliceCap)
   385  	updates = make([]*Validator, 0, sliceCap)
   386  
   387  	var prevAddr common.Address
   388  
   389  	// Scan changes by address and append valid validators to updates or removals lists.
   390  	for _, valUpdate := range changes {
   391  		if valUpdate.Address == prevAddr {
   392  			err = fmt.Errorf("duplicate entry %v in %v", valUpdate, changes)
   393  			return nil, nil, err
   394  		}
   395  
   396  		if valUpdate.VotingPower < 0 {
   397  			err = fmt.Errorf("voting power can't be negative: %v", valUpdate)
   398  			return nil, nil, err
   399  		}
   400  
   401  		if valUpdate.VotingPower > MaxTotalVotingPower {
   402  			err = fmt.Errorf("to prevent clipping/ overflow, voting power can't be higher than %v: %v ",
   403  				MaxTotalVotingPower, valUpdate)
   404  			return nil, nil, err
   405  		}
   406  
   407  		if valUpdate.VotingPower == 0 {
   408  			removals = append(removals, valUpdate)
   409  		} else {
   410  			updates = append(updates, valUpdate)
   411  		}
   412  
   413  		prevAddr = valUpdate.Address
   414  	}
   415  
   416  	return updates, removals, err
   417  }
   418  
   419  // Verifies a list of updates against a validator set, making sure the allowed
   420  // total voting power would not be exceeded if these updates would be applied to the set.
   421  //
   422  // Returns:
   423  // updatedTotalVotingPower - the new total voting power if these updates would be applied
   424  // numNewValidators - number of new validators
   425  // err - non-nil if the maximum allowed total voting power would be exceeded
   426  //
   427  // 'updates' should be a list of proper validator changes, i.e. they have been verified
   428  // by processChanges for duplicates and invalid values.
   429  // No changes are made to the validator set 'vals'.
   430  func verifyUpdates(updates []*Validator, vals *ValidatorSet) (updatedTotalVotingPower int64, numNewValidators int, err error) {
   431  	updatedTotalVotingPower = vals.TotalVotingPower()
   432  
   433  	for _, valUpdate := range updates {
   434  		address := valUpdate.Address
   435  		_, val := vals.GetByAddress(address)
   436  
   437  		if val == nil {
   438  			// New validator, add its voting power the the total.
   439  			updatedTotalVotingPower += valUpdate.VotingPower
   440  			numNewValidators++
   441  		} else {
   442  			// Updated validator, add the difference in power to the total.
   443  			updatedTotalVotingPower += valUpdate.VotingPower - val.VotingPower
   444  		}
   445  
   446  		overflow := updatedTotalVotingPower > MaxTotalVotingPower
   447  
   448  		if overflow {
   449  			err = fmt.Errorf(
   450  				"failed to add/update validator %v, total voting power would exceed the max allowed %v",
   451  				valUpdate, MaxTotalVotingPower)
   452  
   453  			return 0, 0, err
   454  		}
   455  	}
   456  
   457  	return updatedTotalVotingPower, numNewValidators, nil
   458  }
   459  
   460  // Computes the proposer priority for the validators not present in the set based on 'updatedTotalVotingPower'.
   461  // Leaves unchanged the priorities of validators that are changed.
   462  //
   463  // 'updates' parameter must be a list of unique validators to be added or updated.
   464  // No changes are made to the validator set 'vals'.
   465  func computeNewPriorities(updates []*Validator, vals *ValidatorSet, updatedTotalVotingPower int64) {
   466  	for _, valUpdate := range updates {
   467  		address := valUpdate.Address
   468  		_, val := vals.GetByAddress(address)
   469  
   470  		if val == nil {
   471  			// add val
   472  			// Set ProposerPriority to -C*totalVotingPower (with C ~= 1.125) to make sure validators can't
   473  			// un-bond and then re-bond to reset their (potentially previously negative) ProposerPriority to zero.
   474  			//
   475  			// Contract: updatedVotingPower < MaxTotalVotingPower to ensure ProposerPriority does
   476  			// not exceed the bounds of int64.
   477  			//
   478  			// Compute ProposerPriority = -1.125*totalVotingPower == -(updatedVotingPower + (updatedVotingPower >> 3)).
   479  			valUpdate.ProposerPriority = -(updatedTotalVotingPower + (updatedTotalVotingPower >> 3))
   480  		} else {
   481  			valUpdate.ProposerPriority = val.ProposerPriority
   482  		}
   483  	}
   484  }
   485  
   486  // Merges the vals' validator list with the updates list.
   487  // When two elements with same address are seen, the one from updates is selected.
   488  // Expects updates to be a list of updates sorted by address with no duplicates or errors,
   489  // must have been validated with verifyUpdates() and priorities computed with computeNewPriorities().
   490  func (vals *ValidatorSet) applyUpdates(updates []*Validator) {
   491  	existing := vals.Validators
   492  	merged := make([]*Validator, len(existing)+len(updates))
   493  	i := 0
   494  
   495  	for len(existing) > 0 && len(updates) > 0 {
   496  		if bytes.Compare(existing[0].Address.Bytes(), updates[0].Address.Bytes()) < 0 { // unchanged validator
   497  			merged[i] = existing[0]
   498  			existing = existing[1:]
   499  		} else {
   500  			// Apply add or update.
   501  			merged[i] = updates[0]
   502  			if existing[0].Address == updates[0].Address {
   503  				// Validator is present in both, advance existing.
   504  				existing = existing[1:]
   505  			}
   506  
   507  			updates = updates[1:]
   508  		}
   509  		i++
   510  	}
   511  
   512  	// Add the elements which are left.
   513  	for j := 0; j < len(existing); j++ {
   514  		merged[i] = existing[j]
   515  		i++
   516  	}
   517  
   518  	// OR add updates which are left.
   519  	for j := 0; j < len(updates); j++ {
   520  		merged[i] = updates[j]
   521  		i++
   522  	}
   523  
   524  	vals.Validators = merged[:i]
   525  }
   526  
   527  // Checks that the validators to be removed are part of the validator set.
   528  // No changes are made to the validator set 'vals'.
   529  func verifyRemovals(deletes []*Validator, vals *ValidatorSet) error {
   530  	for _, valUpdate := range deletes {
   531  		address := valUpdate.Address
   532  		_, val := vals.GetByAddress(address)
   533  
   534  		if val == nil {
   535  			return fmt.Errorf("failed to find validator %X to remove", address)
   536  		}
   537  	}
   538  
   539  	if len(deletes) > len(vals.Validators) {
   540  		panic("more deletes than validators")
   541  	}
   542  
   543  	return nil
   544  }
   545  
   546  // Removes the validators specified in 'deletes' from validator set 'vals'.
   547  // Should not fail as verification has been done before.
   548  func (vals *ValidatorSet) applyRemovals(deletes []*Validator) {
   549  	existing := vals.Validators
   550  
   551  	merged := make([]*Validator, len(existing)-len(deletes))
   552  	i := 0
   553  
   554  	// Loop over deletes until we removed all of them.
   555  	for len(deletes) > 0 {
   556  		if existing[0].Address == deletes[0].Address {
   557  			deletes = deletes[1:]
   558  		} else { // Leave it in the resulting slice.
   559  			merged[i] = existing[0]
   560  			i++
   561  		}
   562  
   563  		existing = existing[1:]
   564  	}
   565  
   566  	// Add the elements which are left.
   567  	for j := 0; j < len(existing); j++ {
   568  		merged[i] = existing[j]
   569  		i++
   570  	}
   571  
   572  	vals.Validators = merged[:i]
   573  }
   574  
   575  // Main function used by UpdateWithChangeSet() and NewValidatorSet().
   576  // If 'allowDeletes' is false then delete operations (identified by validators with voting power 0)
   577  // are not allowed and will trigger an error if present in 'changes'.
   578  // The 'allowDeletes' flag is set to false by NewValidatorSet() and to true by UpdateWithChangeSet().
   579  func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes bool) error {
   580  	if len(changes) <= 0 {
   581  		return nil
   582  	}
   583  
   584  	// Check for duplicates within changes, split in 'updates' and 'deletes' lists (sorted).
   585  	updates, deletes, err := processChanges(changes)
   586  	if err != nil {
   587  		return err
   588  	}
   589  
   590  	if !allowDeletes && len(deletes) != 0 {
   591  		return fmt.Errorf("cannot process validators with voting power 0: %v", deletes)
   592  	}
   593  
   594  	// Verify that applying the 'deletes' against 'vals' will not result in error.
   595  	if err := verifyRemovals(deletes, vals); err != nil {
   596  		return err
   597  	}
   598  
   599  	// Verify that applying the 'updates' against 'vals' will not result in error.
   600  	updatedTotalVotingPower, numNewValidators, err := verifyUpdates(updates, vals)
   601  	if err != nil {
   602  		return err
   603  	}
   604  
   605  	// Check that the resulting set will not be empty.
   606  	if numNewValidators == 0 && len(vals.Validators) == len(deletes) {
   607  		return fmt.Errorf("applying the validator changes would result in empty set")
   608  	}
   609  
   610  	// Compute the priorities for updates.
   611  	computeNewPriorities(updates, vals, updatedTotalVotingPower)
   612  
   613  	// Apply updates and removals.
   614  	vals.updateValidators(updates, deletes)
   615  
   616  	if err := vals.UpdateTotalVotingPower(); err != nil {
   617  		return err
   618  	}
   619  
   620  	// Scale and center.
   621  	vals.RescalePriorities(PriorityWindowSizeFactor * vals.TotalVotingPower())
   622  	vals.shiftByAvgProposerPriority()
   623  
   624  	return nil
   625  }
   626  
   627  func (vals *ValidatorSet) updateValidators(updates []*Validator, deletes []*Validator) {
   628  	vals.applyUpdates(updates)
   629  	vals.applyRemovals(deletes)
   630  
   631  	vals.UpdateValidatorMap()
   632  }
   633  
   634  func (vals *ValidatorSet) UpdateValidatorMap() {
   635  	vals.validatorsMap = make(map[common.Address]int, len(vals.Validators))
   636  
   637  	for i, val := range vals.Validators {
   638  		vals.validatorsMap[val.Address] = i
   639  	}
   640  }
   641  
   642  // UpdateWithChangeSet attempts to update the validator set with 'changes'.
   643  // It performs the following steps:
   644  //   - validates the changes making sure there are no duplicates and splits them in updates and deletes
   645  //   - verifies that applying the changes will not result in errors
   646  //   - computes the total voting power BEFORE removals to ensure that in the next steps the priorities
   647  //     across old and newly added validators are fair
   648  //   - computes the priorities of new validators against the final set
   649  //   - applies the updates against the validator set
   650  //   - applies the removals against the validator set
   651  //   - performs scaling and centering of priority values
   652  //
   653  // If an error is detected during verification steps, it is returned and the validator set
   654  // is not changed.
   655  func (vals *ValidatorSet) UpdateWithChangeSet(changes []*Validator) error {
   656  	return vals.updateWithChangeSet(changes, true)
   657  }
   658  
   659  //-----------------
   660  // ErrTooMuchChange
   661  
   662  func IsErrTooMuchChange(err error) bool {
   663  	switch err.(type) {
   664  	case tooMuchChangeError:
   665  		return true
   666  	default:
   667  		return false
   668  	}
   669  }
   670  
   671  type tooMuchChangeError struct {
   672  	got    int64
   673  	needed int64
   674  }
   675  
   676  func (e tooMuchChangeError) Error() string {
   677  	return fmt.Sprintf("Invalid commit -- insufficient old voting power: got %v, needed %v", e.got, e.needed)
   678  }
   679  
   680  //----------------
   681  
   682  func (vals *ValidatorSet) String() string {
   683  	return vals.StringIndented("")
   684  }
   685  
   686  func (vals *ValidatorSet) StringIndented(indent string) string {
   687  	if vals == nil {
   688  		return "nil-ValidatorSet"
   689  	}
   690  
   691  	valStrings := make([]string, 0, len(vals.Validators))
   692  
   693  	vals.Iterate(func(index int, val *Validator) bool {
   694  		valStrings = append(valStrings, val.String())
   695  		return false
   696  	})
   697  
   698  	return fmt.Sprintf(`ValidatorSet{
   699  %s  Proposer: %v
   700  %s  Validators:
   701  %s    %v
   702  %s}`,
   703  		indent, vals.GetProposer().String(),
   704  		indent,
   705  		indent, strings.Join(valStrings, "\n"+indent+"    "),
   706  		indent)
   707  }
   708  
   709  func (vals *ValidatorSet) SetTotalVotingPower(totalVotingPower int64) {
   710  	vals.totalVotingPower = totalVotingPower
   711  }
   712  
   713  func (vals *ValidatorSet) SetMap(validatorsMap map[common.Address]int) {
   714  	vals.validatorsMap = validatorsMap
   715  }
   716  
   717  //-------------------------------------
   718  // Implements sort for sorting validators by address.
   719  
   720  // Sort validators by address.
   721  type ValidatorsByAddress []*Validator
   722  
   723  func (valz ValidatorsByAddress) Len() int {
   724  	return len(valz)
   725  }
   726  
   727  func (valz ValidatorsByAddress) Less(i, j int) bool {
   728  	return bytes.Compare(valz[i].Address.Bytes(), valz[j].Address.Bytes()) == -1
   729  }
   730  
   731  func (valz ValidatorsByAddress) Swap(i, j int) {
   732  	it := valz[i]
   733  	valz[i] = valz[j]
   734  	valz[j] = it
   735  }
   736  
   737  ///////////////////////////////////////////////////////////////////////////////
   738  // safe addition/subtraction
   739  
   740  func safeAdd(a, b int64) (int64, bool) {
   741  	if b > 0 && a > math.MaxInt64-b {
   742  		return -1, true
   743  	} else if b < 0 && a < math.MinInt64-b {
   744  		return -1, true
   745  	}
   746  
   747  	return a + b, false
   748  }
   749  
   750  func safeSub(a, b int64) (int64, bool) {
   751  	if b > 0 && a < math.MinInt64+b {
   752  		return -1, true
   753  	} else if b < 0 && a > math.MaxInt64+b {
   754  		return -1, true
   755  	}
   756  
   757  	return a - b, false
   758  }
   759  
   760  func safeAddClip(a, b int64) int64 {
   761  	c, overflow := safeAdd(a, b)
   762  	if overflow {
   763  		if b < 0 {
   764  			return math.MinInt64
   765  		}
   766  
   767  		return math.MaxInt64
   768  	}
   769  
   770  	return c
   771  }
   772  
   773  func safeSubClip(a, b int64) int64 {
   774  	c, overflow := safeSub(a, b)
   775  	if overflow {
   776  		if b > 0 {
   777  			return math.MinInt64
   778  		}
   779  
   780  		return math.MaxInt64
   781  	}
   782  
   783  	return c
   784  }