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