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