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