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.

120 lines
2.9 KiB

8 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
7 years ago
  1. package types
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "github.com/tendermint/go-crypto"
  7. "github.com/tendermint/go-wire"
  8. "github.com/tendermint/go-wire/data"
  9. cmn "github.com/tendermint/tmlibs/common"
  10. )
  11. // Volatile state for each Validator
  12. // NOTE: The Accum is not included in Validator.Hash();
  13. // make sure to update that method if changes are made here
  14. type Validator struct {
  15. Address data.Bytes `json:"address"`
  16. PubKey crypto.PubKey `json:"pub_key"`
  17. VotingPower int64 `json:"voting_power"`
  18. Accum int64 `json:"accum"`
  19. }
  20. func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator {
  21. return &Validator{
  22. Address: pubKey.Address(),
  23. PubKey: pubKey,
  24. VotingPower: votingPower,
  25. Accum: 0,
  26. }
  27. }
  28. // Creates a new copy of the validator so we can mutate accum.
  29. // Panics if the validator is nil.
  30. func (v *Validator) Copy() *Validator {
  31. vCopy := *v
  32. return &vCopy
  33. }
  34. // Returns the one with higher Accum.
  35. func (v *Validator) CompareAccum(other *Validator) *Validator {
  36. if v == nil {
  37. return other
  38. }
  39. if v.Accum > other.Accum {
  40. return v
  41. } else if v.Accum < other.Accum {
  42. return other
  43. } else {
  44. if bytes.Compare(v.Address, other.Address) < 0 {
  45. return v
  46. } else if bytes.Compare(v.Address, other.Address) > 0 {
  47. return other
  48. } else {
  49. cmn.PanicSanity("Cannot compare identical validators")
  50. return nil
  51. }
  52. }
  53. }
  54. func (v *Validator) String() string {
  55. if v == nil {
  56. return "nil-Validator"
  57. }
  58. return fmt.Sprintf("Validator{%v %v VP:%v A:%v}",
  59. v.Address,
  60. v.PubKey,
  61. v.VotingPower,
  62. v.Accum)
  63. }
  64. // Hash computes the unique ID of a validator with a given voting power.
  65. // It excludes the Accum value, which changes with every round.
  66. func (v *Validator) Hash() []byte {
  67. return wire.BinaryRipemd160(struct {
  68. Address data.Bytes
  69. PubKey crypto.PubKey
  70. VotingPower int64
  71. }{
  72. v.Address,
  73. v.PubKey,
  74. v.VotingPower,
  75. })
  76. }
  77. //-------------------------------------
  78. var ValidatorCodec = validatorCodec{}
  79. type validatorCodec struct{}
  80. func (vc validatorCodec) Encode(o interface{}, w io.Writer, n *int, err *error) {
  81. wire.WriteBinary(o.(*Validator), w, n, err)
  82. }
  83. func (vc validatorCodec) Decode(r io.Reader, n *int, err *error) interface{} {
  84. return wire.ReadBinary(&Validator{}, r, 0, n, err)
  85. }
  86. func (vc validatorCodec) Compare(o1 interface{}, o2 interface{}) int {
  87. cmn.PanicSanity("ValidatorCodec.Compare not implemented")
  88. return 0
  89. }
  90. //--------------------------------------------------------------------------------
  91. // For testing...
  92. // RandValidator returns a randomized validator, useful for testing.
  93. // UNSTABLE
  94. func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidatorFS) {
  95. _, tempFilePath := cmn.Tempfile("priv_validator_")
  96. privVal := GenPrivValidatorFS(tempFilePath)
  97. votePower := minPower
  98. if randPower {
  99. votePower += int64(cmn.RandUint32())
  100. }
  101. val := NewValidator(privVal.GetPubKey(), votePower)
  102. return val, privVal
  103. }