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  }