github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/types/validator_set.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "github.com/tendermint/tendermint/crypto/tmhash" 8 "math" 9 "math/big" 10 "sort" 11 "strings" 12 "time" 13 14 "github.com/pkg/errors" 15 16 "github.com/tendermint/tendermint/crypto/merkle" 17 tmmath "github.com/tendermint/tendermint/libs/math" 18 tmproto "github.com/tendermint/tendermint/proto/types" 19 ) 20 21 const ( 22 // MaxTotalVotingPower - the maximum allowed total voting power. 23 // It needs to be sufficiently small to, in all cases: 24 // 1. prevent clipping in incrementProposerPriority() 25 // 2. let (diff+diffMax-1) not overflow in IncrementProposerPriority() 26 // (Proof of 1 is tricky, left to the reader). 27 // It could be higher, but this is sufficiently large for our purposes, 28 // and leaves room for defensive purposes. 29 MaxTotalVotingPower = int64(math.MaxInt64) / 8 30 31 // PriorityWindowSizeFactor - is a constant that when multiplied with the total voting power gives 32 // the maximum allowed distance between validator priorities. 33 PriorityWindowSizeFactor = 2 34 ) 35 36 // ValidatorSet represent a set of *Validator at a given height. 37 // The validators can be fetched by address or index. 38 // The index is in order of .Address, so the indices are fixed 39 // for all rounds of a given blockchain height - ie. the validators 40 // are sorted by their address. 41 // On the other hand, the .ProposerPriority of each validator and 42 // the designated .GetProposer() of a set changes every round, 43 // upon calling .IncrementProposerPriority(). 44 // NOTE: Not goroutine-safe. 45 // NOTE: All get/set to validators should copy the value for safety. 46 type ValidatorSet struct { 47 // NOTE: persisted via reflect, must be exported. 48 Validators []*Validator `json:"validators"` 49 Proposer *Validator `json:"proposer"` 50 51 // cached (unexported) 52 totalVotingPower int64 53 } 54 55 // NewValidatorSet initializes a ValidatorSet by copying over the 56 // values from `valz`, a list of Validators. If valz is nil or empty, 57 // the new ValidatorSet will have an empty list of Validators. 58 // The addresses of validators in `valz` must be unique otherwise the 59 // function panics. 60 // Note the validator set size has an implied limit equal to that of the MaxVotesCount - 61 // commits by a validator set larger than this will fail validation. 62 func NewValidatorSet(valz []*Validator) *ValidatorSet { 63 vals := &ValidatorSet{} 64 err := vals.updateWithChangeSet(valz, false) 65 if err != nil { 66 panic(fmt.Sprintf("cannot create validator set: %s", err)) 67 } 68 if len(valz) > 0 { 69 vals.IncrementProposerPriority(1) 70 } 71 return vals 72 } 73 74 // IsNilOrEmpty returns true if validator set is nil or empty. 75 func (vals *ValidatorSet) IsNilOrEmpty() bool { 76 return vals == nil || len(vals.Validators) == 0 77 } 78 79 // CopyIncrementProposerPriority increments ProposerPriority and updates the 80 // proposer on a copy, and returns it. 81 func (vals *ValidatorSet) CopyIncrementProposerPriority(times int) *ValidatorSet { 82 copy := vals.Copy() 83 copy.IncrementProposerPriority(times) 84 return copy 85 } 86 87 // IncrementProposerPriority increments ProposerPriority of each validator and updates the 88 // proposer. Panics if validator set is empty. 89 // `times` must be positive. 90 func (vals *ValidatorSet) IncrementProposerPriority(times int) { 91 if vals.IsNilOrEmpty() { 92 panic("empty validator set") 93 } 94 if times <= 0 { 95 panic("Cannot call IncrementProposerPriority with non-positive times") 96 } 97 98 // Cap the difference between priorities to be proportional to 2*totalPower by 99 // re-normalizing priorities, i.e., rescale all priorities by multiplying with: 100 // 2*totalVotingPower/(maxPriority - minPriority) 101 diffMax := PriorityWindowSizeFactor * vals.TotalVotingPower() 102 vals.RescalePriorities(diffMax) 103 vals.shiftByAvgProposerPriority() 104 105 // Call IncrementProposerPriority(1) times times. 106 for i := 0; i < times; i++ { 107 vals.incrementProposerPriority(vals.Hash(), uint64(i)) 108 } 109 vals.Proposer = nil 110 } 111 112 // RescalePriorities rescales the priorities such that the distance between the maximum and minimum 113 // is smaller than `diffMax`. 114 func (vals *ValidatorSet) RescalePriorities(diffMax int64) { 115 if vals.IsNilOrEmpty() { 116 panic("empty validator set") 117 } 118 // NOTE: This check is merely a sanity check which could be 119 // removed if all tests would init. voting power appropriately; 120 // i.e. diffMax should always be > 0 121 if diffMax <= 0 { 122 return 123 } 124 125 // Calculating ceil(diff/diffMax): 126 // Re-normalization is performed by dividing by an integer for simplicity. 127 // NOTE: This may make debugging priority issues easier as well. 128 diff := computeMaxMinPriorityDiff(vals) 129 ratio := (diff + diffMax - 1) / diffMax 130 if diff > diffMax { 131 for _, val := range vals.Validators { 132 val.ProposerPriority /= ratio 133 } 134 } 135 } 136 137 func (vals *ValidatorSet) incrementProposerPriority(hash []byte, round uint64) { 138 for _, val := range vals.Validators { 139 // Check for overflow for sum. 140 newPrio := safeAddClip(val.ProposerPriority, val.VotingPower) 141 val.ProposerPriority = newPrio 142 } 143 } 144 145 // Should not be called on an empty validator set. 146 func (vals *ValidatorSet) computeAvgProposerPriority() int64 { 147 n := int64(len(vals.Validators)) 148 sum := big.NewInt(0) 149 for _, val := range vals.Validators { 150 sum.Add(sum, big.NewInt(val.ProposerPriority)) 151 } 152 avg := sum.Div(sum, big.NewInt(n)) 153 if avg.IsInt64() { 154 return avg.Int64() 155 } 156 157 // This should never happen: each val.ProposerPriority is in bounds of int64. 158 panic(fmt.Sprintf("Cannot represent avg ProposerPriority as an int64 %v", avg)) 159 } 160 161 // Should not be called on an empty validator set. 162 func (vals *ValidatorSet) computeAvgVotingPower() int64 { 163 n := int64(len(vals.Validators)) 164 sum := big.NewInt(0) 165 for _, val := range vals.Validators { 166 sum.Add(sum, big.NewInt(val.VotingPower)) 167 } 168 avg := sum.Div(sum, big.NewInt(n)) 169 if avg.IsInt64() { 170 return avg.Int64() 171 } 172 173 // This should never happen: each val.ProposerPriority is in bounds of int64. 174 panic(fmt.Sprintf("Cannot represent avg voting power as an int64 %v", avg)) 175 } 176 177 // Compute the difference between the max and min ProposerPriority of that set. 178 func computeMaxMinPriorityDiff(vals *ValidatorSet) int64 { 179 if vals.IsNilOrEmpty() { 180 panic("empty validator set") 181 } 182 max := int64(math.MinInt64) 183 min := int64(math.MaxInt64) 184 for _, v := range vals.Validators { 185 if v.ProposerPriority < min { 186 min = v.ProposerPriority 187 } 188 if v.ProposerPriority > max { 189 max = v.ProposerPriority 190 } 191 } 192 diff := max - min 193 if diff < 0 { 194 return -1 * diff 195 } 196 return diff 197 } 198 199 func (vals *ValidatorSet) getValWithMostPriority() *Validator { 200 var res *Validator 201 for _, val := range vals.Validators { 202 res = res.CompareProposerPriority(val) 203 } 204 return res 205 } 206 207 func (vals *ValidatorSet) shiftByAvgProposerPriority() { 208 if vals.IsNilOrEmpty() { 209 panic("empty validator set") 210 } 211 avgProposerPriority := vals.computeAvgProposerPriority() 212 for _, val := range vals.Validators { 213 val.ProposerPriority = safeSubClip(val.ProposerPriority, avgProposerPriority) 214 } 215 } 216 217 // Makes a copy of the validator list. 218 func validatorListCopy(valsList []*Validator) []*Validator { 219 if valsList == nil { 220 return nil 221 } 222 valsCopy := make([]*Validator, len(valsList)) 223 for i, val := range valsList { 224 valsCopy[i] = val.Copy() 225 } 226 return valsCopy 227 } 228 229 // Copy each validator into a new ValidatorSet. 230 func (vals *ValidatorSet) Copy() *ValidatorSet { 231 return &ValidatorSet{ 232 Validators: validatorListCopy(vals.Validators), 233 Proposer: vals.Proposer, 234 totalVotingPower: vals.totalVotingPower, 235 } 236 } 237 238 // HasAddress returns true if address given is in the validator set, false - 239 // otherwise. 240 func (vals *ValidatorSet) HasAddress(address []byte) bool { 241 idx := sort.Search(len(vals.Validators), func(i int) bool { 242 return bytes.Compare(address, vals.Validators[i].Address) <= 0 243 }) 244 return idx < len(vals.Validators) && bytes.Equal(vals.Validators[idx].Address, address) 245 } 246 247 // GetByAddress returns an index of the validator with address and validator 248 // itself if found. Otherwise, -1 and nil are returned. 249 func (vals *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) { 250 idx := sort.Search(len(vals.Validators), func(i int) bool { 251 return bytes.Compare(address, vals.Validators[i].Address) <= 0 252 }) 253 if idx < len(vals.Validators) && bytes.Equal(vals.Validators[idx].Address, address) { 254 return idx, vals.Validators[idx].Copy() 255 } 256 return -1, nil 257 } 258 259 // GetByIndex returns the validator's address and validator itself by index. 260 // It returns nil values if index is less than 0 or greater or equal to 261 // len(ValidatorSet.Validators). 262 func (vals *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) { 263 if index < 0 || index >= len(vals.Validators) { 264 return nil, nil 265 } 266 val = vals.Validators[index] 267 return val.Address, val.Copy() 268 } 269 270 // Size returns the length of the validator set. 271 func (vals *ValidatorSet) Size() int { 272 return len(vals.Validators) 273 } 274 275 // Forces recalculation of the set's total voting power. 276 // Panics if total voting power is bigger than MaxTotalVotingPower. 277 func (vals *ValidatorSet) updateTotalVotingPower() { 278 279 sum := int64(0) 280 for _, val := range vals.Validators { 281 // mind overflow 282 sum = safeAddClip(sum, val.VotingPower) 283 if sum > MaxTotalVotingPower { 284 panic(fmt.Sprintf( 285 "Total voting power should be guarded to not exceed %v; got: %v", 286 MaxTotalVotingPower, 287 sum)) 288 } 289 } 290 291 vals.totalVotingPower = sum 292 } 293 294 // TotalVotingPower returns the sum of the voting powers of all validators. 295 // It recomputes the total voting power if required. 296 func (vals *ValidatorSet) TotalVotingPower() int64 { 297 if vals.totalVotingPower == 0 { 298 vals.updateTotalVotingPower() 299 } 300 return vals.totalVotingPower 301 } 302 303 // GetProposer returns the current proposer. If the validator set is empty, nil 304 // is returned. 305 func (vals *ValidatorSet) GetProposer() (proposer *Validator) { 306 if len(vals.Validators) == 0 { 307 return nil 308 } 309 if vals.Proposer == nil { 310 vals.Proposer = vals.findProposer() 311 } 312 return vals.Proposer.Copy() 313 } 314 315 func (vals *ValidatorSet) findProposer() *Validator { 316 var proposer *Validator 317 for _, val := range vals.Validators { 318 if proposer == nil || !bytes.Equal(val.Address, proposer.Address) { 319 proposer = proposer.CompareProposerPriority(val) 320 } 321 } 322 return proposer 323 } 324 325 // Pocket Network's custom addition to tendermint selection 326 func (vals *ValidatorSet) GetProposerRandomized(previousBlockHash []byte, upgradeHeight, height int64, lastCommit []byte, round uint64) *Validator { 327 roundBz := make([]byte, 8) 328 binary.LittleEndian.PutUint64(roundBz, round) 329 if upgradeHeight != 0 && height >= upgradeHeight && height < 30040 { 330 previousBlockHash = tmhash.Sum(append(append(previousBlockHash, lastCommit...), roundBz...)) 331 } else { 332 previousBlockHash = tmhash.Sum(append(previousBlockHash, roundBz...)) 333 } 334 if len(vals.Validators) == 0 { 335 return nil 336 } 337 if vals.Proposer != nil { 338 return vals.Proposer.Copy() 339 } 340 avgPower := vals.computeAvgVotingPower() 341 adjacencyMatrix := make([]int, 0) // an adjacency matrix to allow for fair proposer selection 342 for valIndex, val := range vals.Validators { 343 // append index VP times where VP is the voting power of the validator 344 proposingPower := val.VotingPower / avgPower 345 // give everyone atleast 1 ticket 346 if proposingPower == 0 { 347 proposingPower = 1 348 } 349 for j := int64(0); j < proposingPower; j++ { 350 adjacencyMatrix = append(adjacencyMatrix, valIndex) 351 } 352 } 353 // calculate the length of the adjacency matrix for a max index selection 354 maxIndex := int64(len(adjacencyMatrix)) 355 // hash for show and convert back to decimal 356 blockHashDecimal := new(big.Int).SetBytes(previousBlockHash[:8]) 357 // mod the selection 358 index := new(big.Int).Mod(blockHashDecimal, big.NewInt(maxIndex)) 359 proposerIndex := adjacencyMatrix[index.Int64()] 360 proposer := vals.Validators[proposerIndex] 361 vals.Proposer = proposer 362 return proposer.Copy() 363 } 364 365 // Hash returns the Merkle root hash build using validators (as leaves) in the 366 // set. 367 func (vals *ValidatorSet) Hash() []byte { 368 if len(vals.Validators) == 0 { 369 return nil 370 } 371 bzs := make([][]byte, len(vals.Validators)) 372 for i, val := range vals.Validators { 373 bzs[i] = val.Bytes() 374 } 375 return merkle.SimpleHashFromByteSlices(bzs) 376 } 377 378 // Iterate will run the given function over the set. 379 func (vals *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { 380 for i, val := range vals.Validators { 381 stop := fn(i, val.Copy()) 382 if stop { 383 break 384 } 385 } 386 } 387 388 // Checks changes against duplicates, splits the changes in updates and 389 // removals, sorts them by address. 390 // 391 // Returns: 392 // updates, removals - the sorted lists of updates and removals 393 // err - non-nil if duplicate entries or entries with negative voting power are seen 394 // 395 // No changes are made to 'origChanges'. 396 func processChanges(origChanges []*Validator) (updates, removals []*Validator, err error) { 397 // Make a deep copy of the changes and sort by address. 398 changes := validatorListCopy(origChanges) 399 sort.Sort(ValidatorsByAddress(changes)) 400 401 removals = make([]*Validator, 0, len(changes)) 402 updates = make([]*Validator, 0, len(changes)) 403 var prevAddr Address 404 405 // Scan changes by address and append valid validators to updates or removals lists. 406 for _, valUpdate := range changes { 407 if bytes.Equal(valUpdate.Address, prevAddr) { 408 err = fmt.Errorf("duplicate entry %v in %v", valUpdate, changes) 409 return nil, nil, err 410 } 411 412 switch { 413 case valUpdate.VotingPower < 0: 414 err = fmt.Errorf("voting power can't be negative: %d", valUpdate.VotingPower) 415 return nil, nil, err 416 case valUpdate.VotingPower > MaxTotalVotingPower: 417 err = fmt.Errorf("to prevent clipping/overflow, voting power can't be higher than %d, got %d", 418 MaxTotalVotingPower, valUpdate.VotingPower) 419 return nil, nil, err 420 case valUpdate.VotingPower == 0: 421 removals = append(removals, valUpdate) 422 default: 423 updates = append(updates, valUpdate) 424 } 425 426 prevAddr = valUpdate.Address 427 } 428 429 return updates, removals, err 430 } 431 432 // verifyUpdates verifies a list of updates against a validator set, making sure the allowed 433 // total voting power would not be exceeded if these updates would be applied to the set. 434 // 435 // Inputs: 436 // updates - a list of proper validator changes, i.e. they have been verified by processChanges for duplicates 437 // and invalid values. 438 // vals - the original validator set. Note that vals is NOT modified by this function. 439 // removedPower - the total voting power that will be removed after the updates are verified and applied. 440 // 441 // Returns: 442 // tvpAfterUpdatesBeforeRemovals - the new total voting power if these updates would be applied without the removals. 443 // Note that this will be < 2 * MaxTotalVotingPower in case high power validators are removed and 444 // validators are added/ updated with high power values. 445 // 446 // err - non-nil if the maximum allowed total voting power would be exceeded 447 func verifyUpdates( 448 updates []*Validator, 449 vals *ValidatorSet, 450 removedPower int64, 451 ) (tvpAfterUpdatesBeforeRemovals int64, err error) { 452 delta := func(update *Validator, vals *ValidatorSet) int64 { 453 _, val := vals.GetByAddress(update.Address) 454 if val != nil { 455 return update.VotingPower - val.VotingPower 456 } 457 return update.VotingPower 458 } 459 460 updatesCopy := validatorListCopy(updates) 461 sort.Slice(updatesCopy, func(i, j int) bool { 462 return delta(updatesCopy[i], vals) < delta(updatesCopy[j], vals) 463 }) 464 465 tvpAfterRemovals := vals.TotalVotingPower() - removedPower 466 for _, upd := range updatesCopy { 467 tvpAfterRemovals += delta(upd, vals) 468 if tvpAfterRemovals > MaxTotalVotingPower { 469 err = fmt.Errorf( 470 "failed to add/update validator %v, total voting power would exceed the max allowed %v", 471 upd.Address, MaxTotalVotingPower) 472 return 0, err 473 } 474 } 475 return tvpAfterRemovals + removedPower, nil 476 } 477 478 func numNewValidators(updates []*Validator, vals *ValidatorSet) int { 479 numNewValidators := 0 480 for _, valUpdate := range updates { 481 if !vals.HasAddress(valUpdate.Address) { 482 numNewValidators++ 483 } 484 } 485 return numNewValidators 486 } 487 488 // computeNewPriorities computes the proposer priority for the validators not present in the set based on 489 // 'updatedTotalVotingPower'. 490 // Leaves unchanged the priorities of validators that are changed. 491 // 492 // 'updates' parameter must be a list of unique validators to be added or updated. 493 // 494 // 'updatedTotalVotingPower' is the total voting power of a set where all updates would be applied but 495 // not the removals. It must be < 2*MaxTotalVotingPower and may be close to this limit if close to 496 // MaxTotalVotingPower will be removed. This is still safe from overflow since MaxTotalVotingPower is maxInt64/8. 497 // 498 // No changes are made to the validator set 'vals'. 499 func computeNewPriorities(updates []*Validator, vals *ValidatorSet, updatedTotalVotingPower int64) { 500 501 for _, valUpdate := range updates { 502 address := valUpdate.Address 503 _, val := vals.GetByAddress(address) 504 if val == nil { 505 // add val 506 // Set ProposerPriority to -C*totalVotingPower (with C ~= 1.125) to make sure validators can't 507 // un-bond and then re-bond to reset their (potentially previously negative) ProposerPriority to zero. 508 // 509 // Contract: updatedVotingPower < 2 * MaxTotalVotingPower to ensure ProposerPriority does 510 // not exceed the bounds of int64. 511 // 512 // Compute ProposerPriority = -1.125*totalVotingPower == -(updatedVotingPower + (updatedVotingPower >> 3)). 513 valUpdate.ProposerPriority = -(updatedTotalVotingPower + (updatedTotalVotingPower >> 3)) 514 } else { 515 valUpdate.ProposerPriority = val.ProposerPriority 516 } 517 } 518 519 } 520 521 // Merges the vals' validator list with the updates list. 522 // When two elements with same address are seen, the one from updates is selected. 523 // Expects updates to be a list of updates sorted by address with no duplicates or errors, 524 // must have been validated with verifyUpdates() and priorities computed with computeNewPriorities(). 525 func (vals *ValidatorSet) applyUpdates(updates []*Validator) { 526 527 existing := vals.Validators 528 merged := make([]*Validator, len(existing)+len(updates)) 529 i := 0 530 531 for len(existing) > 0 && len(updates) > 0 { 532 if bytes.Compare(existing[0].Address, updates[0].Address) < 0 { // unchanged validator 533 merged[i] = existing[0] 534 existing = existing[1:] 535 } else { 536 // Apply add or update. 537 merged[i] = updates[0] 538 if bytes.Equal(existing[0].Address, updates[0].Address) { 539 // Validator is present in both, advance existing. 540 existing = existing[1:] 541 } 542 updates = updates[1:] 543 } 544 i++ 545 } 546 547 // Add the elements which are left. 548 for j := 0; j < len(existing); j++ { 549 merged[i] = existing[j] 550 i++ 551 } 552 // OR add updates which are left. 553 for j := 0; j < len(updates); j++ { 554 merged[i] = updates[j] 555 i++ 556 } 557 558 vals.Validators = merged[:i] 559 } 560 561 // Checks that the validators to be removed are part of the validator set. 562 // No changes are made to the validator set 'vals'. 563 func verifyRemovals(deletes []*Validator, vals *ValidatorSet) (votingPower int64, err error) { 564 565 removedVotingPower := int64(0) 566 for _, valUpdate := range deletes { 567 address := valUpdate.Address 568 _, val := vals.GetByAddress(address) 569 if val == nil { 570 return removedVotingPower, fmt.Errorf("failed to find validator %X to remove", address) 571 } 572 removedVotingPower += val.VotingPower 573 } 574 if len(deletes) > len(vals.Validators) { 575 panic("more deletes than validators") 576 } 577 return removedVotingPower, nil 578 } 579 580 // Removes the validators specified in 'deletes' from validator set 'vals'. 581 // Should not fail as verification has been done before. 582 func (vals *ValidatorSet) applyRemovals(deletes []*Validator) { 583 584 existing := vals.Validators 585 586 merged := make([]*Validator, len(existing)-len(deletes)) 587 i := 0 588 589 // Loop over deletes until we removed all of them. 590 for len(deletes) > 0 { 591 if bytes.Equal(existing[0].Address, deletes[0].Address) { 592 deletes = deletes[1:] 593 } else { // Leave it in the resulting slice. 594 merged[i] = existing[0] 595 i++ 596 } 597 existing = existing[1:] 598 } 599 600 // Add the elements which are left. 601 for j := 0; j < len(existing); j++ { 602 merged[i] = existing[j] 603 i++ 604 } 605 606 vals.Validators = merged[:i] 607 } 608 609 // Main function used by UpdateWithChangeSet() and NewValidatorSet(). 610 // If 'allowDeletes' is false then delete operations (identified by validators with voting power 0) 611 // are not allowed and will trigger an error if present in 'changes'. 612 // The 'allowDeletes' flag is set to false by NewValidatorSet() and to true by UpdateWithChangeSet(). 613 func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes bool) error { 614 615 if len(changes) == 0 { 616 return nil 617 } 618 619 // Check for duplicates within changes, split in 'updates' and 'deletes' lists (sorted). 620 updates, deletes, err := processChanges(changes) 621 if err != nil { 622 return err 623 } 624 625 if !allowDeletes && len(deletes) != 0 { 626 return fmt.Errorf("cannot process validators with voting power 0: %v", deletes) 627 } 628 629 // Check that the resulting set will not be empty. 630 if numNewValidators(updates, vals) == 0 && len(vals.Validators) == len(deletes) { 631 return errors.New("applying the validator changes would result in empty set") 632 } 633 634 // Verify that applying the 'deletes' against 'vals' will not result in error. 635 // Get the voting power that is going to be removed. 636 removedVotingPower, err := verifyRemovals(deletes, vals) 637 if err != nil { 638 return err 639 } 640 641 // Verify that applying the 'updates' against 'vals' will not result in error. 642 // Get the updated total voting power before removal. Note that this is < 2 * MaxTotalVotingPower 643 tvpAfterUpdatesBeforeRemovals, err := verifyUpdates(updates, vals, removedVotingPower) 644 if err != nil { 645 return err 646 } 647 648 // Compute the priorities for updates. 649 computeNewPriorities(updates, vals, tvpAfterUpdatesBeforeRemovals) 650 651 // Apply updates and removals. 652 vals.applyUpdates(updates) 653 vals.applyRemovals(deletes) 654 655 vals.updateTotalVotingPower() // will panic if total voting power > MaxTotalVotingPower 656 657 // Scale and center. 658 vals.RescalePriorities(PriorityWindowSizeFactor * vals.TotalVotingPower()) 659 vals.shiftByAvgProposerPriority() 660 661 return nil 662 } 663 664 // UpdateWithChangeSet attempts to update the validator set with 'changes'. 665 // It performs the following steps: 666 // - validates the changes making sure there are no duplicates and splits them in updates and deletes 667 // - verifies that applying the changes will not result in errors 668 // - computes the total voting power BEFORE removals to ensure that in the next steps the priorities 669 // across old and newly added validators are fair 670 // - computes the priorities of new validators against the final set 671 // - applies the updates against the validator set 672 // - applies the removals against the validator set 673 // - performs scaling and centering of priority values 674 // If an error is detected during verification steps, it is returned and the validator set 675 // is not changed. 676 func (vals *ValidatorSet) UpdateWithChangeSet(changes []*Validator) error { 677 return vals.updateWithChangeSet(changes, true) 678 } 679 680 // VerifyCommit verifies +2/3 of the set had signed the given commit. 681 // 682 // It checks all the signatures! While it's safe to exit as soon as we have 683 // 2/3+ signatures, doing so would impact incentivization logic in the ABCI 684 // application that depends on the LastCommitInfo sent in BeginBlock, which 685 // includes which validators signed. For instance, Gaia incentivizes proposers 686 // with a bonus for including more than +2/3 of the signatures. 687 func (vals *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, 688 height int64, commit *Commit) error { 689 690 defer TimeTrack(time.Now(), nil) 691 692 if vals.Size() != len(commit.Precommits) { 693 return NewErrInvalidCommitSignatures(vals.Size(), len(commit.Precommits)) 694 } 695 talliedVotingPower := int64(0) 696 votingPowerNeeded := vals.TotalVotingPower() * 2 / 3 697 698 err, talliedVotingPower := verifyCommitBasicAndPower(commit, height, blockID, chainID, vals, talliedVotingPower) 699 700 if err != nil { 701 return err 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 /////////////////////////////////////////////////////////////////////////////// 712 // LIGHT CLIENT VERIFICATION METHODS 713 /////////////////////////////////////////////////////////////////////////////// 714 715 // VerifyCommitLight verifies +2/3 of the set had signed the given commit. 716 // 717 // This method is primarily used by the light client and does not check all the 718 // signatures. 719 func (vals *ValidatorSet) VerifyCommitLight(chainID string, blockID BlockID, 720 height int64, commit *Commit) error { 721 defer TimeTrack(time.Now(), nil) 722 723 if vals.Size() != len(commit.Precommits) { 724 return NewErrInvalidCommitSignatures(vals.Size(), len(commit.Precommits)) 725 } 726 727 // Validate Height and BlockID. 728 if height != commit.Height() { 729 return NewErrInvalidCommitHeight(height, commit.Height()) 730 } 731 if !blockID.Equals(commit.BlockID) { 732 return fmt.Errorf("invalid commit -- wrong block ID: want %v, got %v", 733 blockID, commit.BlockID) 734 } 735 736 talliedVotingPower := int64(0) 737 votingPowerNeeded := vals.TotalVotingPower() * 2 / 3 738 for idx, commitSig := range commit.Precommits { 739 // No need to verify absent or nil votes. 740 if commitSig == nil { 741 continue 742 } 743 744 // The vals and commit have a 1-to-1 correspondance. 745 // This means we don't need the validator address or to do any lookup. 746 val := vals.Validators[idx] 747 748 // Validate signature. 749 voteSignBytes := commit.VoteSignBytes(chainID, idx) 750 if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) { 751 return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature) 752 } 753 754 talliedVotingPower += val.VotingPower 755 756 // return as soon as +2/3 of the signatures are verified 757 if talliedVotingPower > votingPowerNeeded { 758 return nil 759 } 760 } 761 762 return ErrNotEnoughVotingPowerSigned{Got: talliedVotingPower, Needed: votingPowerNeeded} 763 } 764 765 // VerifyFutureCommit will check to see if the set would be valid with a different 766 // validator set. 767 // 768 // vals is the old validator set that we know. Over 2/3 of the power in old 769 // signed this block. 770 // 771 // In Tendermint, 1/3 of the voting power can halt or fork the chain, but 1/3 772 // can't make arbitrary state transitions. You still need > 2/3 Byzantine to 773 // make arbitrary state transitions. 774 // 775 // To preserve this property in the light client, we also require > 2/3 of the 776 // old vals to sign the future commit at H, that way we preserve the property 777 // that if they weren't being truthful about the validator set at H (block hash 778 // -> vals hash) or about the app state (block hash -> app hash) we can slash 779 // > 2/3. Otherwise, the lite client isn't providing the same security 780 // guarantees. 781 // 782 // Even if we added a slashing condition that if you sign a block header with 783 // the wrong validator set, then we would only need > 1/3 of signatures from 784 // the old vals on the new commit, it wouldn't be sufficient because the new 785 // vals can be arbitrary and commit some arbitrary app hash. 786 // 787 // newSet is the validator set that signed this block. Only votes from new are 788 // sufficient for 2/3 majority in the new set as well, for it to be a valid 789 // commit. 790 // 791 // NOTE: This doesn't check whether the commit is a future commit, because the 792 // current height isn't part of the ValidatorSet. Caller must check that the 793 // commit height is greater than the height for this validator set. 794 func (vals *ValidatorSet) VerifyFutureCommit(newSet *ValidatorSet, chainID string, 795 blockID BlockID, height int64, commit *Commit) error { 796 oldVals := vals 797 798 // Commit must be a valid commit for newSet. 799 err := newSet.VerifyCommit(chainID, blockID, height, commit) 800 if err != nil { 801 return err 802 } 803 804 // Check old voting power. 805 oldVotingPower := int64(0) 806 seen := map[int]bool{} 807 808 for idx, commitSig := range commit.Precommits { 809 if commitSig == nil { 810 continue // OK, some signatures can be absent. 811 } 812 813 // See if this validator is in oldVals. 814 oldIdx, val := oldVals.GetByAddress(commitSig.ValidatorAddress) 815 if val == nil || seen[oldIdx] { 816 continue // missing or double vote... 817 } 818 seen[oldIdx] = true 819 820 // Validate signature. 821 voteSignBytes := commit.VoteSignBytes(chainID, idx) 822 if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) { 823 return errors.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature) 824 } 825 // Good! 826 if blockID.Equals(commitSig.BlockID) { 827 oldVotingPower += val.VotingPower 828 } 829 // else { 830 // It's OK that the BlockID doesn't match. We include stray 831 // signatures (~votes for nil) to measure validator availability. 832 // } 833 } 834 835 if got, needed := oldVotingPower, oldVals.TotalVotingPower()*2/3; got <= needed { 836 return ErrNotEnoughVotingPowerSigned{Got: got, Needed: needed} 837 } 838 return nil 839 } 840 841 // VerifyCommitLightTrusting verifies that trustLevel of the validator set signed 842 // this commit. 843 // 844 // This method is primarily used by the light client and does not check all the 845 // signatures. 846 // 847 // NOTE the given validators do not necessarily correspond to the validator set 848 // for this commit, but there may be some intersection. 849 // 850 // Panics if trustLevel is invalid. 851 func (vals *ValidatorSet) VerifyCommitLightTrusting(chainID string, blockID BlockID, 852 height int64, commit *Commit, trustLevel tmmath.Fraction) error { 853 854 // sanity check 855 if trustLevel.Numerator*3 < trustLevel.Denominator || // < 1/3 856 trustLevel.Numerator > trustLevel.Denominator { // > 1 857 panic(fmt.Sprintf("trustLevel must be within [1/3, 1], given %v", trustLevel)) 858 } 859 860 if err := verifyCommitBasic(commit, height, blockID); err != nil { 861 return err 862 } 863 864 var ( 865 talliedVotingPower int64 866 seenVals = make(map[int]int, len(commit.Precommits)) // validator index -> commit index 867 ) 868 869 // Safely calculate voting power needed. 870 totalVotingPowerMulByNumerator, overflow := safeMul(vals.TotalVotingPower(), trustLevel.Numerator) 871 if overflow { 872 return errors.New("int64 overflow while calculating voting power needed. please provide smaller trustLevel numerator") 873 } 874 votingPowerNeeded := totalVotingPowerMulByNumerator / trustLevel.Denominator 875 876 for idx, commitSig := range commit.Precommits { 877 // No need to verify absent or nil votes. 878 if commitSig == nil { 879 continue 880 } 881 882 // We don't know the validators that committed this block, so we have to 883 // check for each vote if its validator is already known. 884 valIdx, val := vals.GetByAddress(commitSig.ValidatorAddress) 885 886 if val != nil { 887 // check for double vote of validator on the same commit 888 if firstIndex, ok := seenVals[valIdx]; ok { 889 secondIndex := idx 890 return errors.Errorf("double vote from %v (%d and %d)", val, firstIndex, secondIndex) 891 } 892 seenVals[valIdx] = idx 893 894 // Validate signature. 895 voteSignBytes := commit.VoteSignBytes(chainID, idx) 896 if !val.PubKey.VerifyBytes(voteSignBytes, commitSig.Signature) { 897 return errors.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature) 898 } 899 900 talliedVotingPower += val.VotingPower 901 902 if talliedVotingPower > votingPowerNeeded { 903 return nil 904 } 905 } 906 } 907 908 return ErrNotEnoughVotingPowerSigned{Got: talliedVotingPower, Needed: votingPowerNeeded} 909 } 910 911 func verifyCommitBasic(commit *Commit, height int64, blockID BlockID) error { 912 if err := commit.ValidateBasic(); err != nil { 913 return err 914 } 915 if height != commit.Height() { 916 return NewErrInvalidCommitHeight(height, commit.Height()) 917 } 918 if !blockID.Equals(commit.BlockID) { 919 return fmt.Errorf("invalid commit -- wrong block ID: want %v, got %v", 920 blockID, commit.BlockID) 921 } 922 return nil 923 } 924 925 func verifyCommitBasicAndPower(commit *Commit, height int64, blockID BlockID, chainID string, vals *ValidatorSet, talliedPower int64) (error, int64) { 926 err, talliedPower := commit.ValidateBasicAndPower(blockID, chainID, vals, talliedPower) 927 928 if err != nil { 929 return err, 0 930 } 931 if height != commit.Height() { 932 return NewErrInvalidCommitHeight(height, commit.Height()), 0 933 } 934 if !blockID.Equals(commit.BlockID) { 935 return fmt.Errorf("invalid commit -- wrong block ID: want %v, got %v", 936 blockID, commit.BlockID), 0 937 } 938 return nil, talliedPower 939 } 940 941 //----------------- 942 943 // IsErrNotEnoughVotingPowerSigned returns true if err is 944 // ErrNotEnoughVotingPowerSigned. 945 func IsErrNotEnoughVotingPowerSigned(err error) bool { 946 _, ok := errors.Cause(err).(ErrNotEnoughVotingPowerSigned) 947 return ok 948 } 949 950 // ErrNotEnoughVotingPowerSigned is returned when not enough validators signed 951 // a commit. 952 type ErrNotEnoughVotingPowerSigned struct { 953 Got int64 954 Needed int64 955 } 956 957 func (e ErrNotEnoughVotingPowerSigned) Error() string { 958 return fmt.Sprintf("invalid commit -- insufficient voting power: got %d, needed more than %d", e.Got, e.Needed) 959 } 960 961 //---------------- 962 963 func (vals *ValidatorSet) String() string { 964 return vals.StringIndented("") 965 } 966 967 // StringIndented returns an intended string representation of ValidatorSet. 968 func (vals *ValidatorSet) StringIndented(indent string) string { 969 if vals == nil { 970 return "nil-ValidatorSet" 971 } 972 var valStrings []string 973 vals.Iterate(func(index int, val *Validator) bool { 974 valStrings = append(valStrings, val.String()) 975 return false 976 }) 977 return fmt.Sprintf(`ValidatorSet{ 978 %s Validators: 979 %s %v 980 %s}`, 981 indent, 982 indent, strings.Join(valStrings, "\n"+indent+" "), 983 indent) 984 985 } 986 987 //------------------------------------- 988 // Implements sort for sorting validators by address. 989 990 // ValidatorsByAddress implements the sort of validators by address. 991 type ValidatorsByAddress []*Validator 992 993 func (valz ValidatorsByAddress) Len() int { 994 return len(valz) 995 } 996 997 func (valz ValidatorsByAddress) Less(i, j int) bool { 998 return bytes.Compare(valz[i].Address, valz[j].Address) == -1 999 } 1000 1001 func (valz ValidatorsByAddress) Swap(i, j int) { 1002 it := valz[i] 1003 valz[i] = valz[j] 1004 valz[j] = it 1005 } 1006 1007 // ToProto converts ValidatorSet to protobuf 1008 func (vals *ValidatorSet) ToProto() (*tmproto.ValidatorSet, error) { 1009 if vals.IsNilOrEmpty() { 1010 return nil, errors.New("nil validator set") // validator set should never be nil 1011 } 1012 vp := new(tmproto.ValidatorSet) 1013 valsProto := make([]*tmproto.Validator, len(vals.Validators)) 1014 for i := 0; i < len(vals.Validators); i++ { 1015 valp, err := vals.Validators[i].ToProto() 1016 if err != nil { 1017 return nil, err 1018 } 1019 valsProto[i] = valp 1020 } 1021 vp.Validators = valsProto 1022 1023 if vals.Proposer != nil { 1024 valProposer, err := vals.Proposer.ToProto() 1025 if err != nil { 1026 return nil, fmt.Errorf("toProto: validatorSet proposer error: %w", err) 1027 } 1028 vp.Proposer = valProposer 1029 } 1030 1031 vp.TotalVotingPower = vals.totalVotingPower 1032 1033 return vp, nil 1034 } 1035 1036 // ValidatorSetFromProto sets a protobuf ValidatorSet to the given pointer. 1037 // It returns an error if any of the validators from the set or the proposer 1038 // is invalid 1039 func ValidatorSetFromProto(vp *tmproto.ValidatorSet) (*ValidatorSet, error) { 1040 if vp == nil { 1041 return nil, errors.New("nil validator set") // validator set should never be nil, bigger issues are at play if empty 1042 } 1043 vals := new(ValidatorSet) 1044 1045 valsProto := make([]*Validator, len(vp.Validators)) 1046 for i := 0; i < len(vp.Validators); i++ { 1047 v, err := ValidatorFromProto(vp.Validators[i]) 1048 if err != nil { 1049 return nil, err 1050 } 1051 valsProto[i] = v 1052 } 1053 vals.Validators = valsProto 1054 1055 if vp.GetProposer() != nil { 1056 p, err := ValidatorFromProto(vp.GetProposer()) 1057 if err != nil { 1058 return nil, fmt.Errorf("fromProto: validatorSet proposer error: %w", err) 1059 } 1060 1061 vals.Proposer = p 1062 } 1063 1064 vals.totalVotingPower = vp.GetTotalVotingPower() 1065 1066 return vals, nil 1067 } 1068 1069 //---------------------------------------- 1070 // for testing 1071 1072 // RandValidatorSet returns a randomized validator set, useful for testing. 1073 // NOTE: PrivValidator are in order. 1074 // UNSTABLE 1075 func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) { 1076 valz := make([]*Validator, numValidators) 1077 privValidators := make([]PrivValidator, numValidators) 1078 for i := 0; i < numValidators; i++ { 1079 val, privValidator := RandValidator(false, votingPower) 1080 valz[i] = val 1081 privValidators[i] = privValidator 1082 } 1083 vals := NewValidatorSet(valz) 1084 sort.Sort(PrivValidatorsByAddress(privValidators)) 1085 return vals, privValidators 1086 } 1087 1088 /////////////////////////////////////////////////////////////////////////////// 1089 // safe addition/subtraction/multiplication 1090 1091 func safeAdd(a, b int64) (int64, bool) { 1092 if b > 0 && a > math.MaxInt64-b { 1093 return -1, true 1094 } else if b < 0 && a < math.MinInt64-b { 1095 return -1, true 1096 } 1097 return a + b, false 1098 } 1099 1100 func safeSub(a, b int64) (int64, bool) { 1101 if b > 0 && a < math.MinInt64+b { 1102 return -1, true 1103 } else if b < 0 && a > math.MaxInt64+b { 1104 return -1, true 1105 } 1106 return a - b, false 1107 } 1108 1109 func safeAddClip(a, b int64) int64 { 1110 c, overflow := safeAdd(a, b) 1111 if overflow { 1112 if b < 0 { 1113 return math.MinInt64 1114 } 1115 return math.MaxInt64 1116 } 1117 return c 1118 } 1119 1120 func safeSubClip(a, b int64) int64 { 1121 c, overflow := safeSub(a, b) 1122 if overflow { 1123 if b > 0 { 1124 return math.MinInt64 1125 } 1126 return math.MaxInt64 1127 } 1128 return c 1129 } 1130 1131 func safeMul(a, b int64) (int64, bool) { 1132 if a == 0 || b == 0 { 1133 return 0, false 1134 } 1135 1136 absOfB := b 1137 if b < 0 { 1138 absOfB = -b 1139 } 1140 1141 var ( 1142 c = a 1143 overflow bool 1144 ) 1145 1146 for absOfB > 1 { 1147 c, overflow = safeAdd(c, a) 1148 if overflow { 1149 return c, true 1150 } 1151 absOfB-- 1152 } 1153 1154 if (b < 0 && a > 0) || (b < 0 && a < 0) { 1155 return -c, false 1156 } 1157 1158 return c, false 1159 }