github.com/adoriasoft/tendermint@v0.34.0-dev1.0.20200722151356-96d84601a75a/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 if len(vals.Validators) == 0 { 349 return nil 350 } 351 bzs := make([][]byte, len(vals.Validators)) 352 for i, val := range vals.Validators { 353 bzs[i] = val.Bytes() 354 } 355 return merkle.HashFromByteSlices(bzs) 356 } 357 358 // Iterate will run the given function over the set. 359 func (vals *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { 360 for i, val := range vals.Validators { 361 stop := fn(i, val.Copy()) 362 if stop { 363 break 364 } 365 } 366 } 367 368 // Checks changes against duplicates, splits the changes in updates and 369 // removals, sorts them by address. 370 // 371 // Returns: 372 // updates, removals - the sorted lists of updates and removals 373 // err - non-nil if duplicate entries or entries with negative voting power are seen 374 // 375 // No changes are made to 'origChanges'. 376 func processChanges(origChanges []*Validator) (updates, removals []*Validator, err error) { 377 // Make a deep copy of the changes and sort by address. 378 changes := validatorListCopy(origChanges) 379 sort.Sort(ValidatorsByAddress(changes)) 380 381 removals = make([]*Validator, 0, len(changes)) 382 updates = make([]*Validator, 0, len(changes)) 383 var prevAddr Address 384 385 // Scan changes by address and append valid validators to updates or removals lists. 386 for _, valUpdate := range changes { 387 if bytes.Equal(valUpdate.Address, prevAddr) { 388 err = fmt.Errorf("duplicate entry %v in %v", valUpdate, changes) 389 return nil, nil, err 390 } 391 392 switch { 393 case valUpdate.VotingPower < 0: 394 err = fmt.Errorf("voting power can't be negative: %d", valUpdate.VotingPower) 395 return nil, nil, err 396 case valUpdate.VotingPower > MaxTotalVotingPower: 397 err = fmt.Errorf("to prevent clipping/overflow, voting power can't be higher than %d, got %d", 398 MaxTotalVotingPower, valUpdate.VotingPower) 399 return nil, nil, err 400 case valUpdate.VotingPower == 0: 401 removals = append(removals, valUpdate) 402 default: 403 updates = append(updates, valUpdate) 404 } 405 406 prevAddr = valUpdate.Address 407 } 408 409 return updates, removals, err 410 } 411 412 // verifyUpdates verifies a list of updates against a validator set, making sure the allowed 413 // total voting power would not be exceeded if these updates would be applied to the set. 414 // 415 // Inputs: 416 // updates - a list of proper validator changes, i.e. they have been verified by processChanges for duplicates 417 // and invalid values. 418 // vals - the original validator set. Note that vals is NOT modified by this function. 419 // removedPower - the total voting power that will be removed after the updates are verified and applied. 420 // 421 // Returns: 422 // tvpAfterUpdatesBeforeRemovals - the new total voting power if these updates would be applied without the removals. 423 // Note that this will be < 2 * MaxTotalVotingPower in case high power validators are removed and 424 // validators are added/ updated with high power values. 425 // 426 // err - non-nil if the maximum allowed total voting power would be exceeded 427 func verifyUpdates( 428 updates []*Validator, 429 vals *ValidatorSet, 430 removedPower int64, 431 ) (tvpAfterUpdatesBeforeRemovals int64, err error) { 432 433 delta := func(update *Validator, vals *ValidatorSet) int64 { 434 _, val := vals.GetByAddress(update.Address) 435 if val != nil { 436 return update.VotingPower - val.VotingPower 437 } 438 return update.VotingPower 439 } 440 441 updatesCopy := validatorListCopy(updates) 442 sort.Slice(updatesCopy, func(i, j int) bool { 443 return delta(updatesCopy[i], vals) < delta(updatesCopy[j], vals) 444 }) 445 446 tvpAfterRemovals := vals.TotalVotingPower() - removedPower 447 for _, upd := range updatesCopy { 448 tvpAfterRemovals += delta(upd, vals) 449 if tvpAfterRemovals > MaxTotalVotingPower { 450 return 0, ErrTotalVotingPowerOverflow 451 } 452 } 453 return tvpAfterRemovals + removedPower, nil 454 } 455 456 func numNewValidators(updates []*Validator, vals *ValidatorSet) int { 457 numNewValidators := 0 458 for _, valUpdate := range updates { 459 if !vals.HasAddress(valUpdate.Address) { 460 numNewValidators++ 461 } 462 } 463 return numNewValidators 464 } 465 466 // computeNewPriorities computes the proposer priority for the validators not present in the set based on 467 // 'updatedTotalVotingPower'. 468 // Leaves unchanged the priorities of validators that are changed. 469 // 470 // 'updates' parameter must be a list of unique validators to be added or updated. 471 // 472 // 'updatedTotalVotingPower' is the total voting power of a set where all updates would be applied but 473 // not the removals. It must be < 2*MaxTotalVotingPower and may be close to this limit if close to 474 // MaxTotalVotingPower will be removed. This is still safe from overflow since MaxTotalVotingPower is maxInt64/8. 475 // 476 // No changes are made to the validator set 'vals'. 477 func computeNewPriorities(updates []*Validator, vals *ValidatorSet, updatedTotalVotingPower int64) { 478 for _, valUpdate := range updates { 479 address := valUpdate.Address 480 _, val := vals.GetByAddress(address) 481 if val == nil { 482 // add val 483 // Set ProposerPriority to -C*totalVotingPower (with C ~= 1.125) to make sure validators can't 484 // un-bond and then re-bond to reset their (potentially previously negative) ProposerPriority to zero. 485 // 486 // Contract: updatedVotingPower < 2 * MaxTotalVotingPower to ensure ProposerPriority does 487 // not exceed the bounds of int64. 488 // 489 // Compute ProposerPriority = -1.125*totalVotingPower == -(updatedVotingPower + (updatedVotingPower >> 3)). 490 valUpdate.ProposerPriority = -(updatedTotalVotingPower + (updatedTotalVotingPower >> 3)) 491 } else { 492 valUpdate.ProposerPriority = val.ProposerPriority 493 } 494 } 495 496 } 497 498 // Merges the vals' validator list with the updates list. 499 // When two elements with same address are seen, the one from updates is selected. 500 // Expects updates to be a list of updates sorted by address with no duplicates or errors, 501 // must have been validated with verifyUpdates() and priorities computed with computeNewPriorities(). 502 func (vals *ValidatorSet) applyUpdates(updates []*Validator) { 503 existing := vals.Validators 504 sort.Sort(ValidatorsByAddress(existing)) 505 506 merged := make([]*Validator, len(existing)+len(updates)) 507 i := 0 508 509 for len(existing) > 0 && len(updates) > 0 { 510 if bytes.Compare(existing[0].Address, updates[0].Address) < 0 { // unchanged validator 511 merged[i] = existing[0] 512 existing = existing[1:] 513 } else { 514 // Apply add or update. 515 merged[i] = updates[0] 516 if bytes.Equal(existing[0].Address, updates[0].Address) { 517 // Validator is present in both, advance existing. 518 existing = existing[1:] 519 } 520 updates = updates[1:] 521 } 522 i++ 523 } 524 525 // Add the elements which are left. 526 for j := 0; j < len(existing); j++ { 527 merged[i] = existing[j] 528 i++ 529 } 530 // OR add updates which are left. 531 for j := 0; j < len(updates); j++ { 532 merged[i] = updates[j] 533 i++ 534 } 535 536 vals.Validators = merged[:i] 537 } 538 539 // Checks that the validators to be removed are part of the validator set. 540 // No changes are made to the validator set 'vals'. 541 func verifyRemovals(deletes []*Validator, vals *ValidatorSet) (votingPower int64, err error) { 542 removedVotingPower := int64(0) 543 for _, valUpdate := range deletes { 544 address := valUpdate.Address 545 _, val := vals.GetByAddress(address) 546 if val == nil { 547 return removedVotingPower, fmt.Errorf("failed to find validator %X to remove", address) 548 } 549 removedVotingPower += val.VotingPower 550 } 551 if len(deletes) > len(vals.Validators) { 552 panic("more deletes than validators") 553 } 554 return removedVotingPower, nil 555 } 556 557 // Removes the validators specified in 'deletes' from validator set 'vals'. 558 // Should not fail as verification has been done before. 559 // Expects vals to be sorted by address (done by applyUpdates). 560 func (vals *ValidatorSet) applyRemovals(deletes []*Validator) { 561 existing := vals.Validators 562 563 merged := make([]*Validator, len(existing)-len(deletes)) 564 i := 0 565 566 // Loop over deletes until we removed all of them. 567 for len(deletes) > 0 { 568 if bytes.Equal(existing[0].Address, deletes[0].Address) { 569 deletes = deletes[1:] 570 } else { // Leave it in the resulting slice. 571 merged[i] = existing[0] 572 i++ 573 } 574 existing = existing[1:] 575 } 576 577 // Add the elements which are left. 578 for j := 0; j < len(existing); j++ { 579 merged[i] = existing[j] 580 i++ 581 } 582 583 vals.Validators = merged[:i] 584 } 585 586 // Main function used by UpdateWithChangeSet() and NewValidatorSet(). 587 // If 'allowDeletes' is false then delete operations (identified by validators with voting power 0) 588 // are not allowed and will trigger an error if present in 'changes'. 589 // The 'allowDeletes' flag is set to false by NewValidatorSet() and to true by UpdateWithChangeSet(). 590 func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes bool) error { 591 if len(changes) == 0 { 592 return nil 593 } 594 595 // Check for duplicates within changes, split in 'updates' and 'deletes' lists (sorted). 596 updates, deletes, err := processChanges(changes) 597 if err != nil { 598 return err 599 } 600 601 if !allowDeletes && len(deletes) != 0 { 602 return fmt.Errorf("cannot process validators with voting power 0: %v", deletes) 603 } 604 605 // Check that the resulting set will not be empty. 606 if numNewValidators(updates, vals) == 0 && len(vals.Validators) == len(deletes) { 607 return errors.New("applying the validator changes would result in empty set") 608 } 609 610 // Verify that applying the 'deletes' against 'vals' will not result in error. 611 // Get the voting power that is going to be removed. 612 removedVotingPower, err := verifyRemovals(deletes, vals) 613 if err != nil { 614 return err 615 } 616 617 // Verify that applying the 'updates' against 'vals' will not result in error. 618 // Get the updated total voting power before removal. Note that this is < 2 * MaxTotalVotingPower 619 tvpAfterUpdatesBeforeRemovals, err := verifyUpdates(updates, vals, removedVotingPower) 620 if err != nil { 621 return err 622 } 623 624 // Compute the priorities for updates. 625 computeNewPriorities(updates, vals, tvpAfterUpdatesBeforeRemovals) 626 627 // Apply updates and removals. 628 vals.applyUpdates(updates) 629 vals.applyRemovals(deletes) 630 631 vals.updateTotalVotingPower() // will panic if total voting power > MaxTotalVotingPower 632 633 // Scale and center. 634 vals.RescalePriorities(PriorityWindowSizeFactor * vals.TotalVotingPower()) 635 vals.shiftByAvgProposerPriority() 636 637 sort.Sort(ValidatorsByVotingPower(vals.Validators)) 638 639 return nil 640 } 641 642 // UpdateWithChangeSet attempts to update the validator set with 'changes'. 643 // It performs the following steps: 644 // - validates the changes making sure there are no duplicates and splits them in updates and deletes 645 // - verifies that applying the changes will not result in errors 646 // - computes the total voting power BEFORE removals to ensure that in the next steps the priorities 647 // across old and newly added validators are fair 648 // - computes the priorities of new validators against the final set 649 // - applies the updates against the validator set 650 // - applies the removals against the validator set 651 // - performs scaling and centering of priority values 652 // If an error is detected during verification steps, it is returned and the validator set 653 // is not changed. 654 func (vals *ValidatorSet) UpdateWithChangeSet(changes []*Validator) error { 655 return vals.updateWithChangeSet(changes, true) 656 } 657 658 // VerifyCommit verifies +2/3 of the set had signed the given commit. 659 // 660 // It checks all the signatures! While it's safe to exit as soon as we have 661 // 2/3+ signatures, doing so would impact incentivization logic in the ABCI 662 // application that depends on the LastCommitInfo sent in BeginBlock, which 663 // includes which validators signed. For instance, Gaia incentivizes proposers 664 // with a bonus for including more than +2/3 of the signatures. 665 func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, 666 height int64, commit *Commit) error { 667 668 if vals.Size() != len(commit.Signatures) { 669 return NewErrInvalidCommitSignatures(vals.Size(), len(commit.Signatures)) 670 } 671 672 // Validate Height and BlockID. 673 if height != commit.Height { 674 return NewErrInvalidCommitHeight(height, commit.Height) 675 } 676 if !blockID.Equals(commit.BlockID) { 677 return fmt.Errorf("invalid commit -- wrong block ID: want %v, got %v", 678 blockID, commit.BlockID) 679 } 680 681 talliedVotingPower := int64(0) 682 votingPowerNeeded := vals.TotalVotingPower() * 2 / 3 683 for idx, commitSig := range commit.Signatures { 684 if commitSig.Absent() { 685 continue // OK, some signatures can be absent. 686 } 687 688 // The vals and commit have a 1-to-1 correspondance. 689 // This means we don't need the validator address or to do any lookup. 690 val := vals.Validators[idx] 691 692 // Validate signature. 693 voteSignBytes := commit.VoteSignBytes(chainID, int32(idx)) 694 if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) { 695 return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature) 696 } 697 // Good! 698 if commitSig.ForBlock() { 699 talliedVotingPower += val.VotingPower 700 } 701 // else { 702 // It's OK. We include stray signatures (~votes for nil) to measure 703 // validator availability. 704 // } 705 } 706 707 if got, needed := talliedVotingPower, votingPowerNeeded; got <= needed { 708 return ErrNotEnoughVotingPowerSigned{Got: got, Needed: needed} 709 } 710 711 return nil 712 } 713 714 /////////////////////////////////////////////////////////////////////////////// 715 // LIGHT CLIENT VERIFICATION METHODS 716 /////////////////////////////////////////////////////////////////////////////// 717 718 // VerifyCommitLight verifies +2/3 of the set had signed the given commit. 719 // 720 // This method is primarily used by the light client and does not check all the 721 // signatures. 722 func (vals *ValidatorSet) VerifyCommitLight(chainID string, blockID BlockID, 723 height int64, commit *Commit) error { 724 725 if vals.Size() != len(commit.Signatures) { 726 return NewErrInvalidCommitSignatures(vals.Size(), len(commit.Signatures)) 727 } 728 729 // Validate Height and BlockID. 730 if height != commit.Height { 731 return NewErrInvalidCommitHeight(height, commit.Height) 732 } 733 if !blockID.Equals(commit.BlockID) { 734 return fmt.Errorf("invalid commit -- wrong block ID: want %v, got %v", 735 blockID, commit.BlockID) 736 } 737 738 talliedVotingPower := int64(0) 739 votingPowerNeeded := vals.TotalVotingPower() * 2 / 3 740 for idx, commitSig := range commit.Signatures { 741 // No need to verify absent or nil votes. 742 if !commitSig.ForBlock() { 743 continue 744 } 745 746 // The vals and commit have a 1-to-1 correspondance. 747 // This means we don't need the validator address or to do any lookup. 748 val := vals.Validators[idx] 749 750 // Validate signature. 751 voteSignBytes := commit.VoteSignBytes(chainID, int32(idx)) 752 if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) { 753 return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature) 754 } 755 756 talliedVotingPower += val.VotingPower 757 758 // return as soon as +2/3 of the signatures are verified 759 if talliedVotingPower > votingPowerNeeded { 760 return nil 761 } 762 } 763 764 return ErrNotEnoughVotingPowerSigned{Got: talliedVotingPower, Needed: votingPowerNeeded} 765 } 766 767 // VerifyCommitLightTrusting verifies that trustLevel of the validator set signed 768 // this commit. 769 // 770 // NOTE the given validators do not necessarily correspond to the validator set 771 // for this commit, but there may be some intersection. 772 // 773 // This method is primarily used by the light client and does not check all the 774 // signatures. 775 func (vals *ValidatorSet) VerifyCommitLightTrusting(chainID string, commit *Commit, trustLevel tmmath.Fraction) error { 776 // sanity check 777 if trustLevel.Denominator == 0 { 778 return errors.New("trustLevel has zero Denominator") 779 } 780 781 var ( 782 talliedVotingPower int64 783 seenVals = make(map[int32]int, len(commit.Signatures)) // validator index -> commit index 784 ) 785 786 // Safely calculate voting power needed. 787 totalVotingPowerMulByNumerator, overflow := safeMul(vals.TotalVotingPower(), trustLevel.Numerator) 788 if overflow { 789 return errors.New("int64 overflow while calculating voting power needed. please provide smaller trustLevel numerator") 790 } 791 votingPowerNeeded := totalVotingPowerMulByNumerator / trustLevel.Denominator 792 793 for idx, commitSig := range commit.Signatures { 794 // No need to verify absent or nil votes. 795 if !commitSig.ForBlock() { 796 continue 797 } 798 799 // We don't know the validators that committed this block, so we have to 800 // check for each vote if its validator is already known. 801 valIdx, val := vals.GetByAddress(commitSig.ValidatorAddress) 802 803 if val != nil { 804 // check for double vote of validator on the same commit 805 if firstIndex, ok := seenVals[valIdx]; ok { 806 secondIndex := idx 807 return fmt.Errorf("double vote from %v (%d and %d)", val, firstIndex, secondIndex) 808 } 809 seenVals[valIdx] = idx 810 811 // Validate signature. 812 voteSignBytes := commit.VoteSignBytes(chainID, int32(idx)) 813 if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) { 814 return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature) 815 } 816 817 talliedVotingPower += val.VotingPower 818 819 if talliedVotingPower > votingPowerNeeded { 820 return nil 821 } 822 } 823 } 824 825 return ErrNotEnoughVotingPowerSigned{Got: talliedVotingPower, Needed: votingPowerNeeded} 826 } 827 828 //----------------- 829 830 // IsErrNotEnoughVotingPowerSigned returns true if err is 831 // ErrNotEnoughVotingPowerSigned. 832 func IsErrNotEnoughVotingPowerSigned(err error) bool { 833 return errors.As(err, &ErrNotEnoughVotingPowerSigned{}) 834 } 835 836 // ErrNotEnoughVotingPowerSigned is returned when not enough validators signed 837 // a commit. 838 type ErrNotEnoughVotingPowerSigned struct { 839 Got int64 840 Needed int64 841 } 842 843 func (e ErrNotEnoughVotingPowerSigned) Error() string { 844 return fmt.Sprintf("invalid commit -- insufficient voting power: got %d, needed more than %d", e.Got, e.Needed) 845 } 846 847 //---------------- 848 849 func (vals *ValidatorSet) String() string { 850 return vals.StringIndented("") 851 } 852 853 // StringIndented returns an intended string representation of ValidatorSet. 854 func (vals *ValidatorSet) StringIndented(indent string) string { 855 if vals == nil { 856 return "nil-ValidatorSet" 857 } 858 var valStrings []string 859 vals.Iterate(func(index int, val *Validator) bool { 860 valStrings = append(valStrings, val.String()) 861 return false 862 }) 863 return fmt.Sprintf(`ValidatorSet{ 864 %s Proposer: %v 865 %s Validators: 866 %s %v 867 %s}`, 868 indent, vals.GetProposer().String(), 869 indent, 870 indent, strings.Join(valStrings, "\n"+indent+" "), 871 indent) 872 873 } 874 875 //------------------------------------- 876 877 // ValidatorsByVotingPower implements sort.Interface for []*Validator based on 878 // the VotingPower and Address fields. 879 type ValidatorsByVotingPower []*Validator 880 881 func (valz ValidatorsByVotingPower) Len() int { return len(valz) } 882 883 func (valz ValidatorsByVotingPower) Less(i, j int) bool { 884 if valz[i].VotingPower == valz[j].VotingPower { 885 return bytes.Compare(valz[i].Address, valz[j].Address) == -1 886 } 887 return valz[i].VotingPower > valz[j].VotingPower 888 } 889 890 func (valz ValidatorsByVotingPower) Swap(i, j int) { 891 valz[i], valz[j] = valz[j], valz[i] 892 } 893 894 // ValidatorsByAddress implements sort.Interface for []*Validator based on 895 // the Address field. 896 type ValidatorsByAddress []*Validator 897 898 func (valz ValidatorsByAddress) Len() int { return len(valz) } 899 900 func (valz ValidatorsByAddress) Less(i, j int) bool { 901 return bytes.Compare(valz[i].Address, valz[j].Address) == -1 902 } 903 904 func (valz ValidatorsByAddress) Swap(i, j int) { 905 valz[i], valz[j] = valz[j], valz[i] 906 } 907 908 // ToProto converts ValidatorSet to protobuf 909 func (vals *ValidatorSet) ToProto() (*tmproto.ValidatorSet, error) { 910 if vals == nil { 911 return nil, errors.New("nil validator set") // validator set should never be nil 912 } 913 if err := vals.ValidateBasic(); err != nil { 914 return nil, fmt.Errorf("validator set failed basic: %w", err) 915 } 916 vp := new(tmproto.ValidatorSet) 917 valsProto := make([]*tmproto.Validator, len(vals.Validators)) 918 for i := 0; i < len(vals.Validators); i++ { 919 valp, err := vals.Validators[i].ToProto() 920 if err != nil { 921 return nil, err 922 } 923 valsProto[i] = valp 924 } 925 vp.Validators = valsProto 926 927 valProposer, err := vals.Proposer.ToProto() 928 if err != nil { 929 return nil, fmt.Errorf("toProto: validatorSet proposer error: %w", err) 930 } 931 vp.Proposer = valProposer 932 933 vp.TotalVotingPower = vals.totalVotingPower 934 935 return vp, nil 936 } 937 938 // ValidatorSetFromProto sets a protobuf ValidatorSet to the given pointer. 939 // It returns an error if any of the validators from the set or the proposer 940 // is invalid 941 func ValidatorSetFromProto(vp *tmproto.ValidatorSet) (*ValidatorSet, error) { 942 if vp == nil { 943 return nil, errors.New("nil validator set") // validator set should never be nil, bigger issues are at play if empty 944 } 945 vals := new(ValidatorSet) 946 947 valsProto := make([]*Validator, len(vp.Validators)) 948 for i := 0; i < len(vp.Validators); i++ { 949 v, err := ValidatorFromProto(vp.Validators[i]) 950 if err != nil { 951 return nil, err 952 } 953 valsProto[i] = v 954 } 955 vals.Validators = valsProto 956 957 p, err := ValidatorFromProto(vp.GetProposer()) 958 if err != nil { 959 return nil, fmt.Errorf("fromProto: validatorSet proposer error: %w", err) 960 } 961 962 vals.Proposer = p 963 964 vals.totalVotingPower = vp.GetTotalVotingPower() 965 966 return vals, nil 967 } 968 969 //---------------------------------------- 970 971 // RandValidatorSet returns a randomized validator set (size: +numValidators+), 972 // where each validator has a voting power of +votingPower+. 973 // 974 // EXPOSED FOR TESTING. 975 func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) { 976 var ( 977 valz = make([]*Validator, numValidators) 978 privValidators = make([]PrivValidator, numValidators) 979 ) 980 981 for i := 0; i < numValidators; i++ { 982 val, privValidator := RandValidator(false, votingPower) 983 valz[i] = val 984 privValidators[i] = privValidator 985 } 986 987 sort.Sort(PrivValidatorsByAddress(privValidators)) 988 989 return NewValidatorSet(valz), privValidators 990 } 991 992 /////////////////////////////////////////////////////////////////////////////// 993 // safe addition/subtraction/multiplication 994 995 func safeAdd(a, b int64) (int64, bool) { 996 if b > 0 && a > math.MaxInt64-b { 997 return -1, true 998 } else if b < 0 && a < math.MinInt64-b { 999 return -1, true 1000 } 1001 return a + b, false 1002 } 1003 1004 func safeSub(a, b int64) (int64, bool) { 1005 if b > 0 && a < math.MinInt64+b { 1006 return -1, true 1007 } else if b < 0 && a > math.MaxInt64+b { 1008 return -1, true 1009 } 1010 return a - b, false 1011 } 1012 1013 func safeAddClip(a, b int64) int64 { 1014 c, overflow := safeAdd(a, b) 1015 if overflow { 1016 if b < 0 { 1017 return math.MinInt64 1018 } 1019 return math.MaxInt64 1020 } 1021 return c 1022 } 1023 1024 func safeSubClip(a, b int64) int64 { 1025 c, overflow := safeSub(a, b) 1026 if overflow { 1027 if b > 0 { 1028 return math.MinInt64 1029 } 1030 return math.MaxInt64 1031 } 1032 return c 1033 } 1034 1035 func safeMul(a, b int64) (int64, bool) { 1036 if a == 0 || b == 0 { 1037 return 0, false 1038 } 1039 1040 absOfB := b 1041 if b < 0 { 1042 absOfB = -b 1043 } 1044 1045 absOfA := a 1046 if a < 0 { 1047 absOfA = -a 1048 } 1049 1050 if absOfA > math.MaxInt64/absOfB { 1051 return 0, true 1052 } 1053 1054 return a * b, false 1055 }