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.

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