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.

517 lines
15 KiB

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