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