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.

390 lines
11 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/tendermint/go-wire"
  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 += int64(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 >= len(ValidatorSet.Validators)
  91. func (valSet *ValidatorSet) GetByIndex(index int) (address []byte, val *Validator) {
  92. if index >= len(valSet.Validators) {
  93. return nil, nil
  94. }
  95. val = valSet.Validators[index]
  96. return val.Address, val.Copy()
  97. }
  98. func (valSet *ValidatorSet) Size() int {
  99. return len(valSet.Validators)
  100. }
  101. func (valSet *ValidatorSet) TotalVotingPower() int64 {
  102. if valSet.totalVotingPower == 0 {
  103. for _, val := range valSet.Validators {
  104. valSet.totalVotingPower += val.VotingPower
  105. }
  106. }
  107. return valSet.totalVotingPower
  108. }
  109. func (valSet *ValidatorSet) GetProposer() (proposer *Validator) {
  110. if len(valSet.Validators) == 0 {
  111. return nil
  112. }
  113. if valSet.Proposer == nil {
  114. valSet.Proposer = valSet.findProposer()
  115. }
  116. return valSet.Proposer.Copy()
  117. }
  118. func (valSet *ValidatorSet) findProposer() *Validator {
  119. var proposer *Validator
  120. for _, val := range valSet.Validators {
  121. if proposer == nil || !bytes.Equal(val.Address, proposer.Address) {
  122. proposer = proposer.CompareAccum(val)
  123. }
  124. }
  125. return proposer
  126. }
  127. func (valSet *ValidatorSet) Hash() []byte {
  128. if len(valSet.Validators) == 0 {
  129. return nil
  130. }
  131. hashables := make([]merkle.Hashable, len(valSet.Validators))
  132. for i, val := range valSet.Validators {
  133. hashables[i] = val
  134. }
  135. return merkle.SimpleHashFromHashables(hashables)
  136. }
  137. func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
  138. val = val.Copy()
  139. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  140. return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0
  141. })
  142. if idx == len(valSet.Validators) {
  143. valSet.Validators = append(valSet.Validators, val)
  144. // Invalidate cache
  145. valSet.Proposer = nil
  146. valSet.totalVotingPower = 0
  147. return true
  148. } else if bytes.Equal(valSet.Validators[idx].Address, val.Address) {
  149. return false
  150. } else {
  151. newValidators := make([]*Validator, len(valSet.Validators)+1)
  152. copy(newValidators[:idx], valSet.Validators[:idx])
  153. newValidators[idx] = val
  154. copy(newValidators[idx+1:], valSet.Validators[idx:])
  155. valSet.Validators = newValidators
  156. // Invalidate cache
  157. valSet.Proposer = nil
  158. valSet.totalVotingPower = 0
  159. return true
  160. }
  161. }
  162. func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
  163. index, sameVal := valSet.GetByAddress(val.Address)
  164. if sameVal == nil {
  165. return false
  166. } else {
  167. valSet.Validators[index] = val.Copy()
  168. // Invalidate cache
  169. valSet.Proposer = nil
  170. valSet.totalVotingPower = 0
  171. return true
  172. }
  173. }
  174. func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) {
  175. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  176. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  177. })
  178. if idx == len(valSet.Validators) || !bytes.Equal(valSet.Validators[idx].Address, address) {
  179. return nil, false
  180. } else {
  181. removedVal := valSet.Validators[idx]
  182. newValidators := valSet.Validators[:idx]
  183. if idx+1 < len(valSet.Validators) {
  184. newValidators = append(newValidators, valSet.Validators[idx+1:]...)
  185. }
  186. valSet.Validators = newValidators
  187. // Invalidate cache
  188. valSet.Proposer = nil
  189. valSet.totalVotingPower = 0
  190. return removedVal, true
  191. }
  192. }
  193. func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) {
  194. for i, val := range valSet.Validators {
  195. stop := fn(i, val.Copy())
  196. if stop {
  197. break
  198. }
  199. }
  200. }
  201. // Verify that +2/3 of the set had signed the given signBytes
  202. func (valSet *ValidatorSet) VerifyCommit(chainID string, blockID BlockID, height int, commit *Commit) error {
  203. if valSet.Size() != len(commit.Precommits) {
  204. return fmt.Errorf("Invalid commit -- wrong set size: %v vs %v", valSet.Size(), len(commit.Precommits))
  205. }
  206. if height != commit.Height() {
  207. return fmt.Errorf("Invalid commit -- wrong height: %v vs %v", height, commit.Height())
  208. }
  209. talliedVotingPower := int64(0)
  210. round := commit.Round()
  211. for idx, precommit := range commit.Precommits {
  212. // may be nil if validator skipped.
  213. if precommit == nil {
  214. continue
  215. }
  216. if precommit.Height != height {
  217. return fmt.Errorf("Invalid commit -- wrong height: %v vs %v", height, precommit.Height)
  218. }
  219. if precommit.Round != round {
  220. return fmt.Errorf("Invalid commit -- wrong round: %v vs %v", round, precommit.Round)
  221. }
  222. if precommit.Type != VoteTypePrecommit {
  223. return fmt.Errorf("Invalid commit -- not precommit @ index %v", idx)
  224. }
  225. _, val := valSet.GetByIndex(idx)
  226. // Validate signature
  227. precommitSignBytes := SignBytes(chainID, precommit)
  228. if !val.PubKey.VerifyBytes(precommitSignBytes, precommit.Signature) {
  229. return fmt.Errorf("Invalid commit -- invalid signature: %v", precommit)
  230. }
  231. if !blockID.Equals(precommit.BlockID) {
  232. continue // Not an error, but doesn't count
  233. }
  234. // Good precommit!
  235. talliedVotingPower += val.VotingPower
  236. }
  237. if talliedVotingPower > valSet.TotalVotingPower()*2/3 {
  238. return nil
  239. } else {
  240. return fmt.Errorf("Invalid commit -- insufficient voting power: got %v, needed %v",
  241. talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
  242. }
  243. }
  244. // Verify that +2/3 of this set had signed the given signBytes.
  245. // Unlike VerifyCommit(), this function can verify commits with differeent sets.
  246. func (valSet *ValidatorSet) VerifyCommitAny(chainID string, blockID BlockID, height int, commit *Commit) error {
  247. panic("Not yet implemented")
  248. /*
  249. Start like:
  250. FOR_LOOP:
  251. for _, val := range vals {
  252. if len(precommits) == 0 {
  253. break FOR_LOOP
  254. }
  255. next := precommits[0]
  256. switch bytes.Compare(val.Address(), next.ValidatorAddress) {
  257. case -1:
  258. continue FOR_LOOP
  259. case 0:
  260. signBytes := tm.SignBytes(next)
  261. ...
  262. case 1:
  263. ... // error?
  264. }
  265. }
  266. */
  267. }
  268. func (valSet *ValidatorSet) ToBytes() []byte {
  269. buf, n, err := new(bytes.Buffer), new(int), new(error)
  270. wire.WriteBinary(valSet, buf, n, err)
  271. if *err != nil {
  272. cmn.PanicCrisis(*err)
  273. }
  274. return buf.Bytes()
  275. }
  276. func (valSet *ValidatorSet) FromBytes(b []byte) {
  277. r, n, err := bytes.NewReader(b), new(int), new(error)
  278. wire.ReadBinary(valSet, r, 0, n, err)
  279. if *err != nil {
  280. // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
  281. cmn.PanicCrisis(*err)
  282. }
  283. }
  284. func (valSet *ValidatorSet) String() string {
  285. return valSet.StringIndented("")
  286. }
  287. func (valSet *ValidatorSet) StringIndented(indent string) string {
  288. if valSet == nil {
  289. return "nil-ValidatorSet"
  290. }
  291. valStrings := []string{}
  292. valSet.Iterate(func(index int, val *Validator) bool {
  293. valStrings = append(valStrings, val.String())
  294. return false
  295. })
  296. return fmt.Sprintf(`ValidatorSet{
  297. %s Proposer: %v
  298. %s Validators:
  299. %s %v
  300. %s}`,
  301. indent, valSet.GetProposer().String(),
  302. indent,
  303. indent, strings.Join(valStrings, "\n"+indent+" "),
  304. indent)
  305. }
  306. //-------------------------------------
  307. // Implements sort for sorting validators by address.
  308. type ValidatorsByAddress []*Validator
  309. func (vs ValidatorsByAddress) Len() int {
  310. return len(vs)
  311. }
  312. func (vs ValidatorsByAddress) Less(i, j int) bool {
  313. return bytes.Compare(vs[i].Address, vs[j].Address) == -1
  314. }
  315. func (vs ValidatorsByAddress) Swap(i, j int) {
  316. it := vs[i]
  317. vs[i] = vs[j]
  318. vs[j] = it
  319. }
  320. //-------------------------------------
  321. // Use with Heap for sorting validators by accum
  322. type accumComparable struct {
  323. *Validator
  324. }
  325. // We want to find the validator with the greatest accum.
  326. func (ac accumComparable) Less(o interface{}) bool {
  327. other := o.(accumComparable).Validator
  328. larger := ac.CompareAccum(other)
  329. return bytes.Equal(larger.Address, ac.Address)
  330. }
  331. //----------------------------------------
  332. // For testing
  333. // RandValidatorSet returns a randomized validator set, useful for testing.
  334. // NOTE: PrivValidator are in order.
  335. // UNSTABLE
  336. func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []*PrivValidatorFS) {
  337. vals := make([]*Validator, numValidators)
  338. privValidators := make([]*PrivValidatorFS, numValidators)
  339. for i := 0; i < numValidators; i++ {
  340. val, privValidator := RandValidator(false, votingPower)
  341. vals[i] = val
  342. privValidators[i] = privValidator
  343. }
  344. valSet := NewValidatorSet(vals)
  345. sort.Sort(PrivValidatorsByAddress(privValidators))
  346. return valSet, privValidators
  347. }