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.

109 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. panic("Cannot compare identical validators")
  49. }
  50. }
  51. }
  52. func (v *Validator) String() string {
  53. if v == nil {
  54. return "nil-Validator"
  55. }
  56. return fmt.Sprintf("Validator{%v %v VP:%v A:%v}",
  57. v.Address,
  58. v.PubKey,
  59. v.VotingPower,
  60. v.ProposerPriority)
  61. }
  62. // ValidatorListString returns a prettified validator list for logging purposes.
  63. func ValidatorListString(vals []*Validator) string {
  64. chunks := make([]string, len(vals))
  65. for i, val := range vals {
  66. chunks[i] = fmt.Sprintf("%s:%d", val.Address, val.VotingPower)
  67. }
  68. return strings.Join(chunks, ",")
  69. }
  70. // Bytes computes the unique encoding of a validator with a given voting power.
  71. // These are the bytes that gets hashed in consensus. It excludes address
  72. // as its redundant with the pubkey. This also excludes ProposerPriority
  73. // which changes every round.
  74. func (v *Validator) Bytes() []byte {
  75. return cdcEncode(struct {
  76. PubKey crypto.PubKey
  77. VotingPower int64
  78. }{
  79. v.PubKey,
  80. v.VotingPower,
  81. })
  82. }
  83. //----------------------------------------
  84. // RandValidator
  85. // RandValidator returns a randomized validator, useful for testing.
  86. // UNSTABLE
  87. func RandValidator(randPower bool, minPower int64) (*Validator, PrivValidator) {
  88. privVal := NewMockPV()
  89. votePower := minPower
  90. if randPower {
  91. votePower += int64(cmn.RandUint32())
  92. }
  93. pubKey := privVal.GetPubKey()
  94. val := NewValidator(pubKey, votePower)
  95. return val, privVal
  96. }