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.

427 lines
13 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
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
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
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. "sort"
  6. "strings"
  7. "github.com/pkg/errors"
  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. // TODO: consider validator Accum overflow
  21. type ValidatorSet struct {
  22. // NOTE: persisted via reflect, must be exported.
  23. Validators []*Validator `json:"validators"`
  24. Proposer *Validator `json:"proposer"`
  25. // cached (unexported)
  26. totalVotingPower int64
  27. }
  28. func NewValidatorSet(vals []*Validator) *ValidatorSet {
  29. validators := make([]*Validator, len(vals))
  30. for i, val := range vals {
  31. validators[i] = val.Copy()
  32. }
  33. sort.Sort(ValidatorsByAddress(validators))
  34. vs := &ValidatorSet{
  35. Validators: validators,
  36. }
  37. if vals != nil {
  38. vs.IncrementAccum(1)
  39. }
  40. return vs
  41. }
  42. // incrementAccum and update the proposer
  43. // TODO: mind the overflow when times and votingPower shares too large.
  44. func (valSet *ValidatorSet) IncrementAccum(times int) {
  45. // Add VotingPower * times to each validator and order into heap.
  46. validatorsHeap := cmn.NewHeap()
  47. for _, val := range valSet.Validators {
  48. val.Accum += val.VotingPower * int64(times) // TODO: mind overflow
  49. validatorsHeap.Push(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. if i == times-1 {
  55. valSet.Proposer = mostest
  56. }
  57. mostest.Accum -= int64(valSet.TotalVotingPower())
  58. validatorsHeap.Update(mostest, accumComparable{mostest})
  59. }
  60. }
  61. func (valSet *ValidatorSet) Copy() *ValidatorSet {
  62. validators := make([]*Validator, len(valSet.Validators))
  63. for i, val := range valSet.Validators {
  64. // NOTE: must copy, since IncrementAccum updates in place.
  65. validators[i] = val.Copy()
  66. }
  67. return &ValidatorSet{
  68. Validators: validators,
  69. Proposer: valSet.Proposer,
  70. totalVotingPower: valSet.totalVotingPower,
  71. }
  72. }
  73. func (valSet *ValidatorSet) HasAddress(address []byte) bool {
  74. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  75. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  76. })
  77. return idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address)
  78. }
  79. func (valSet *ValidatorSet) GetByAddress(address []byte) (index int, val *Validator) {
  80. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  81. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  82. })
  83. if idx != len(valSet.Validators) && bytes.Equal(valSet.Validators[idx].Address, address) {
  84. return idx, valSet.Validators[idx].Copy()
  85. } else {
  86. return 0, nil
  87. }
  88. }
  89. // GetByIndex returns the validator by index.
  90. // It returns nil values if index < 0 or
  91. // index >= len(ValidatorSet.Validators)
  92. func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) {
  93. if index < 0 || index >= len(valSet.Validators) {
  94. return nil, nil
  95. }
  96. val = valSet.Validators[index]
  97. return val.Address, val.Copy()
  98. }
  99. func (valSet *ValidatorSet) Size() int {
  100. return len(valSet.Validators)
  101. }
  102. func (valSet *ValidatorSet) TotalVotingPower() int64 {
  103. if valSet.totalVotingPower == 0 {
  104. for _, val := range valSet.Validators {
  105. valSet.totalVotingPower += val.VotingPower
  106. }
  107. }
  108. return valSet.totalVotingPower
  109. }
  110. func (valSet *ValidatorSet) GetProposer() (proposer *Validator) {
  111. if len(valSet.Validators) == 0 {
  112. return nil
  113. }
  114. if valSet.Proposer == nil {
  115. valSet.Proposer = valSet.findProposer()
  116. }
  117. return valSet.Proposer.Copy()
  118. }
  119. func (valSet *ValidatorSet) findProposer() *Validator {
  120. var proposer *Validator
  121. for _, val := range valSet.Validators {
  122. if proposer == nil || !bytes.Equal(val.Address, proposer.Address) {
  123. proposer = proposer.CompareAccum(val)
  124. }
  125. }
  126. return proposer
  127. }
  128. func (valSet *ValidatorSet) Hash() []byte {
  129. if len(valSet.Validators) == 0 {
  130. return nil
  131. }
  132. hashables := make([]merkle.Hashable, len(valSet.Validators))
  133. for i, val := range valSet.Validators {
  134. hashables[i] = val
  135. }
  136. return merkle.SimpleHashFromHashables(hashables)
  137. }
  138. func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
  139. val = val.Copy()
  140. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  141. return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0
  142. })
  143. if idx == len(valSet.Validators) {
  144. valSet.Validators = append(valSet.Validators, val)
  145. // Invalidate cache
  146. valSet.Proposer = nil
  147. valSet.totalVotingPower = 0
  148. return true
  149. } else if bytes.Equal(valSet.Validators[idx].Address, val.Address) {
  150. return false
  151. } else {
  152. newValidators := make([]*Validator, len(valSet.Validators)+1)
  153. copy(newValidators[:idx], valSet.Validators[:idx])
  154. newValidators[idx] = val
  155. copy(newValidators[idx+1:], valSet.Validators[idx:])
  156. valSet.Validators = newValidators
  157. // Invalidate cache
  158. valSet.Proposer = nil
  159. valSet.totalVotingPower = 0
  160. return true
  161. }
  162. }
  163. func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
  164. index, sameVal := valSet.GetByAddress(val.Address)
  165. if sameVal == nil {
  166. return false
  167. } else {
  168. valSet.Validators[index] = val.Copy()
  169. // Invalidate cache
  170. valSet.Proposer = nil
  171. valSet.totalVotingPower = 0
  172. return true
  173. }
  174. }
  175. func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) {
  176. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  177. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  178. })
  179. if idx == len(valSet.Validators) || !bytes.Equal(valSet.Validators[idx].Address, address) {
  180. return nil, false
  181. } else {
  182. removedVal := valSet.Validators[idx]
  183. newValidators := valSet.Validators[:idx]
  184. if idx+1 < len(valSet.Validators) {
  185. newValidators = append(newValidators, valSet.Validators[idx+1:]...)
  186. }
  187. valSet.Validators = newValidators
  188. // Invalidate cache
  189. valSet.Proposer = nil
  190. valSet.totalVotingPower = 0
  191. return removedVal, true
  192. }
  193. }
  194. func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) {
  195. for i, val := range valSet.Validators {
  196. stop := fn(i, val.Copy())
  197. if stop {
  198. break
  199. }
  200. }
  201. }
  202. // Verify that +2/3 of the set had signed the given signBytes
  203. func (valSet *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height int64, commit *Commit) error {
  204. if valSet.Size() != len(commit.Precommits) {
  205. return fmt.Errorf("Invalid commit -- wrong set size: %v vs %v", valSet.Size(), len(commit.Precommits))
  206. }
  207. if height != commit.Height() {
  208. return fmt.Errorf("Invalid commit -- wrong height: %v vs %v", height, commit.Height())
  209. }
  210. talliedVotingPower := int64(0)
  211. round := commit.Round()
  212. for idx, precommit := range commit.Precommits {
  213. // may be nil if validator skipped.
  214. if precommit == nil {
  215. continue
  216. }
  217. if precommit.Height != height {
  218. return fmt.Errorf("Invalid commit -- wrong height: %v vs %v", height, precommit.Height)
  219. }
  220. if precommit.Round != round {
  221. return fmt.Errorf("Invalid commit -- wrong round: %v vs %v", round, precommit.Round)
  222. }
  223. if precommit.Type != VoteTypePrecommit {
  224. return fmt.Errorf("Invalid commit -- not precommit @ index %v", idx)
  225. }
  226. _, val := valSet.GetByIndex(idx)
  227. // Validate signature
  228. precommitSignBytes := SignBytes(chainID, precommit)
  229. if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
  230. return fmt.Errorf("Invalid commit -- invalid signature: %v", precommit)
  231. }
  232. if !blockID.Equals(precommit.BlockID) {
  233. continue // Not an error, but doesn't count
  234. }
  235. // Good precommit!
  236. talliedVotingPower += val.VotingPower
  237. }
  238. if talliedVotingPower > valSet.TotalVotingPower()*2/3 {
  239. return nil
  240. } else {
  241. return fmt.Errorf("Invalid commit -- insufficient voting power: got %v, needed %v",
  242. talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
  243. }
  244. }
  245. // VerifyCommitAny will check to see if the set would
  246. // be valid with a different validator set.
  247. //
  248. // valSet is the validator set that we know
  249. // * over 2/3 of the power in old signed this block
  250. //
  251. // newSet is the validator set that signed this block
  252. // * only votes from old are sufficient for 2/3 majority
  253. // in the new set as well
  254. //
  255. // That means that:
  256. // * 10% of the valset can't just declare themselves kings
  257. // * If the validator set is 3x old size, we need more proof to trust
  258. func (valSet *ValidatorSet) VerifyCommitAny(newSet *ValidatorSet, chainID string,
  259. blockID BlockID, height int64, commit *Commit) error {
  260. if newSet.Size() != len(commit.Precommits) {
  261. return errors.Errorf("Invalid commit -- wrong set size: %v vs %v", newSet.Size(), len(commit.Precommits))
  262. }
  263. if height != commit.Height() {
  264. return errors.Errorf("Invalid commit -- wrong height: %v vs %v", height, commit.Height())
  265. }
  266. oldVotingPower := int64(0)
  267. newVotingPower := int64(0)
  268. seen := map[int]bool{}
  269. round := commit.Round()
  270. for idx, precommit := range commit.Precommits {
  271. // first check as in VerifyCommit
  272. if precommit == nil {
  273. continue
  274. }
  275. if precommit.Height != height {
  276. // return certerr.ErrHeightMismatch(height, precommit.Height)
  277. return errors.Errorf("Blocks don't match - %d vs %d", round, precommit.Round)
  278. }
  279. if precommit.Round != round {
  280. return errors.Errorf("Invalid commit -- wrong round: %v vs %v", round, precommit.Round)
  281. }
  282. if precommit.Type != VoteTypePrecommit {
  283. return errors.Errorf("Invalid commit -- not precommit @ index %v", idx)
  284. }
  285. if !blockID.Equals(precommit.BlockID) {
  286. continue // Not an error, but doesn't count
  287. }
  288. // we only grab by address, ignoring unknown validators
  289. vi, ov := valSet.GetByAddress(precommit.ValidatorAddress)
  290. if ov == nil || seen[vi] {
  291. continue // missing or double vote...
  292. }
  293. seen[vi] = true
  294. // Validate signature old school
  295. precommitSignBytes := SignBytes(chainID, precommit)
  296. if !ov.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
  297. return errors.Errorf("Invalid commit -- invalid signature: %v", precommit)
  298. }
  299. // Good precommit!
  300. oldVotingPower += ov.VotingPower
  301. // check new school
  302. _, cv := newSet.GetByIndex(idx)
  303. if cv.PubKey.Equals(ov.PubKey) {
  304. // make sure this is properly set in the current block as well
  305. newVotingPower += cv.VotingPower
  306. }
  307. }
  308. if oldVotingPower <= valSet.TotalVotingPower()*2/3 {
  309. return errors.Errorf("Invalid commit -- insufficient old voting power: got %v, needed %v",
  310. oldVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
  311. } else if newVotingPower <= newSet.TotalVotingPower()*2/3 {
  312. return errors.Errorf("Invalid commit -- insufficient cur voting power: got %v, needed %v",
  313. newVotingPower, (newSet.TotalVotingPower()*2/3 + 1))
  314. }
  315. return nil
  316. }
  317. func (valSet *ValidatorSet) String() string {
  318. return valSet.StringIndented("")
  319. }
  320. func (valSet *ValidatorSet) StringIndented(indent string) string {
  321. if valSet == nil {
  322. return "nil-ValidatorSet"
  323. }
  324. valStrings := []string{}
  325. valSet.Iterate(func(index int, val *Validator) bool {
  326. valStrings = append(valStrings, val.String())
  327. return false
  328. })
  329. return fmt.Sprintf(`ValidatorSet{
  330. %s Proposer: %v
  331. %s Validators:
  332. %s %v
  333. %s}`,
  334. indent, valSet.GetProposer().String(),
  335. indent,
  336. indent, strings.Join(valStrings, "\n"+indent+" "),
  337. indent)
  338. }
  339. //-------------------------------------
  340. // Implements sort for sorting validators by address.
  341. type ValidatorsByAddress []*Validator
  342. func (vs ValidatorsByAddress) Len() int {
  343. return len(vs)
  344. }
  345. func (vs ValidatorsByAddress) Less(i, j int) bool {
  346. return bytes.Compare(vs[i].Address, vs[j].Address) == -1
  347. }
  348. func (vs ValidatorsByAddress) Swap(i, j int) {
  349. it := vs[i]
  350. vs[i] = vs[j]
  351. vs[j] = it
  352. }
  353. //-------------------------------------
  354. // Use with Heap for sorting validators by accum
  355. type accumComparable struct {
  356. *Validator
  357. }
  358. // We want to find the validator with the greatest accum.
  359. func (ac accumComparable) Less(o interface{}) bool {
  360. other := o.(accumComparable).Validator
  361. larger := ac.CompareAccum(other)
  362. return bytes.Equal(larger.Address, ac.Address)
  363. }
  364. //----------------------------------------
  365. // For testing
  366. // RandValidatorSet returns a randomized validator set, useful for testing.
  367. // NOTE: PrivValidator are in order.
  368. // UNSTABLE
  369. func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []*PrivValidatorFS) {
  370. vals := make([]*Validator, numValidators)
  371. privValidators := make([]*PrivValidatorFS, numValidators)
  372. for i := 0; i < numValidators; i++ {
  373. val, privValidator := RandValidator(false, votingPower)
  374. vals[i] = val
  375. privValidators[i] = privValidator
  376. }
  377. valSet := NewValidatorSet(vals)
  378. sort.Sort(PrivValidatorsByAddress(privValidators))
  379. return valSet, privValidators
  380. }