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.

250 lines
7.0 KiB

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
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "fmt"
  5. "sort"
  6. "strings"
  7. . "github.com/tendermint/tendermint/common"
  8. "github.com/tendermint/tendermint/merkle"
  9. )
  10. // ValidatorSet represent a set of *Validator at a given height.
  11. // The validators can be fetched by address or index.
  12. // The index is in order of .Address, so the indices are fixed
  13. // for all rounds of a given blockchain height.
  14. // On the other hand, the .AccumPower of each validator and
  15. // the designated .Proposer() of a set changes every round,
  16. // upon calling .IncrementAccum().
  17. // NOTE: Not goroutine-safe.
  18. // NOTE: All get/set to validators should copy the value for safety.
  19. // TODO: consider validator Accum overflow
  20. // TODO: replace validators []*Validator with github.com/jaekwon/go-ibbs?
  21. type ValidatorSet struct {
  22. Validators []*Validator // NOTE: persisted via reflect, must be exported.
  23. // cached (unexported)
  24. proposer *Validator
  25. totalVotingPower uint64
  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. return &ValidatorSet{
  34. Validators: validators,
  35. }
  36. }
  37. // TODO: mind the overflow when times and votingPower shares too large.
  38. func (valSet *ValidatorSet) IncrementAccum(times uint) {
  39. // Add VotingPower * times to each validator and order into heap.
  40. validatorsHeap := NewHeap()
  41. for _, val := range valSet.Validators {
  42. val.Accum += int64(val.VotingPower) * int64(times) // TODO: mind overflow
  43. validatorsHeap.Push(val, accumComparable(val.Accum))
  44. }
  45. // Decrement the validator with most accum, times times.
  46. for i := uint(0); i < times; i++ {
  47. mostest := validatorsHeap.Peek().(*Validator)
  48. mostest.Accum -= int64(valSet.TotalVotingPower())
  49. validatorsHeap.Update(mostest, accumComparable(mostest.Accum))
  50. }
  51. // The next proposer is the next most accums remaining
  52. valSet.proposer = validatorsHeap.Peek().(*Validator)
  53. }
  54. func (valSet *ValidatorSet) Copy() *ValidatorSet {
  55. validators := make([]*Validator, len(valSet.Validators))
  56. for i, val := range valSet.Validators {
  57. // NOTE: must copy, since IncrementAccum updates in place.
  58. validators[i] = val.Copy()
  59. }
  60. return &ValidatorSet{
  61. Validators: validators,
  62. proposer: valSet.proposer,
  63. totalVotingPower: valSet.totalVotingPower,
  64. }
  65. }
  66. func (valSet *ValidatorSet) HasAddress(address []byte) bool {
  67. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  68. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  69. })
  70. return idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0
  71. }
  72. func (valSet *ValidatorSet) GetByAddress(address []byte) (index uint, val *Validator) {
  73. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  74. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  75. })
  76. if idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0 {
  77. return uint(idx), valSet.Validators[idx].Copy()
  78. } else {
  79. return 0, nil
  80. }
  81. }
  82. func (valSet *ValidatorSet) GetByIndex(index uint) (address []byte, val *Validator) {
  83. val = valSet.Validators[index]
  84. return val.Address, val.Copy()
  85. }
  86. func (valSet *ValidatorSet) Size() uint {
  87. return uint(len(valSet.Validators))
  88. }
  89. func (valSet *ValidatorSet) TotalVotingPower() uint64 {
  90. if valSet.totalVotingPower == 0 {
  91. for _, val := range valSet.Validators {
  92. valSet.totalVotingPower += val.VotingPower
  93. }
  94. }
  95. return valSet.totalVotingPower
  96. }
  97. func (valSet *ValidatorSet) Proposer() (proposer *Validator) {
  98. if valSet.proposer == nil {
  99. for _, val := range valSet.Validators {
  100. valSet.proposer = valSet.proposer.CompareAccum(val)
  101. }
  102. }
  103. return valSet.proposer.Copy()
  104. }
  105. func (valSet *ValidatorSet) Hash() []byte {
  106. if len(valSet.Validators) == 0 {
  107. return nil
  108. }
  109. hashables := make([]merkle.Hashable, len(valSet.Validators))
  110. for i, val := range valSet.Validators {
  111. hashables[i] = val
  112. }
  113. return merkle.HashFromHashables(hashables)
  114. }
  115. func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
  116. val = val.Copy()
  117. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  118. return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0
  119. })
  120. if idx == len(valSet.Validators) {
  121. valSet.Validators = append(valSet.Validators, val)
  122. // Invalidate cache
  123. valSet.proposer = nil
  124. valSet.totalVotingPower = 0
  125. return true
  126. } else if bytes.Compare(valSet.Validators[idx].Address, val.Address) == 0 {
  127. return false
  128. } else {
  129. newValidators := make([]*Validator, len(valSet.Validators)+1)
  130. copy(newValidators[:idx], valSet.Validators[:idx])
  131. newValidators[idx] = val
  132. copy(newValidators[idx+1:], valSet.Validators[idx:])
  133. valSet.Validators = newValidators
  134. // Invalidate cache
  135. valSet.proposer = nil
  136. valSet.totalVotingPower = 0
  137. return true
  138. }
  139. }
  140. func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
  141. index, sameVal := valSet.GetByAddress(val.Address)
  142. if sameVal == nil {
  143. return false
  144. } else {
  145. valSet.Validators[index] = val.Copy()
  146. // Invalidate cache
  147. valSet.proposer = nil
  148. valSet.totalVotingPower = 0
  149. return true
  150. }
  151. }
  152. func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) {
  153. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  154. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  155. })
  156. if idx == len(valSet.Validators) || bytes.Compare(valSet.Validators[idx].Address, address) != 0 {
  157. return nil, false
  158. } else {
  159. removedVal := valSet.Validators[idx]
  160. newValidators := valSet.Validators[:idx]
  161. if idx+1 < len(valSet.Validators) {
  162. newValidators = append(newValidators, valSet.Validators[idx+1:]...)
  163. }
  164. valSet.Validators = newValidators
  165. // Invalidate cache
  166. valSet.proposer = nil
  167. valSet.totalVotingPower = 0
  168. return removedVal, true
  169. }
  170. }
  171. func (valSet *ValidatorSet) Iterate(fn func(index uint, val *Validator) bool) {
  172. for i, val := range valSet.Validators {
  173. stop := fn(uint(i), val.Copy())
  174. if stop {
  175. break
  176. }
  177. }
  178. }
  179. func (valSet *ValidatorSet) String() string {
  180. return valSet.StringIndented("")
  181. }
  182. func (valSet *ValidatorSet) StringIndented(indent string) string {
  183. valStrings := []string{}
  184. valSet.Iterate(func(index uint, val *Validator) bool {
  185. valStrings = append(valStrings, val.String())
  186. return false
  187. })
  188. return fmt.Sprintf(`ValidatorSet{
  189. %s Proposer: %v
  190. %s Validators:
  191. %s %v
  192. %s}`,
  193. indent, valSet.Proposer().String(),
  194. indent,
  195. indent, strings.Join(valStrings, "\n"+indent+" "),
  196. indent)
  197. }
  198. //-------------------------------------
  199. // Implements sort for sorting validators by address.
  200. type ValidatorsByAddress []*Validator
  201. func (vs ValidatorsByAddress) Len() int {
  202. return len(vs)
  203. }
  204. func (vs ValidatorsByAddress) Less(i, j int) bool {
  205. return bytes.Compare(vs[i].Address, vs[j].Address) == -1
  206. }
  207. func (vs ValidatorsByAddress) Swap(i, j int) {
  208. it := vs[i]
  209. vs[i] = vs[j]
  210. vs[j] = it
  211. }
  212. //-------------------------------------
  213. // Use with Heap for sorting validators by accum
  214. type accumComparable uint64
  215. // We want to find the validator with the greatest accum.
  216. func (ac accumComparable) Less(o interface{}) bool {
  217. return uint64(ac) > uint64(o.(accumComparable))
  218. }