You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

518 lines
15 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
7 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
7 years ago
10 years ago
7 years ago
7 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
7 years ago
7 years ago
  1. package types
  2. import (
  3. "bytes"
  4. "fmt"
  5. "math"
  6. "sort"
  7. "strings"
  8. "github.com/tendermint/tendermint/crypto/merkle"
  9. cmn "github.com/tendermint/tendermint/libs/common"
  10. )
  11. // ValidatorSet represent a set of *Validator at a given height.
  12. // The validators can be fetched by address or index.
  13. // The index is in order of .Address, so the indices are fixed
  14. // for all rounds of a given blockchain height.
  15. // On the other hand, the .AccumPower of each validator and
  16. // the designated .GetProposer() of a set changes every round,
  17. // upon calling .IncrementAccum().
  18. // NOTE: Not goroutine-safe.
  19. // NOTE: All get/set to validators should copy the value for safety.
  20. type ValidatorSet struct {
  21. // NOTE: persisted via reflect, must be exported.
  22. Validators []*Validator `json:"validators"`
  23. Proposer *Validator `json:"proposer"`
  24. // cached (unexported)
  25. totalVotingPower int64
  26. }
  27. func NewValidatorSet(vals []*Validator) *ValidatorSet {
  28. validators := make([]*Validator, len(vals))
  29. for i, val := range vals {
  30. validators[i] = val.Copy()
  31. }
  32. sort.Sort(ValidatorsByAddress(validators))
  33. vs := &ValidatorSet{
  34. Validators: validators,
  35. }
  36. if len(vals) > 0 {
  37. vs.IncrementAccum(1)
  38. }
  39. return vs
  40. }
  41. // IncrementAccum increments accum of each validator and updates the
  42. // proposer. Panics if validator set is empty.
  43. func (valSet *ValidatorSet) IncrementAccum(times int) {
  44. // Add VotingPower * times to each validator and order into heap.
  45. validatorsHeap := cmn.NewHeap()
  46. for _, val := range valSet.Validators {
  47. // check for overflow both multiplication and sum
  48. val.Accum = safeAddClip(val.Accum, safeMulClip(val.VotingPower, int64(times)))
  49. validatorsHeap.PushComparable(val, accumComparable{val})
  50. }
  51. // Decrement the validator with most accum times times
  52. for i := 0; i < times; i++ {
  53. mostest := validatorsHeap.Peek().(*Validator)
  54. // mind underflow
  55. mostest.Accum = safeSubClip(mostest.Accum, valSet.TotalVotingPower())
  56. if i == times-1 {
  57. valSet.Proposer = mostest
  58. } else {
  59. validatorsHeap.Update(mostest, accumComparable{mostest})
  60. }
  61. }
  62. }
  63. // Copy each validator into a new ValidatorSet
  64. func (valSet *ValidatorSet) Copy() *ValidatorSet {
  65. validators := make([]*Validator, len(valSet.Validators))
  66. for i, val := range valSet.Validators {
  67. // NOTE: must copy, since IncrementAccum updates in place.
  68. validators[i] = val.Copy()
  69. }
  70. return &ValidatorSet{
  71. Validators: validators,
  72. Proposer: valSet.Proposer,
  73. totalVotingPower: valSet.totalVotingPower,
  74. }
  75. }
  76. // HasAddress returns true if address given is in the validator set, false -
  77. // otherwise.
  78. func (valSet *ValidatorSet) HasAddress(address []byte) bool {
  79. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  80. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  81. })
  82. return idx < len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address)
  83. }
  84. // GetByAddress returns an index of the validator with address and validator
  85. // itself if found. Otherwise, -1 and nil are returned.
  86. func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) {
  87. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  88. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  89. })
  90. if idx < len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) {
  91. return idx, valSet.Validators[idx].Copy()
  92. }
  93. return -1, nil
  94. }
  95. // GetByIndex returns the validator's address and validator itself by index.
  96. // It returns nil values if index is less than 0 or greater or equal to
  97. // len(ValidatorSet.Validators).
  98. func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) {
  99. if index < 0 || index >= len(valSet.Validators) {
  100. return nil, nil
  101. }
  102. val = valSet.Validators[index]
  103. return val.Address, val.Copy()
  104. }
  105. // Size returns the length of the validator set.
  106. func (valSet *ValidatorSet) Size() int {
  107. return len(valSet.Validators)
  108. }
  109. // TotalVotingPower returns the sum of the voting powers of all validators.
  110. func (valSet *ValidatorSet) TotalVotingPower() int64 {
  111. if valSet.totalVotingPower == 0 {
  112. for _, val := range valSet.Validators {
  113. // mind overflow
  114. valSet.totalVotingPower = safeAddClip(valSet.totalVotingPower, val.VotingPower)
  115. }
  116. }
  117. return valSet.totalVotingPower
  118. }
  119. // GetProposer returns the current proposer. If the validator set is empty, nil
  120. // is returned.
  121. func (valSet *ValidatorSet) GetProposer() (proposer *Validator) {
  122. if len(valSet.Validators) == 0 {
  123. return nil
  124. }
  125. if valSet.Proposer == nil {
  126. valSet.Proposer = valSet.findProposer()
  127. }
  128. return valSet.Proposer.Copy()
  129. }
  130. func (valSet *ValidatorSet) findProposer() *Validator {
  131. var proposer *Validator
  132. for _, val := range valSet.Validators {
  133. if proposer == nil || !bytes.Equal(val.Address, proposer.Address) {
  134. proposer = proposer.CompareAccum(val)
  135. }
  136. }
  137. return proposer
  138. }
  139. // Hash returns the Merkle root hash build using validators (as leaves) in the
  140. // set.
  141. func (valSet *ValidatorSet) Hash() []byte {
  142. if len(valSet.Validators) == 0 {
  143. return nil
  144. }
  145. hashers := make([]merkle.Hasher, len(valSet.Validators))
  146. for i, val := range valSet.Validators {
  147. hashers[i] = val
  148. }
  149. return merkle.SimpleHashFromHashers(hashers)
  150. }
  151. // Add adds val to the validator set and returns true. It returns false if val
  152. // is already in the set.
  153. func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
  154. val = val.Copy()
  155. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  156. return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0
  157. })
  158. if idx >= len(valSet.Validators) {
  159. valSet.Validators = append(valSet.Validators, val)
  160. // Invalidate cache
  161. valSet.Proposer = nil
  162. valSet.totalVotingPower = 0
  163. return true
  164. } else if bytes.Equal(valSet.Validators[idx].Address, val.Address) {
  165. return false
  166. } else {
  167. newValidators := make([]*Validator, len(valSet.Validators)+1)
  168. copy(newValidators[:idx], valSet.Validators[:idx])
  169. newValidators[idx] = val
  170. copy(newValidators[idx+1:], valSet.Validators[idx:])
  171. valSet.Validators = newValidators
  172. // Invalidate cache
  173. valSet.Proposer = nil
  174. valSet.totalVotingPower = 0
  175. return true
  176. }
  177. }
  178. // Update updates val and returns true. It returns false if val is not present
  179. // in the set.
  180. func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
  181. index, sameVal := valSet.GetByAddress(val.Address)
  182. if sameVal == nil {
  183. return false
  184. }
  185. valSet.Validators[index] = val.Copy()
  186. // Invalidate cache
  187. valSet.Proposer = nil
  188. valSet.totalVotingPower = 0
  189. return true
  190. }
  191. // Remove deletes the validator with address. It returns the validator removed
  192. // and true. If returns nil and false if validator is not present in the set.
  193. func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) {
  194. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  195. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  196. })
  197. if idx >= len(valSet.Validators) || !bytes.Equal(valSet.Validators[idx].Address, address) {
  198. return nil, false
  199. }
  200. removedVal := valSet.Validators[idx]
  201. newValidators := valSet.Validators[:idx]
  202. if idx+1 < len(valSet.Validators) {
  203. newValidators = append(newValidators, valSet.Validators[idx+1:]...)
  204. }
  205. valSet.Validators = newValidators
  206. // Invalidate cache
  207. valSet.Proposer = nil
  208. valSet.totalVotingPower = 0
  209. return removedVal, true
  210. }
  211. // Iterate will run the given function over the set.
  212. func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) {
  213. for i, val := range valSet.Validators {
  214. stop := fn(i, val.Copy())
  215. if stop {
  216. break
  217. }
  218. }
  219. }
  220. // Verify that +2/3 of the set had signed the given signBytes
  221. func (valSet *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height int64, commit *Commit) error {
  222. if valSet.Size() != len(commit.Precommits) {
  223. return fmt.Errorf("Invalid commit -- wrong set size: %v vs %v", valSet.Size(), len(commit.Precommits))
  224. }
  225. if height != commit.Height() {
  226. return fmt.Errorf("Invalid commit -- wrong height: %v vs %v", height, commit.Height())
  227. }
  228. talliedVotingPower := int64(0)
  229. round := commit.Round()
  230. for idx, precommit := range commit.Precommits {
  231. // may be nil if validator skipped.
  232. if precommit == nil {
  233. continue
  234. }
  235. if precommit.Height != height {
  236. return fmt.Errorf("Invalid commit -- wrong height: %v vs %v", height, precommit.Height)
  237. }
  238. if precommit.Round != round {
  239. return fmt.Errorf("Invalid commit -- wrong round: %v vs %v", round, precommit.Round)
  240. }
  241. if precommit.Type != VoteTypePrecommit {
  242. return fmt.Errorf("Invalid commit -- not precommit @ index %v", idx)
  243. }
  244. _, val := valSet.GetByIndex(idx)
  245. // Validate signature
  246. precommitSignBytes := precommit.SignBytes(chainID)
  247. if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
  248. return fmt.Errorf("Invalid commit -- invalid signature: %v", precommit)
  249. }
  250. if !blockID.Equals(precommit.BlockID) {
  251. continue // Not an error, but doesn't count
  252. }
  253. // Good precommit!
  254. talliedVotingPower += val.VotingPower
  255. }
  256. if talliedVotingPower > valSet.TotalVotingPower()*2/3 {
  257. return nil
  258. }
  259. return fmt.Errorf("Invalid commit -- insufficient voting power: got %v, needed %v",
  260. talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
  261. }
  262. // VerifyCommitAny will check to see if the set would
  263. // be valid with a different validator set.
  264. //
  265. // valSet is the validator set that we know
  266. // * over 2/3 of the power in old signed this block
  267. //
  268. // newSet is the validator set that signed this block
  269. // * only votes from old are sufficient for 2/3 majority
  270. // in the new set as well
  271. //
  272. // That means that:
  273. // * 10% of the valset can't just declare themselves kings
  274. // * If the validator set is 3x old size, we need more proof to trust
  275. func (valSet *ValidatorSet) VerifyCommitAny(newSet *ValidatorSet, chainID string,
  276. blockID BlockID, height int64, commit *Commit) error {
  277. if newSet.Size() != len(commit.Precommits) {
  278. return cmn.NewError("Invalid commit -- wrong set size: %v vs %v", newSet.Size(), len(commit.Precommits))
  279. }
  280. if height != commit.Height() {
  281. return cmn.NewError("Invalid commit -- wrong height: %v vs %v", height, commit.Height())
  282. }
  283. oldVotingPower := int64(0)
  284. newVotingPower := int64(0)
  285. seen := map[int]bool{}
  286. round := commit.Round()
  287. for idx, precommit := range commit.Precommits {
  288. // first check as in VerifyCommit
  289. if precommit == nil {
  290. continue
  291. }
  292. if precommit.Height != height {
  293. // return certerr.ErrHeightMismatch(height, precommit.Height)
  294. return cmn.NewError("Blocks don't match - %d vs %d", round, precommit.Round)
  295. }
  296. if precommit.Round != round {
  297. return cmn.NewError("Invalid commit -- wrong round: %v vs %v", round, precommit.Round)
  298. }
  299. if precommit.Type != VoteTypePrecommit {
  300. return cmn.NewError("Invalid commit -- not precommit @ index %v", idx)
  301. }
  302. if !blockID.Equals(precommit.BlockID) {
  303. continue // Not an error, but doesn't count
  304. }
  305. // we only grab by address, ignoring unknown validators
  306. vi, ov := valSet.GetByAddress(precommit.ValidatorAddress)
  307. if ov == nil || seen[vi] {
  308. continue // missing or double vote...
  309. }
  310. seen[vi] = true
  311. // Validate signature old school
  312. precommitSignBytes := precommit.SignBytes(chainID)
  313. if !ov.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
  314. return cmn.NewError("Invalid commit -- invalid signature: %v", precommit)
  315. }
  316. // Good precommit!
  317. oldVotingPower += ov.VotingPower
  318. // check new school
  319. _, cv := newSet.GetByIndex(idx)
  320. if cv.PubKey.Equals(ov.PubKey) {
  321. // make sure this is properly set in the current block as well
  322. newVotingPower += cv.VotingPower
  323. }
  324. }
  325. if oldVotingPower <= valSet.TotalVotingPower()*2/3 {
  326. return cmn.NewError("Invalid commit -- insufficient old voting power: got %v, needed %v",
  327. oldVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
  328. } else if newVotingPower <= newSet.TotalVotingPower()*2/3 {
  329. return cmn.NewError("Invalid commit -- insufficient cur voting power: got %v, needed %v",
  330. newVotingPower, (newSet.TotalVotingPower()*2/3 + 1))
  331. }
  332. return nil
  333. }
  334. func (valSet *ValidatorSet) String() string {
  335. return valSet.StringIndented("")
  336. }
  337. // String
  338. func (valSet *ValidatorSet) StringIndented(indent string) string {
  339. if valSet == nil {
  340. return "nil-ValidatorSet"
  341. }
  342. valStrings := []string{}
  343. valSet.Iterate(func(index int, val *Validator) bool {
  344. valStrings = append(valStrings, val.String())
  345. return false
  346. })
  347. return fmt.Sprintf(`ValidatorSet{
  348. %s Proposer: %v
  349. %s Validators:
  350. %s %v
  351. %s}`,
  352. indent, valSet.GetProposer().String(),
  353. indent,
  354. indent, strings.Join(valStrings, "\n"+indent+" "),
  355. indent)
  356. }
  357. //-------------------------------------
  358. // Implements sort for sorting validators by address.
  359. // Sort validators by address
  360. type ValidatorsByAddress []*Validator
  361. func (vs ValidatorsByAddress) Len() int {
  362. return len(vs)
  363. }
  364. func (vs ValidatorsByAddress) Less(i, j int) bool {
  365. return bytes.Compare(vs[i].Address, vs[j].Address) == -1
  366. }
  367. func (vs ValidatorsByAddress) Swap(i, j int) {
  368. it := vs[i]
  369. vs[i] = vs[j]
  370. vs[j] = it
  371. }
  372. //-------------------------------------
  373. // Use with Heap for sorting validators by accum
  374. type accumComparable struct {
  375. *Validator
  376. }
  377. // We want to find the validator with the greatest accum.
  378. func (ac accumComparable) Less(o interface{}) bool {
  379. other := o.(accumComparable).Validator
  380. larger := ac.CompareAccum(other)
  381. return bytes.Equal(larger.Address, ac.Address)
  382. }
  383. //----------------------------------------
  384. // For testing
  385. // RandValidatorSet returns a randomized validator set, useful for testing.
  386. // NOTE: PrivValidator are in order.
  387. // UNSTABLE
  388. func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) {
  389. vals := make([]*Validator, numValidators)
  390. privValidators := make([]PrivValidator, numValidators)
  391. for i := 0; i < numValidators; i++ {
  392. val, privValidator := RandValidator(false, votingPower)
  393. vals[i] = val
  394. privValidators[i] = privValidator
  395. }
  396. valSet := NewValidatorSet(vals)
  397. sort.Sort(PrivValidatorsByAddress(privValidators))
  398. return valSet, privValidators
  399. }
  400. ///////////////////////////////////////////////////////////////////////////////
  401. // Safe multiplication and addition/subtraction
  402. func safeMul(a, b int64) (int64, bool) {
  403. if a == 0 || b == 0 {
  404. return 0, false
  405. }
  406. if a == 1 {
  407. return b, false
  408. }
  409. if b == 1 {
  410. return a, false
  411. }
  412. if a == math.MinInt64 || b == math.MinInt64 {
  413. return -1, true
  414. }
  415. c := a * b
  416. return c, c/b != a
  417. }
  418. func safeAdd(a, b int64) (int64, bool) {
  419. if b > 0 && a > math.MaxInt64-b {
  420. return -1, true
  421. } else if b < 0 && a < math.MinInt64-b {
  422. return -1, true
  423. }
  424. return a + b, false
  425. }
  426. func safeSub(a, b int64) (int64, bool) {
  427. if b > 0 && a < math.MinInt64+b {
  428. return -1, true
  429. } else if b < 0 && a > math.MaxInt64+b {
  430. return -1, true
  431. }
  432. return a - b, false
  433. }
  434. func safeMulClip(a, b int64) int64 {
  435. c, overflow := safeMul(a, b)
  436. if overflow {
  437. if (a < 0 || b < 0) && !(a < 0 && b < 0) {
  438. return math.MinInt64
  439. }
  440. return math.MaxInt64
  441. }
  442. return c
  443. }
  444. func safeAddClip(a, b int64) int64 {
  445. c, overflow := safeAdd(a, b)
  446. if overflow {
  447. if b < 0 {
  448. return math.MinInt64
  449. }
  450. return math.MaxInt64
  451. }
  452. return c
  453. }
  454. func safeSubClip(a, b int64) int64 {
  455. c, overflow := safeSub(a, b)
  456. if overflow {
  457. if b > 0 {
  458. return math.MinInt64
  459. }
  460. return math.MaxInt64
  461. }
  462. return c
  463. }