github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/consensus/bor/valset/validator.go (about) 1 package valset 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "math/big" 8 "sort" 9 "strings" 10 11 "github.com/ethereum/go-ethereum/common" 12 ) 13 14 // Validator represets Volatile state for each Validator 15 type Validator struct { 16 ID uint64 `json:"ID"` 17 Address common.Address `json:"signer"` 18 VotingPower int64 `json:"power"` 19 ProposerPriority int64 `json:"accum"` 20 } 21 22 // NewValidator creates new validator 23 func NewValidator(address common.Address, votingPower int64) *Validator { 24 return &Validator{ 25 Address: address, 26 VotingPower: votingPower, 27 ProposerPriority: 0, 28 } 29 } 30 31 // Copy creates a new copy of the validator so we can mutate ProposerPriority. 32 // Panics if the validator is nil. 33 func (v *Validator) Copy() *Validator { 34 vCopy := *v 35 return &vCopy 36 } 37 38 // Cmp returns the one validator with a higher ProposerPriority. 39 // If ProposerPriority is same, it returns the validator with lexicographically smaller address 40 func (v *Validator) Cmp(other *Validator) *Validator { 41 // if both of v and other are nil, nil will be returned and that could possibly lead to nil pointer dereference bubbling up the stack 42 if v == nil { 43 return other 44 } 45 46 if other == nil { 47 return v 48 } 49 50 if v.ProposerPriority > other.ProposerPriority { 51 return v 52 } 53 54 if v.ProposerPriority < other.ProposerPriority { 55 return other 56 } 57 58 result := bytes.Compare(v.Address.Bytes(), other.Address.Bytes()) 59 60 if result == 0 { 61 panic("Cannot compare identical validators") 62 } 63 64 if result < 0 { 65 return v 66 } 67 68 // result > 0 69 return other 70 } 71 72 func (v *Validator) String() string { 73 if v == nil { 74 return "nil-Validator" 75 } 76 77 return fmt.Sprintf("Validator{%v Power:%v Priority:%v}", 78 v.Address.Hex(), 79 v.VotingPower, 80 v.ProposerPriority) 81 } 82 83 // ValidatorListString returns a prettified validator list for logging purposes. 84 func ValidatorListString(vals []*Validator) string { 85 chunks := make([]string, len(vals)) 86 for i, val := range vals { 87 chunks[i] = fmt.Sprintf("%s:%d", val.Address, val.VotingPower) 88 } 89 90 return strings.Join(chunks, ",") 91 } 92 93 // HeaderBytes return header bytes 94 func (v *Validator) HeaderBytes() []byte { 95 result := make([]byte, 40) 96 copy(result[:20], v.Address.Bytes()) 97 copy(result[20:], v.PowerBytes()) 98 99 return result 100 } 101 102 // PowerBytes return power bytes 103 func (v *Validator) PowerBytes() []byte { 104 powerBytes := big.NewInt(0).SetInt64(v.VotingPower).Bytes() 105 result := make([]byte, 20) 106 copy(result[20-len(powerBytes):], powerBytes) 107 108 return result 109 } 110 111 // MinimalVal returns block number of last validator update 112 func (v *Validator) MinimalVal() MinimalVal { 113 return MinimalVal{ 114 ID: v.ID, 115 VotingPower: uint64(v.VotingPower), 116 Signer: v.Address, 117 } 118 } 119 120 // ParseValidators returns validator set bytes 121 func ParseValidators(validatorsBytes []byte) ([]*Validator, error) { 122 if len(validatorsBytes)%40 != 0 { 123 return nil, errors.New("Invalid validators bytes") 124 } 125 126 result := make([]*Validator, len(validatorsBytes)/40) 127 128 for i := 0; i < len(validatorsBytes); i += 40 { 129 address := make([]byte, 20) 130 power := make([]byte, 20) 131 132 copy(address, validatorsBytes[i:i+20]) 133 copy(power, validatorsBytes[i+20:i+40]) 134 135 result[i/40] = NewValidator(common.BytesToAddress(address), big.NewInt(0).SetBytes(power).Int64()) 136 } 137 138 return result, nil 139 } 140 141 // --- 142 143 // MinimalVal is the minimal validator representation 144 // Used to send validator information to bor validator contract 145 type MinimalVal struct { 146 ID uint64 `json:"ID"` 147 VotingPower uint64 `json:"power"` // TODO add 10^-18 here so that we dont overflow easily 148 Signer common.Address `json:"signer"` 149 } 150 151 // SortMinimalValByAddress sorts validators 152 func SortMinimalValByAddress(a []MinimalVal) []MinimalVal { 153 sort.Slice(a, func(i, j int) bool { 154 return bytes.Compare(a[i].Signer.Bytes(), a[j].Signer.Bytes()) < 0 155 }) 156 157 return a 158 } 159 160 // ValidatorsToMinimalValidators converts array of validators to minimal validators 161 func ValidatorsToMinimalValidators(vals []Validator) (minVals []MinimalVal) { 162 for _, val := range vals { 163 minVals = append(minVals, val.MinimalVal()) 164 } 165 166 return 167 }