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