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