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.

111 lines
2.7 KiB

  1. package types
  2. import (
  3. "bytes"
  4. "fmt"
  5. "strings"
  6. "github.com/tendermint/tendermint/crypto"
  7. tmrand "github.com/tendermint/tendermint/libs/rand"
  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. switch {
  38. case v.ProposerPriority > other.ProposerPriority:
  39. return v
  40. case v.ProposerPriority < other.ProposerPriority:
  41. return other
  42. default:
  43. result := bytes.Compare(v.Address, other.Address)
  44. switch {
  45. case result < 0:
  46. return v
  47. case result > 0:
  48. return other
  49. default:
  50. panic("Cannot compare identical validators")
  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.ProposerPriority)
  63. }
  64. // ValidatorListString returns a prettified validator list for logging purposes.
  65. func ValidatorListString(vals []*Validator) string {
  66. chunks := make([]string, len(vals))
  67. for i, val := range vals {
  68. chunks[i] = fmt.Sprintf("%s:%d", val.Address, val.VotingPower)
  69. }
  70. return strings.Join(chunks, ",")
  71. }
  72. // Bytes computes the unique encoding of a validator with a given voting power.
  73. // These are the bytes that gets hashed in consensus. It excludes address
  74. // as its redundant with the pubkey. This also excludes ProposerPriority
  75. // which changes every round.
  76. func (v *Validator) Bytes() []byte {
  77. return cdcEncode(struct {
  78. PubKey crypto.PubKey
  79. VotingPower int64
  80. }{
  81. v.PubKey,
  82. v.VotingPower,
  83. })
  84. }
  85. //----------------------------------------
  86. // RandValidator
  87. // RandValidator returns a randomized validator, useful for testing.
  88. // UNSTABLE
  89. func RandValidator(randPower bool, minPower int64) (*Validator, PrivValidator) {
  90. privVal := NewMockPV()
  91. votePower := minPower
  92. if randPower {
  93. votePower += int64(tmrand.Uint32())
  94. }
  95. pubKey := privVal.GetPubKey()
  96. val := NewValidator(pubKey, votePower)
  97. return val, privVal
  98. }