github.com/bloxroute-labs/bor@v0.1.4/consensus/bor/validator_set.go (about)

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