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.

156 lines
3.9 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
  1. package state
  2. import (
  3. "fmt"
  4. "io"
  5. "strings"
  6. . "github.com/tendermint/tendermint/binary"
  7. "github.com/tendermint/tendermint/merkle"
  8. )
  9. // Not goroutine-safe.
  10. // TODO: consider validator Accum overflow?
  11. type ValidatorSet struct {
  12. validators merkle.Tree
  13. proposer *Validator // Whoever has the highest Accum.
  14. totalVotingPower uint64
  15. }
  16. func NewValidatorSet(vals []*Validator) *ValidatorSet {
  17. validators := merkle.NewIAVLTree(BasicCodec, ValidatorCodec, 0, nil) // In memory
  18. var proposer *Validator
  19. totalVotingPower := uint64(0)
  20. for _, val := range vals {
  21. validators.Set(val.Id, val)
  22. proposer = proposer.CompareAccum(val)
  23. totalVotingPower += val.VotingPower
  24. }
  25. return &ValidatorSet{
  26. validators: validators,
  27. proposer: proposer,
  28. totalVotingPower: totalVotingPower,
  29. }
  30. }
  31. func ReadValidatorSet(r io.Reader, n *int64, err *error) *ValidatorSet {
  32. size := ReadUInt64(r, n, err)
  33. validators := []*Validator{}
  34. for i := uint64(0); i < size; i++ {
  35. validator := ReadValidator(r, n, err)
  36. validators = append(validators, validator)
  37. }
  38. return NewValidatorSet(validators)
  39. }
  40. func (vset *ValidatorSet) WriteTo(w io.Writer) (n int64, err error) {
  41. WriteUInt64(w, uint64(vset.validators.Size()), &n, &err)
  42. vset.validators.Iterate(func(key_ interface{}, val_ interface{}) bool {
  43. val := val_.(*Validator)
  44. WriteBinary(w, val, &n, &err)
  45. return false
  46. })
  47. return
  48. }
  49. func (vset *ValidatorSet) IncrementAccum() {
  50. // Decrement from previous proposer
  51. vset.proposer.Accum -= int64(vset.totalVotingPower)
  52. var proposer *Validator
  53. // Increment accum and find proposer
  54. vset.validators.Iterate(func(key_ interface{}, val_ interface{}) bool {
  55. val := val_.(*Validator)
  56. val.Accum += int64(val.VotingPower)
  57. proposer = proposer.CompareAccum(val)
  58. return false
  59. })
  60. vset.proposer = proposer
  61. }
  62. func (vset *ValidatorSet) Copy() *ValidatorSet {
  63. return &ValidatorSet{
  64. validators: vset.validators.Copy(),
  65. proposer: vset.proposer,
  66. totalVotingPower: vset.totalVotingPower,
  67. }
  68. }
  69. func (vset *ValidatorSet) GetById(id uint64) (index uint, val *Validator) {
  70. index_, val_ := vset.validators.Get(id)
  71. index, val = uint(index_), val_.(*Validator)
  72. return
  73. }
  74. func (vset *ValidatorSet) HasId(id uint64) bool {
  75. _, val_ := vset.validators.Get(id)
  76. return val_ != nil
  77. }
  78. func (vset *ValidatorSet) GetByIndex(index uint) (id uint64, val *Validator) {
  79. id_, val_ := vset.validators.GetByIndex(uint64(index))
  80. id, val = id_.(uint64), val_.(*Validator)
  81. return
  82. }
  83. func (vset *ValidatorSet) Size() uint {
  84. return uint(vset.validators.Size())
  85. }
  86. func (vset *ValidatorSet) TotalVotingPower() uint64 {
  87. return vset.totalVotingPower
  88. }
  89. func (vset *ValidatorSet) Proposer() (proposer *Validator) {
  90. return vset.proposer
  91. }
  92. func (vset *ValidatorSet) Hash() []byte {
  93. return vset.validators.Hash()
  94. }
  95. func (vset *ValidatorSet) Add(val *Validator) (added bool) {
  96. if vset.validators.Has(val.Id) {
  97. return false
  98. }
  99. return !vset.validators.Set(val.Id, val)
  100. }
  101. func (vset *ValidatorSet) Update(val *Validator) (updated bool) {
  102. if !vset.validators.Has(val.Id) {
  103. return false
  104. }
  105. return vset.validators.Set(val.Id, val)
  106. }
  107. func (vset *ValidatorSet) Remove(validatorId uint64) (val *Validator, removed bool) {
  108. val_, removed := vset.validators.Remove(validatorId)
  109. return val_.(*Validator), removed
  110. }
  111. func (vset *ValidatorSet) Iterate(fn func(val *Validator) bool) {
  112. vset.validators.Iterate(func(key_ interface{}, val_ interface{}) bool {
  113. return fn(val_.(*Validator))
  114. })
  115. }
  116. func (vset *ValidatorSet) String() string {
  117. return vset.StringWithIndent("")
  118. }
  119. func (vset *ValidatorSet) StringWithIndent(indent string) string {
  120. valStrings := []string{}
  121. vset.Iterate(func(val *Validator) bool {
  122. valStrings = append(valStrings, val.String())
  123. return false
  124. })
  125. return fmt.Sprintf(`ValidatorSet{
  126. %s Proposer: %v
  127. %s Validators:
  128. %s %v
  129. %s}`,
  130. indent, vset.proposer.String(),
  131. indent,
  132. indent, strings.Join(valStrings, "\n"+indent+" "),
  133. indent)
  134. }