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.

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