github.com/vipernet-xyz/tendermint-core@v0.32.0/types/validator.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "strings" 8 9 "github.com/tendermint/tendermint/crypto" 10 ce "github.com/tendermint/tendermint/crypto/encoding" 11 tmrand "github.com/tendermint/tendermint/libs/rand" 12 tmproto "github.com/tendermint/tendermint/proto/types" 13 ) 14 15 // Volatile state for each Validator 16 // NOTE: The ProposerPriority is not included in Validator.Hash(); 17 // make sure to update that method if changes are made here 18 type Validator struct { 19 Address Address `json:"address"` 20 PubKey crypto.PubKey `json:"pub_key"` 21 VotingPower int64 `json:"voting_power"` 22 23 ProposerPriority int64 `json:"proposer_priority"` 24 } 25 26 func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { 27 return &Validator{ 28 Address: pubKey.Address(), 29 PubKey: pubKey, 30 VotingPower: votingPower, 31 ProposerPriority: 0, 32 } 33 } 34 35 // Creates a new copy of the validator so we can mutate ProposerPriority. 36 // Panics if the validator is nil. 37 func (v *Validator) Copy() *Validator { 38 vCopy := *v 39 return &vCopy 40 } 41 42 // Returns the one with higher ProposerPriority. 43 func (v *Validator) CompareProposerPriority(other *Validator) *Validator { 44 if v == nil { 45 return other 46 } 47 switch { 48 case v.ProposerPriority > other.ProposerPriority: 49 return v 50 case v.ProposerPriority < other.ProposerPriority: 51 return other 52 default: 53 result := bytes.Compare(v.Address, other.Address) 54 switch { 55 case result < 0: 56 return v 57 case result > 0: 58 return other 59 default: 60 panic("Cannot compare identical validators") 61 } 62 } 63 } 64 65 func (v *Validator) String() string { 66 if v == nil { 67 return "nil-Validator" 68 } 69 return fmt.Sprintf("Validator{%v %v VP:%v A:%v}", 70 v.Address, 71 v.PubKey, 72 v.VotingPower, 73 v.ProposerPriority) 74 } 75 76 // ValidatorListString returns a prettified validator list for logging purposes. 77 func ValidatorListString(vals []*Validator) string { 78 chunks := make([]string, len(vals)) 79 for i, val := range vals { 80 chunks[i] = fmt.Sprintf("%s:%d", val.Address, val.VotingPower) 81 } 82 83 return strings.Join(chunks, ",") 84 } 85 86 // Bytes computes the unique encoding of a validator with a given voting power. 87 // These are the bytes that gets hashed in consensus. It excludes address 88 // as its redundant with the pubkey. This also excludes ProposerPriority 89 // which changes every round. 90 func (v *Validator) Bytes() []byte { 91 return cdcEncode(struct { 92 PubKey crypto.PubKey 93 VotingPower int64 94 }{ 95 v.PubKey, 96 v.VotingPower, 97 }) 98 } 99 100 // ToProto converts Valiator to protobuf 101 func (v *Validator) ToProto() (*tmproto.Validator, error) { 102 if v == nil { 103 return nil, errors.New("nil validator") 104 } 105 106 pk, err := ce.PubKeyToProto(v.PubKey) 107 if err != nil { 108 return nil, err 109 } 110 111 vp := tmproto.Validator{ 112 Address: v.Address, 113 PubKey: pk, 114 VotingPower: v.VotingPower, 115 ProposerPriority: v.ProposerPriority, 116 } 117 118 return &vp, nil 119 } 120 121 // FromProto sets a protobuf Validator to the given pointer. 122 // It returns an error if the public key is invalid. 123 func ValidatorFromProto(vp *tmproto.Validator) (*Validator, error) { 124 if vp == nil { 125 return nil, errors.New("nil validator") 126 } 127 128 pk, err := ce.PubKeyFromProto(&vp.PubKey) 129 if err != nil { 130 return nil, err 131 } 132 v := new(Validator) 133 v.Address = vp.GetAddress() 134 v.PubKey = pk 135 v.VotingPower = vp.GetVotingPower() 136 v.ProposerPriority = vp.GetProposerPriority() 137 138 return v, nil 139 } 140 141 //---------------------------------------- 142 // RandValidator 143 144 // RandValidator returns a randomized validator, useful for testing. 145 // UNSTABLE 146 func RandValidator(randPower bool, minPower int64) (*Validator, PrivValidator) { 147 privVal := NewMockPV() 148 votePower := minPower 149 if randPower { 150 votePower += int64(tmrand.Uint32()) 151 } 152 pubKey, err := privVal.GetPubKey() 153 if err != nil { 154 panic(fmt.Errorf("could not retrieve pubkey %w", err)) 155 } 156 val := NewValidator(pubKey, votePower) 157 return val, privVal 158 }