package types import ( "bytes" "fmt" "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/crypto" cmn "github.com/tendermint/tendermint/libs/common" ) // Volatile state for each Validator // NOTE: The Accum is not included in Validator.Hash(); // make sure to update that method if changes are made here type Validator struct { Address Address `json:"address"` PubKey crypto.PubKey `json:"pub_key"` VotingPower int64 `json:"voting_power"` Accum int64 `json:"accum"` } func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { return &Validator{ Address: pubKey.Address(), PubKey: pubKey, VotingPower: votingPower, Accum: 0, } } // Creates a new copy of the validator so we can mutate accum. // Panics if the validator is nil. func (v *Validator) Copy() *Validator { vCopy := *v return &vCopy } // Returns the one with higher Accum. func (v *Validator) CompareAccum(other *Validator) *Validator { if v == nil { return other } if v.Accum > other.Accum { return v } else if v.Accum < other.Accum { return other } else { result := bytes.Compare(v.Address, other.Address) if result < 0 { return v } else if result > 0 { return other } else { cmn.PanicSanity("Cannot compare identical validators") return nil } } } func (v *Validator) String() string { if v == nil { return "nil-Validator" } return fmt.Sprintf("Validator{%v %v VP:%v A:%v}", v.Address, v.PubKey, v.VotingPower, v.Accum) } // Hash computes the unique ID of a validator with a given voting power. // It excludes the Accum value, which changes with every round. func (v *Validator) Hash() []byte { return tmhash.Sum(v.Bytes()) } // Bytes computes the unique encoding of a validator with a given voting power. // These are the bytes that gets hashed in consensus. It excludes pubkey // as its redundant with the address. This also excludes accum which changes // every round. func (v *Validator) Bytes() []byte { return cdcEncode((struct { Address Address VotingPower int64 }{ v.Address, v.VotingPower, })) } //---------------------------------------- // RandValidator // RandValidator returns a randomized validator, useful for testing. // UNSTABLE func RandValidator(randPower bool, minPower int64) (*Validator, PrivValidator) { privVal := NewMockPV() votePower := minPower if randPower { votePower += int64(cmn.RandUint32()) } val := NewValidator(privVal.GetPubKey(), votePower) return val, privVal }