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.

110 lines
2.7 KiB

  1. package types
  2. import (
  3. "bytes"
  4. "fmt"
  5. "strings"
  6. "github.com/tendermint/tendermint/crypto"
  7. cmn "github.com/tendermint/tendermint/libs/common"
  8. )
  9. // Volatile state for each Validator
  10. // NOTE: The ProposerPriority is not included in Validator.Hash();
  11. // make sure to update that method if changes are made here
  12. type Validator struct {
  13. Address Address `json:"address"`
  14. PubKey crypto.PubKey `json:"pub_key"`
  15. VotingPower int64 `json:"voting_power"`
  16. ProposerPriority int64 `json:"proposer_priority"`
  17. }
  18. func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator {
  19. return &Validator{
  20. Address: pubKey.Address(),
  21. PubKey: pubKey,
  22. VotingPower: votingPower,
  23. ProposerPriority: 0,
  24. }
  25. }
  26. // Creates a new copy of the validator so we can mutate ProposerPriority.
  27. // Panics if the validator is nil.
  28. func (v *Validator) Copy() *Validator {
  29. vCopy := *v
  30. return &vCopy
  31. }
  32. // Returns the one with higher ProposerPriority.
  33. func (v *Validator) CompareProposerPriority(other *Validator) *Validator {
  34. if v == nil {
  35. return other
  36. }
  37. if v.ProposerPriority > other.ProposerPriority {
  38. return v
  39. } else if v.ProposerPriority < other.ProposerPriority {
  40. return other
  41. } else {
  42. result := bytes.Compare(v.Address, other.Address)
  43. if result < 0 {
  44. return v
  45. } else if result > 0 {
  46. return other
  47. } else {
  48. cmn.PanicSanity("Cannot compare identical validators")
  49. return nil
  50. }
  51. }
  52. }
  53. func (v *Validator) String() string {
  54. if v == nil {
  55. return "nil-Validator"
  56. }
  57. return fmt.Sprintf("Validator{%v %v VP:%v A:%v}",
  58. v.Address,
  59. v.PubKey,
  60. v.VotingPower,
  61. v.ProposerPriority)
  62. }
  63. // ValidatorListString returns a prettified validator list for logging purposes.
  64. func ValidatorListString(vals []*Validator) string {
  65. chunks := make([]string, len(vals))
  66. for i, val := range vals {
  67. chunks[i] = fmt.Sprintf("%s:%d", val.Address, val.VotingPower)
  68. }
  69. return strings.Join(chunks, ",")
  70. }
  71. // Bytes computes the unique encoding of a validator with a given voting power.
  72. // These are the bytes that gets hashed in consensus. It excludes address
  73. // as its redundant with the pubkey. This also excludes ProposerPriority
  74. // which changes every round.
  75. func (v *Validator) Bytes() []byte {
  76. return cdcEncode(struct {
  77. PubKey crypto.PubKey
  78. VotingPower int64
  79. }{
  80. v.PubKey,
  81. v.VotingPower,
  82. })
  83. }
  84. //----------------------------------------
  85. // RandValidator
  86. // RandValidator returns a randomized validator, useful for testing.
  87. // UNSTABLE
  88. func RandValidator(randPower bool, minPower int64) (*Validator, PrivValidator) {
  89. privVal := NewMockPV()
  90. votePower := minPower
  91. if randPower {
  92. votePower += int64(cmn.RandUint32())
  93. }
  94. pubKey := privVal.GetPubKey()
  95. val := NewValidator(pubKey, votePower)
  96. return val, privVal
  97. }