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.

296 lines
8.4 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
  1. package state
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "sort"
  7. "strings"
  8. "github.com/tendermint/tendermint/account"
  9. . "github.com/tendermint/tendermint/common"
  10. "github.com/tendermint/tendermint/merkle"
  11. "github.com/tendermint/tendermint/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. if i == times-1 {
  52. valSet.proposer = mostest
  53. }
  54. mostest.Accum -= int64(valSet.TotalVotingPower())
  55. validatorsHeap.Update(mostest, accumComparable(mostest.Accum))
  56. }
  57. }
  58. func (valSet *ValidatorSet) Copy() *ValidatorSet {
  59. validators := make([]*Validator, len(valSet.Validators))
  60. for i, val := range valSet.Validators {
  61. // NOTE: must copy, since IncrementAccum updates in place.
  62. validators[i] = val.Copy()
  63. }
  64. return &ValidatorSet{
  65. Validators: validators,
  66. proposer: valSet.proposer,
  67. totalVotingPower: valSet.totalVotingPower,
  68. }
  69. }
  70. func (valSet *ValidatorSet) HasAddress(address []byte) bool {
  71. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  72. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  73. })
  74. return idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0
  75. }
  76. func (valSet *ValidatorSet) GetByAddress(address []byte) (index uint, val *Validator) {
  77. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  78. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  79. })
  80. if idx != len(valSet.Validators) && bytes.Compare(valSet.Validators[idx].Address, address) == 0 {
  81. return uint(idx), valSet.Validators[idx].Copy()
  82. } else {
  83. return 0, nil
  84. }
  85. }
  86. func (valSet *ValidatorSet) GetByIndex(index uint) (address []byte, val *Validator) {
  87. val = valSet.Validators[index]
  88. return val.Address, val.Copy()
  89. }
  90. func (valSet *ValidatorSet) Size() uint {
  91. return uint(len(valSet.Validators))
  92. }
  93. func (valSet *ValidatorSet) TotalVotingPower() uint64 {
  94. if valSet.totalVotingPower == 0 {
  95. for _, val := range valSet.Validators {
  96. valSet.totalVotingPower += val.VotingPower
  97. }
  98. }
  99. return valSet.totalVotingPower
  100. }
  101. func (valSet *ValidatorSet) Proposer() (proposer *Validator) {
  102. if valSet.proposer == nil {
  103. for _, val := range valSet.Validators {
  104. valSet.proposer = valSet.proposer.CompareAccum(val)
  105. }
  106. }
  107. return valSet.proposer.Copy()
  108. }
  109. func (valSet *ValidatorSet) Hash() []byte {
  110. if len(valSet.Validators) == 0 {
  111. return nil
  112. }
  113. hashables := make([]merkle.Hashable, len(valSet.Validators))
  114. for i, val := range valSet.Validators {
  115. hashables[i] = val
  116. }
  117. return merkle.HashFromHashables(hashables)
  118. }
  119. func (valSet *ValidatorSet) Add(val *Validator) (added bool) {
  120. val = val.Copy()
  121. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  122. return bytes.Compare(val.Address, valSet.Validators[i].Address) <= 0
  123. })
  124. if idx == len(valSet.Validators) {
  125. valSet.Validators = append(valSet.Validators, val)
  126. // Invalidate cache
  127. valSet.proposer = nil
  128. valSet.totalVotingPower = 0
  129. return true
  130. } else if bytes.Compare(valSet.Validators[idx].Address, val.Address) == 0 {
  131. return false
  132. } else {
  133. newValidators := make([]*Validator, len(valSet.Validators)+1)
  134. copy(newValidators[:idx], valSet.Validators[:idx])
  135. newValidators[idx] = val
  136. copy(newValidators[idx+1:], valSet.Validators[idx:])
  137. valSet.Validators = newValidators
  138. // Invalidate cache
  139. valSet.proposer = nil
  140. valSet.totalVotingPower = 0
  141. return true
  142. }
  143. }
  144. func (valSet *ValidatorSet) Update(val *Validator) (updated bool) {
  145. index, sameVal := valSet.GetByAddress(val.Address)
  146. if sameVal == nil {
  147. return false
  148. } else {
  149. valSet.Validators[index] = val.Copy()
  150. // Invalidate cache
  151. valSet.proposer = nil
  152. valSet.totalVotingPower = 0
  153. return true
  154. }
  155. }
  156. func (valSet *ValidatorSet) Remove(address []byte) (val *Validator, removed bool) {
  157. idx := sort.Search(len(valSet.Validators), func(i int) bool {
  158. return bytes.Compare(address, valSet.Validators[i].Address) <= 0
  159. })
  160. if idx == len(valSet.Validators) || bytes.Compare(valSet.Validators[idx].Address, address) != 0 {
  161. return nil, false
  162. } else {
  163. removedVal := valSet.Validators[idx]
  164. newValidators := valSet.Validators[:idx]
  165. if idx+1 < len(valSet.Validators) {
  166. newValidators = append(newValidators, valSet.Validators[idx+1:]...)
  167. }
  168. valSet.Validators = newValidators
  169. // Invalidate cache
  170. valSet.proposer = nil
  171. valSet.totalVotingPower = 0
  172. return removedVal, true
  173. }
  174. }
  175. func (valSet *ValidatorSet) Iterate(fn func(index uint, val *Validator) bool) {
  176. for i, val := range valSet.Validators {
  177. stop := fn(uint(i), val.Copy())
  178. if stop {
  179. break
  180. }
  181. }
  182. }
  183. // Verify that +2/3 of the set had signed the given signBytes
  184. func (valSet *ValidatorSet) VerifyValidation(hash []byte, parts types.PartSetHeader, height uint, v *types.Validation) error {
  185. if valSet.Size() != uint(len(v.Commits)) {
  186. return errors.New(Fmt("Invalid validation -- wrong set size: %v vs %v",
  187. valSet.Size(), len(v.Commits)))
  188. }
  189. talliedVotingPower := uint64(0)
  190. seenValidators := map[string]struct{}{}
  191. for idx, commit := range v.Commits {
  192. // may be zero, in which case skip.
  193. if commit.Signature.IsZero() {
  194. continue
  195. }
  196. _, val := valSet.GetByIndex(uint(idx))
  197. commitSignBytes := account.SignBytes(&types.Vote{
  198. Height: height, Round: commit.Round, Type: types.VoteTypeCommit,
  199. BlockHash: hash,
  200. BlockParts: parts,
  201. })
  202. // Validate
  203. if _, seen := seenValidators[string(val.Address)]; seen {
  204. return fmt.Errorf("Duplicate validator for commit %v for Validation %v", commit, v)
  205. }
  206. if !val.PubKey.VerifyBytes(commitSignBytes, commit.Signature) {
  207. return fmt.Errorf("Invalid signature for commit %v for Validation %v", commit, v)
  208. }
  209. // Tally
  210. seenValidators[string(val.Address)] = struct{}{}
  211. talliedVotingPower += val.VotingPower
  212. }
  213. if talliedVotingPower > valSet.TotalVotingPower()*2/3 {
  214. return nil
  215. } else {
  216. return fmt.Errorf("insufficient voting power %v, needed %v",
  217. talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
  218. }
  219. }
  220. func (valSet *ValidatorSet) String() string {
  221. return valSet.StringIndented("")
  222. }
  223. func (valSet *ValidatorSet) StringIndented(indent string) string {
  224. valStrings := []string{}
  225. valSet.Iterate(func(index uint, val *Validator) bool {
  226. valStrings = append(valStrings, val.String())
  227. return false
  228. })
  229. return fmt.Sprintf(`ValidatorSet{
  230. %s Proposer: %v
  231. %s Validators:
  232. %s %v
  233. %s}`,
  234. indent, valSet.Proposer().String(),
  235. indent,
  236. indent, strings.Join(valStrings, "\n"+indent+" "),
  237. indent)
  238. }
  239. //-------------------------------------
  240. // Implements sort for sorting validators by address.
  241. type ValidatorsByAddress []*Validator
  242. func (vs ValidatorsByAddress) Len() int {
  243. return len(vs)
  244. }
  245. func (vs ValidatorsByAddress) Less(i, j int) bool {
  246. return bytes.Compare(vs[i].Address, vs[j].Address) == -1
  247. }
  248. func (vs ValidatorsByAddress) Swap(i, j int) {
  249. it := vs[i]
  250. vs[i] = vs[j]
  251. vs[j] = it
  252. }
  253. //-------------------------------------
  254. // Use with Heap for sorting validators by accum
  255. type accumComparable uint64
  256. // We want to find the validator with the greatest accum.
  257. func (ac accumComparable) Less(o interface{}) bool {
  258. return uint64(ac) < uint64(o.(accumComparable))
  259. }