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.

297 lines
8.5 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
10 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "sort"
  7. "strings"
  8. "github.com/tendermint/tendermint2/account"
  9. . "github.com/tendermint/tendermint2/common"
  10. "github.com/tendermint/tendermint2/merkle"
  11. "github.com/tendermint/tendermint2/types"
  12. )
  13. // ValidatorSet represent a set of *Validator at a given height.
  14. // The validators can be fetched by address or index.
  15. // The index is in order of .Address, so the indices are fixed
  16. // for all rounds of a given blockchain height.
  17. // On the other hand, the .AccumPower of each validator and
  18. // the designated .Proposer() of a set changes every round,
  19. // upon calling .IncrementAccum().
  20. // NOTE: Not goroutine-safe.
  21. // NOTE: All get/set to validators should copy the value for safety.
  22. // TODO: consider validator Accum overflow
  23. // TODO: replace validators []*Validator with github.com/jaekwon/go-ibbs?
  24. type ValidatorSet struct {
  25. Validators []*Validator // NOTE: persisted via reflect, must be exported.
  26. // cached (unexported)
  27. proposer *Validator
  28. totalVotingPower uint64
  29. }
  30. func NewValidatorSet(vals []*Validator) *ValidatorSet {
  31. validators := make([]*Validator, len(vals))
  32. for i, val := range vals {
  33. validators[i] = val.Copy()
  34. }
  35. sort.Sort(ValidatorsByAddress(validators))
  36. return &ValidatorSet{
  37. Validators: validators,
  38. }
  39. }
  40. // TODO: mind the overflow when times and votingPower shares too large.
  41. func (valSet *ValidatorSet) IncrementAccum(times uint) {
  42. // Add VotingPower * times to each validator and order into heap.
  43. validatorsHeap := NewHeap()
  44. for _, val := range valSet.Validators {
  45. val.Accum += int64(val.VotingPower) * int64(times) // TODO: mind overflow
  46. validatorsHeap.Push(val, accumComparable(val.Accum))
  47. }
  48. // Decrement the validator with most accum, times times.
  49. for i := uint(0); i < times; i++ {
  50. mostest := validatorsHeap.Peek().(*Validator)
  51. mostest.Accum -= int64(valSet.TotalVotingPower())
  52. validatorsHeap.Update(mostest, accumComparable(mostest.Accum))
  53. }
  54. // The next proposer is the next most accums remaining
  55. valSet.proposer = validatorsHeap.Peek().(*Validator)
  56. }
  57. func (valSet *ValidatorSet) Copy() *ValidatorSet {
  58. validators := make([]*Validator, len(valSet.Validators))
  59. for i, val := range valSet.Validators {
  60. // NOTE: must copy, since IncrementAccum updates in place.
  61. validators[i] = val.Copy()
  62. }
  63. return &ValidatorSet{
  64. Validators: validators,
  65. proposer: valSet.proposer,
  66. totalVotingPower: valSet.totalVotingPower,
  67. }
  68. }
  69. func (valSet *ValidatorSet) HasAddress(address []byte) bool {
  70. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  71. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  72. })
  73. return idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0
  74. }
  75. func (valSet *ValidatorSet) GetByAddress(address []byte) (index uint, val *Validator) {
  76. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  77. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  78. })
  79. if idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0 {
  80. return uint(idx), valSet.Validators[idx].Copy()
  81. } else {
  82. return 0, nil
  83. }
  84. }
  85. func (valSet *ValidatorSet) GetByIndex(index uint) (address []byte, val *Validator) {
  86. val = valSet.Validators[index]
  87. return val.Address, val.Copy()
  88. }
  89. func (valSet *ValidatorSet) Size() uint {
  90. return uint(len(valSet.Validators))
  91. }
  92. func (valSet *ValidatorSet) TotalVotingPower() uint64 {
  93. if valSet.totalVotingPower == 0 {
  94. for _, val := range valSet.Validators {
  95. valSet.totalVotingPower += val.VotingPower
  96. }
  97. }
  98. return valSet.totalVotingPower
  99. }
  100. func (valSet *ValidatorSet) Proposer() (proposer *Validator) {
  101. if valSet.proposer == nil {
  102. for _, val := range valSet.Validators {
  103. valSet.proposer = valSet.proposer.CompareAccum(val)
  104. }
  105. }
  106. return valSet.proposer.Copy()
  107. }
  108. func (valSet *ValidatorSet) Hash() []byte {
  109. if len(valSet.Validators) == 0 {
  110. return nil
  111. }
  112. hashables := make([]merkle.Hashable, len(valSet.Validators))
  113. for i, val := range valSet.Validators {
  114. hashables[i] = val
  115. }
  116. return merkle.HashFromHashables(hashables)
  117. }
  118. func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
  119. val = val.Copy()
  120. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  121. return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0
  122. })
  123. if idx == len(valSet.Validators) {
  124. valSet.Validators = append(valSet.Validators, val)
  125. // Invalidate cache
  126. valSet.proposer = nil
  127. valSet.totalVotingPower = 0
  128. return true
  129. } else if bytes.Compare(valSet.Validators[idx].Address, val.Address) == 0 {
  130. return false
  131. } else {
  132. newValidators := make([]*Validator, len(valSet.Validators)+1)
  133. copy(newValidators[:idx], valSet.Validators[:idx])
  134. newValidators[idx] = val
  135. copy(newValidators[idx+1:], valSet.Validators[idx:])
  136. valSet.Validators = newValidators
  137. // Invalidate cache
  138. valSet.proposer = nil
  139. valSet.totalVotingPower = 0
  140. return true
  141. }
  142. }
  143. func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
  144. index, sameVal := valSet.GetByAddress(val.Address)
  145. if sameVal == nil {
  146. return false
  147. } else {
  148. valSet.Validators[index] = val.Copy()
  149. // Invalidate cache
  150. valSet.proposer = nil
  151. valSet.totalVotingPower = 0
  152. return true
  153. }
  154. }
  155. func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) {
  156. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  157. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  158. })
  159. if idx == len(valSet.Validators) || bytes.Compare(valSet.Validators[idx].Address, address) != 0 {
  160. return nil, false
  161. } else {
  162. removedVal := valSet.Validators[idx]
  163. newValidators := valSet.Validators[:idx]
  164. if idx+1 < len(valSet.Validators) {
  165. newValidators = append(newValidators, valSet.Validators[idx+1:]...)
  166. }
  167. valSet.Validators = newValidators
  168. // Invalidate cache
  169. valSet.proposer = nil
  170. valSet.totalVotingPower = 0
  171. return removedVal, true
  172. }
  173. }
  174. func (valSet *ValidatorSet) Iterate(fn func(index uint, val *Validator) bool) {
  175. for i, val := range valSet.Validators {
  176. stop := fn(uint(i), val.Copy())
  177. if stop {
  178. break
  179. }
  180. }
  181. }
  182. // Verify that +2/3 of the set had signed the given signBytes
  183. func (valSet *ValidatorSet) VerifyValidation(hash []byte, parts types.PartSetHeader, height uint, v *types.Validation) error {
  184. if valSet.Size() != uint(len(v.Commits)) {
  185. return errors.New(Fmt("Invalid validation -- wrong set size: %v vs %v",
  186. valSet.Size(), len(v.Commits)))
  187. }
  188. talliedVotingPower := uint64(0)
  189. seenValidators := map[string]struct{}{}
  190. for idx, commit := range v.Commits {
  191. // may be zero, in which case skip.
  192. if commit.Signature.IsZero() {
  193. continue
  194. }
  195. _, val := valSet.GetByIndex(uint(idx))
  196. commitSignBytes := account.SignBytes(&types.Vote{
  197. Height: height, Round: commit.Round, Type: types.VoteTypeCommit,
  198. BlockHash: hash,
  199. BlockParts: parts,
  200. })
  201. // Validate
  202. if _, seen := seenValidators[string(val.Address)]; seen {
  203. return Errorf("Duplicate validator for commit %v for Validation %v", commit, v)
  204. }
  205. if !val.PubKey.VerifyBytes(commitSignBytes, commit.Signature) {
  206. return Errorf("Invalid signature for commit %v for Validation %v", commit, v)
  207. }
  208. // Tally
  209. seenValidators[string(val.Address)] = struct{}{}
  210. talliedVotingPower += val.VotingPower
  211. }
  212. if talliedVotingPower > valSet.TotalVotingPower()*2/3 {
  213. return nil
  214. } else {
  215. return Errorf("insufficient voting power %v, needed %v",
  216. talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
  217. }
  218. }
  219. func (valSet *ValidatorSet) String() string {
  220. return valSet.StringIndented("")
  221. }
  222. func (valSet *ValidatorSet) StringIndented(indent string) string {
  223. valStrings := []string{}
  224. valSet.Iterate(func(index uint, val *Validator) bool {
  225. valStrings = append(valStrings, val.String())
  226. return false
  227. })
  228. return fmt.Sprintf(`ValidatorSet{
  229. %s Proposer: %v
  230. %s Validators:
  231. %s %v
  232. %s}`,
  233. indent, valSet.Proposer().String(),
  234. indent,
  235. indent, strings.Join(valStrings, "\n"+indent+" "),
  236. indent)
  237. }
  238. //-------------------------------------
  239. // Implements sort for sorting validators by address.
  240. type ValidatorsByAddress []*Validator
  241. func (vs ValidatorsByAddress) Len() int {
  242. return len(vs)
  243. }
  244. func (vs ValidatorsByAddress) Less(i, j int) bool {
  245. return bytes.Compare(vs[i].Address, vs[j].Address) == -1
  246. }
  247. func (vs ValidatorsByAddress) Swap(i, j int) {
  248. it := vs[i]
  249. vs[i] = vs[j]
  250. vs[j] = it
  251. }
  252. //-------------------------------------
  253. // Use with Heap for sorting validators by accum
  254. type accumComparable uint64
  255. // We want to find the validator with the greatest accum.
  256. func (ac accumComparable) Less(o interface{}) bool {
  257. return uint64(ac) > uint64(o.(accumComparable))
  258. }