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.

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