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  }