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.

247 lines
6.1 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
  1. package state
  2. import (
  3. "fmt"
  4. "io"
  5. "sort"
  6. "strings"
  7. . "github.com/tendermint/tendermint/binary"
  8. "github.com/tendermint/tendermint/merkle"
  9. )
  10. //-------------------------------------
  11. // Implements sort for sorting validators by id.
  12. type ValidatorSlice []*Validator
  13. func (vs ValidatorSlice) Len() int {
  14. return len(vs)
  15. }
  16. func (vs ValidatorSlice) Less(i, j int) bool {
  17. return vs[i].Id < vs[j].Id
  18. }
  19. func (vs ValidatorSlice) Swap(i, j int) {
  20. it := vs[i]
  21. vs[i] = vs[j]
  22. vs[j] = it
  23. }
  24. //-------------------------------------
  25. // Not goroutine-safe.
  26. // TODO: consider validator Accum overflow?
  27. // TODO: replace validators []*Validator with github.com/jaekwon/go-ibbs?
  28. // NOTE: all get/set to validators should copy the value for safety.
  29. type ValidatorSet struct {
  30. validators []*Validator
  31. // cache
  32. proposer *Validator
  33. totalVotingPower uint64
  34. }
  35. func NewValidatorSet(vals []*Validator) *ValidatorSet {
  36. validators := make([]*Validator, len(vals))
  37. for i, val := range vals {
  38. validators[i] = val.Copy()
  39. }
  40. sort.Sort(ValidatorSlice(validators))
  41. return &ValidatorSet{
  42. validators: validators,
  43. }
  44. }
  45. func ReadValidatorSet(r io.Reader, n *int64, err *error) *ValidatorSet {
  46. size := ReadUVarInt(r, n, err)
  47. validators := []*Validator{}
  48. for i := uint(0); i < size; i++ {
  49. validator := ReadValidator(r, n, err)
  50. validators = append(validators, validator)
  51. }
  52. sort.Sort(ValidatorSlice(validators))
  53. return NewValidatorSet(validators)
  54. }
  55. func (vset *ValidatorSet) WriteTo(w io.Writer) (n int64, err error) {
  56. WriteUVarInt(w, uint(len(vset.validators)), &n, &err)
  57. vset.Iterate(func(index uint, val *Validator) bool {
  58. WriteBinary(w, val, &n, &err)
  59. return false
  60. })
  61. return
  62. }
  63. func (vset *ValidatorSet) IncrementAccum() {
  64. // Decrement from previous proposer
  65. oldProposer := vset.Proposer()
  66. oldProposer.Accum -= int64(vset.TotalVotingPower())
  67. vset.Update(oldProposer)
  68. var newProposer *Validator
  69. // Increment accum and find new proposer
  70. // NOTE: updates validators in place.
  71. for _, val := range vset.validators {
  72. val.Accum += int64(val.VotingPower)
  73. newProposer = newProposer.CompareAccum(val)
  74. }
  75. vset.proposer = newProposer
  76. }
  77. func (vset *ValidatorSet) Copy() *ValidatorSet {
  78. validators := make([]*Validator, len(vset.validators))
  79. for i, val := range vset.validators {
  80. // NOTE: must copy, since IncrementAccum updates in place.
  81. validators[i] = val.Copy()
  82. }
  83. return &ValidatorSet{
  84. validators: validators,
  85. proposer: vset.proposer,
  86. totalVotingPower: vset.totalVotingPower,
  87. }
  88. }
  89. func (vset *ValidatorSet) HasId(id uint64) bool {
  90. idx := sort.Search(len(vset.validators), func(i int) bool {
  91. return id <= vset.validators[i].Id
  92. })
  93. return idx != len(vset.validators) && vset.validators[idx].Id == id
  94. }
  95. func (vset *ValidatorSet) GetById(id uint64) (index uint, val *Validator) {
  96. idx := sort.Search(len(vset.validators), func(i int) bool {
  97. return id <= vset.validators[i].Id
  98. })
  99. if idx != len(vset.validators) && vset.validators[idx].Id == id {
  100. return uint(idx), vset.validators[idx].Copy()
  101. } else {
  102. return 0, nil
  103. }
  104. }
  105. func (vset *ValidatorSet) GetByIndex(index uint) (id uint64, val *Validator) {
  106. val = vset.validators[index]
  107. return val.Id, val.Copy()
  108. }
  109. func (vset *ValidatorSet) Size() uint {
  110. return uint(len(vset.validators))
  111. }
  112. func (vset *ValidatorSet) TotalVotingPower() uint64 {
  113. if vset.totalVotingPower == 0 {
  114. for _, val := range vset.validators {
  115. vset.totalVotingPower += val.VotingPower
  116. }
  117. }
  118. return vset.totalVotingPower
  119. }
  120. func (vset *ValidatorSet) Proposer() (proposer *Validator) {
  121. if vset.proposer == nil {
  122. for _, val := range vset.validators {
  123. vset.proposer = vset.proposer.CompareAccum(val)
  124. }
  125. }
  126. return vset.proposer.Copy()
  127. }
  128. func (vset *ValidatorSet) Hash() []byte {
  129. if len(vset.validators) == 0 {
  130. return nil
  131. }
  132. hashables := make([]merkle.Hashable, len(vset.validators))
  133. for i, val := range vset.validators {
  134. hashables[i] = val
  135. }
  136. return merkle.HashFromHashables(hashables)
  137. }
  138. func (vset *ValidatorSet) Add(val *Validator) (added bool) {
  139. val = val.Copy()
  140. idx := sort.Search(len(vset.validators), func(i int) bool {
  141. return val.Id <= vset.validators[i].Id
  142. })
  143. if idx == len(vset.validators) {
  144. vset.validators = append(vset.validators, val)
  145. // Invalidate cache
  146. vset.proposer = nil
  147. vset.totalVotingPower = 0
  148. return true
  149. } else if vset.validators[idx].Id == val.Id {
  150. return false
  151. } else {
  152. newValidators := append(vset.validators[:idx], val)
  153. newValidators = append(newValidators, vset.validators[idx:]...)
  154. vset.validators = newValidators
  155. // Invalidate cache
  156. vset.proposer = nil
  157. vset.totalVotingPower = 0
  158. return true
  159. }
  160. }
  161. func (vset *ValidatorSet) Update(val *Validator) (updated bool) {
  162. index, sameVal := vset.GetById(val.Id)
  163. if sameVal == nil {
  164. return false
  165. } else {
  166. vset.validators[index] = val.Copy()
  167. // Invalidate cache
  168. vset.proposer = nil
  169. vset.totalVotingPower = 0
  170. return true
  171. }
  172. }
  173. func (vset *ValidatorSet) Remove(id uint64) (val *Validator, removed bool) {
  174. idx := sort.Search(len(vset.validators), func(i int) bool {
  175. return id <= vset.validators[i].Id
  176. })
  177. if idx == len(vset.validators) || vset.validators[idx].Id != id {
  178. return nil, false
  179. } else {
  180. removedVal := vset.validators[idx]
  181. newValidators := vset.validators[:idx]
  182. if idx+1 < len(vset.validators) {
  183. newValidators = append(newValidators, vset.validators[idx+1:]...)
  184. }
  185. vset.validators = newValidators
  186. // Invalidate cache
  187. vset.proposer = nil
  188. vset.totalVotingPower = 0
  189. return removedVal, true
  190. }
  191. }
  192. func (vset *ValidatorSet) Iterate(fn func(index uint, val *Validator) bool) {
  193. for i, val := range vset.validators {
  194. stop := fn(uint(i), val.Copy())
  195. if stop {
  196. break
  197. }
  198. }
  199. }
  200. func (vset *ValidatorSet) String() string {
  201. return vset.StringWithIndent("")
  202. }
  203. func (vset *ValidatorSet) StringWithIndent(indent string) string {
  204. valStrings := []string{}
  205. vset.Iterate(func(index uint, val *Validator) bool {
  206. valStrings = append(valStrings, val.String())
  207. return false
  208. })
  209. return fmt.Sprintf(`ValidatorSet{
  210. %s Proposer: %v
  211. %s Validators:
  212. %s %v
  213. %s}`,
  214. indent, vset.Proposer().String(),
  215. indent,
  216. indent, strings.Join(valStrings, "\n"+indent+" "),
  217. indent)
  218. }