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.

151 lines
3.8 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
  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 uint32, val *Validator) {
  70. index_, val_ := vset.validators.Get(id)
  71. index, val = uint32(index_), val_.(*Validator)
  72. return
  73. }
  74. func (vset *ValidatorSet) GetByIndex(index uint32) (id uint64, val *Validator) {
  75. id_, val_ := vset.validators.GetByIndex(uint64(index))
  76. id, val = id_.(uint64), val_.(*Validator)
  77. return
  78. }
  79. func (vset *ValidatorSet) Size() uint {
  80. return uint(vset.validators.Size())
  81. }
  82. func (vset *ValidatorSet) TotalVotingPower() uint64 {
  83. return vset.totalVotingPower
  84. }
  85. func (vset *ValidatorSet) Proposer() (proposer *Validator) {
  86. return vset.proposer
  87. }
  88. func (vset *ValidatorSet) Hash() []byte {
  89. return vset.validators.Hash()
  90. }
  91. func (vset *ValidatorSet) Add(val *Validator) (added bool) {
  92. if vset.validators.Has(val.Id) {
  93. return false
  94. }
  95. return !vset.validators.Set(val.Id, val)
  96. }
  97. func (vset *ValidatorSet) Update(val *Validator) (updated bool) {
  98. if !vset.validators.Has(val.Id) {
  99. return false
  100. }
  101. return vset.validators.Set(val.Id, val)
  102. }
  103. func (vset *ValidatorSet) Remove(validatorId uint64) (val *Validator, removed bool) {
  104. val_, removed := vset.validators.Remove(validatorId)
  105. return val_.(*Validator), removed
  106. }
  107. func (vset *ValidatorSet) Iterate(fn func(val *Validator) bool) {
  108. vset.validators.Iterate(func(key_ interface{}, val_ interface{}) bool {
  109. return fn(val_.(*Validator))
  110. })
  111. }
  112. func (vset *ValidatorSet) String() string {
  113. return vset.StringWithIndent("")
  114. }
  115. func (vset *ValidatorSet) StringWithIndent(indent string) string {
  116. valStrings := []string{}
  117. vset.Iterate(func(val *Validator) bool {
  118. valStrings = append(valStrings, val.String())
  119. return false
  120. })
  121. return fmt.Sprintf(`ValidatorSet{
  122. %s Proposer: %v
  123. %s Validators:
  124. %s %v
  125. %s}`,
  126. indent, vset.proposer.String(),
  127. indent,
  128. indent, strings.Join(valStrings, "\n"+indent+" "),
  129. indent)
  130. }