github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/v1/getters_validator.go (about) 1 package v1 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 8 "github.com/prysmaticlabs/prysm/shared/copyutil" 9 10 "github.com/pkg/errors" 11 types "github.com/prysmaticlabs/eth2-types" 12 iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface" 13 "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" 14 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 15 "github.com/prysmaticlabs/prysm/shared/bytesutil" 16 "github.com/prysmaticlabs/prysm/shared/featureconfig" 17 "github.com/prysmaticlabs/prysm/shared/hashutil" 18 "github.com/prysmaticlabs/prysm/shared/htrutils" 19 "github.com/prysmaticlabs/prysm/shared/params" 20 ) 21 22 // ValidatorIndexOutOfRangeError represents an error scenario where a validator does not exist 23 // at a given index in the validator's array. 24 type ValidatorIndexOutOfRangeError struct { 25 message string 26 } 27 28 // NewStateNotFoundError creates a new error instance. 29 func NewValidatorIndexOutOfRangeError(index types.ValidatorIndex) ValidatorIndexOutOfRangeError { 30 return ValidatorIndexOutOfRangeError{ 31 message: fmt.Sprintf("index %d out of range", index), 32 } 33 } 34 35 // Error returns the underlying error message. 36 func (e *ValidatorIndexOutOfRangeError) Error() string { 37 return e.message 38 } 39 40 // Validators participating in consensus on the beacon chain. 41 func (b *BeaconState) Validators() []*ethpb.Validator { 42 if !b.hasInnerState() { 43 return nil 44 } 45 if b.state.Validators == nil { 46 return nil 47 } 48 49 b.lock.RLock() 50 defer b.lock.RUnlock() 51 52 return b.validators() 53 } 54 55 // validators participating in consensus on the beacon chain. 56 // This assumes that a lock is already held on BeaconState. 57 func (b *BeaconState) validators() []*ethpb.Validator { 58 if !b.hasInnerState() { 59 return nil 60 } 61 if b.state.Validators == nil { 62 return nil 63 } 64 65 res := make([]*ethpb.Validator, len(b.state.Validators)) 66 for i := 0; i < len(res); i++ { 67 val := b.state.Validators[i] 68 if val == nil { 69 continue 70 } 71 res[i] = copyutil.CopyValidator(val) 72 } 73 return res 74 } 75 76 // references of validators participating in consensus on the beacon chain. 77 // This assumes that a lock is already held on BeaconState. This does not 78 // copy fully and instead just copies the reference. 79 func (b *BeaconState) validatorsReferences() []*ethpb.Validator { 80 if !b.hasInnerState() { 81 return nil 82 } 83 if b.state.Validators == nil { 84 return nil 85 } 86 87 res := make([]*ethpb.Validator, len(b.state.Validators)) 88 for i := 0; i < len(res); i++ { 89 validator := b.state.Validators[i] 90 if validator == nil { 91 continue 92 } 93 // copy validator reference instead. 94 res[i] = validator 95 } 96 return res 97 } 98 99 // ValidatorAtIndex is the validator at the provided index. 100 func (b *BeaconState) ValidatorAtIndex(idx types.ValidatorIndex) (*ethpb.Validator, error) { 101 if !b.hasInnerState() { 102 return nil, ErrNilInnerState 103 } 104 if b.state.Validators == nil { 105 return ðpb.Validator{}, nil 106 } 107 if uint64(len(b.state.Validators)) <= uint64(idx) { 108 e := NewValidatorIndexOutOfRangeError(idx) 109 return nil, &e 110 } 111 112 b.lock.RLock() 113 defer b.lock.RUnlock() 114 115 val := b.state.Validators[idx] 116 return copyutil.CopyValidator(val), nil 117 } 118 119 // ValidatorAtIndexReadOnly is the validator at the provided index. This method 120 // doesn't clone the validator. 121 func (b *BeaconState) ValidatorAtIndexReadOnly(idx types.ValidatorIndex) (iface.ReadOnlyValidator, error) { 122 if !b.hasInnerState() { 123 return ReadOnlyValidator{}, ErrNilInnerState 124 } 125 if b.state.Validators == nil { 126 return ReadOnlyValidator{}, nil 127 } 128 if uint64(len(b.state.Validators)) <= uint64(idx) { 129 e := NewValidatorIndexOutOfRangeError(idx) 130 return ReadOnlyValidator{}, &e 131 } 132 133 b.lock.RLock() 134 defer b.lock.RUnlock() 135 136 return ReadOnlyValidator{b.state.Validators[idx]}, nil 137 } 138 139 // ValidatorIndexByPubkey returns a given validator by its 48-byte public key. 140 func (b *BeaconState) ValidatorIndexByPubkey(key [48]byte) (types.ValidatorIndex, bool) { 141 if b == nil || b.valMapHandler == nil || b.valMapHandler.IsNil() { 142 return 0, false 143 } 144 b.lock.RLock() 145 defer b.lock.RUnlock() 146 numOfVals := len(b.state.Validators) 147 148 idx, ok := b.valMapHandler.Get(key) 149 if ok && numOfVals <= int(idx) { 150 return types.ValidatorIndex(0), false 151 } 152 return idx, ok 153 } 154 155 // PubkeyAtIndex returns the pubkey at the given 156 // validator index. 157 func (b *BeaconState) PubkeyAtIndex(idx types.ValidatorIndex) [48]byte { 158 if !b.hasInnerState() { 159 return [48]byte{} 160 } 161 if uint64(idx) >= uint64(len(b.state.Validators)) { 162 return [48]byte{} 163 } 164 b.lock.RLock() 165 defer b.lock.RUnlock() 166 167 if b.state.Validators[idx] == nil { 168 return [48]byte{} 169 } 170 return bytesutil.ToBytes48(b.state.Validators[idx].PublicKey) 171 } 172 173 // NumValidators returns the size of the validator registry. 174 func (b *BeaconState) NumValidators() int { 175 if !b.hasInnerState() { 176 return 0 177 } 178 b.lock.RLock() 179 defer b.lock.RUnlock() 180 181 return len(b.state.Validators) 182 } 183 184 // ReadFromEveryValidator reads values from every validator and applies it to the provided function. 185 // Warning: This method is potentially unsafe, as it exposes the actual validator registry. 186 func (b *BeaconState) ReadFromEveryValidator(f func(idx int, val iface.ReadOnlyValidator) error) error { 187 if !b.hasInnerState() { 188 return ErrNilInnerState 189 } 190 if b.state.Validators == nil { 191 return errors.New("nil validators in state") 192 } 193 b.lock.RLock() 194 validators := b.state.Validators 195 b.lock.RUnlock() 196 197 for i, v := range validators { 198 err := f(i, ReadOnlyValidator{validator: v}) 199 if err != nil { 200 return err 201 } 202 } 203 return nil 204 } 205 206 // Balances of validators participating in consensus on the beacon chain. 207 func (b *BeaconState) Balances() []uint64 { 208 if !b.hasInnerState() { 209 return nil 210 } 211 if b.state.Balances == nil { 212 return nil 213 } 214 215 b.lock.RLock() 216 defer b.lock.RUnlock() 217 218 return b.balances() 219 } 220 221 // balances of validators participating in consensus on the beacon chain. 222 // This assumes that a lock is already held on BeaconState. 223 func (b *BeaconState) balances() []uint64 { 224 if !b.hasInnerState() { 225 return nil 226 } 227 if b.state.Balances == nil { 228 return nil 229 } 230 231 res := make([]uint64, len(b.state.Balances)) 232 copy(res, b.state.Balances) 233 return res 234 } 235 236 // BalanceAtIndex of validator with the provided index. 237 func (b *BeaconState) BalanceAtIndex(idx types.ValidatorIndex) (uint64, error) { 238 if !b.hasInnerState() { 239 return 0, ErrNilInnerState 240 } 241 if b.state.Balances == nil { 242 return 0, nil 243 } 244 245 b.lock.RLock() 246 defer b.lock.RUnlock() 247 248 if uint64(len(b.state.Balances)) <= uint64(idx) { 249 return 0, fmt.Errorf("index of %d does not exist", idx) 250 } 251 return b.state.Balances[idx], nil 252 } 253 254 // BalancesLength returns the length of the balances slice. 255 func (b *BeaconState) BalancesLength() int { 256 if !b.hasInnerState() { 257 return 0 258 } 259 if b.state.Balances == nil { 260 return 0 261 } 262 263 b.lock.RLock() 264 defer b.lock.RUnlock() 265 266 return b.balancesLength() 267 } 268 269 // Slashings of validators on the beacon chain. 270 func (b *BeaconState) Slashings() []uint64 { 271 if !b.hasInnerState() { 272 return nil 273 } 274 if b.state.Slashings == nil { 275 return nil 276 } 277 278 b.lock.RLock() 279 defer b.lock.RUnlock() 280 281 return b.slashings() 282 } 283 284 // slashings of validators on the beacon chain. 285 // This assumes that a lock is already held on BeaconState. 286 func (b *BeaconState) slashings() []uint64 { 287 if !b.hasInnerState() { 288 return nil 289 } 290 if b.state.Slashings == nil { 291 return nil 292 } 293 294 res := make([]uint64, len(b.state.Slashings)) 295 copy(res, b.state.Slashings) 296 return res 297 } 298 299 func (h *stateRootHasher) validatorRegistryRoot(validators []*ethpb.Validator) ([32]byte, error) { 300 hashKeyElements := make([]byte, len(validators)*32) 301 roots := make([][32]byte, len(validators)) 302 emptyKey := hashutil.FastSum256(hashKeyElements) 303 hasher := hashutil.CustomSHA256Hasher() 304 bytesProcessed := 0 305 for i := 0; i < len(validators); i++ { 306 val, err := h.validatorRoot(hasher, validators[i]) 307 if err != nil { 308 return [32]byte{}, errors.Wrap(err, "could not compute validators merkleization") 309 } 310 copy(hashKeyElements[bytesProcessed:bytesProcessed+32], val[:]) 311 roots[i] = val 312 bytesProcessed += 32 313 } 314 315 hashKey := hashutil.FastSum256(hashKeyElements) 316 if hashKey != emptyKey && h.rootsCache != nil { 317 if found, ok := h.rootsCache.Get(string(hashKey[:])); found != nil && ok { 318 return found.([32]byte), nil 319 } 320 } 321 322 validatorsRootsRoot, err := htrutils.BitwiseMerkleizeArrays(hasher, roots, uint64(len(roots)), params.BeaconConfig().ValidatorRegistryLimit) 323 if err != nil { 324 return [32]byte{}, errors.Wrap(err, "could not compute validator registry merkleization") 325 } 326 validatorsRootsBuf := new(bytes.Buffer) 327 if err := binary.Write(validatorsRootsBuf, binary.LittleEndian, uint64(len(validators))); err != nil { 328 return [32]byte{}, errors.Wrap(err, "could not marshal validator registry length") 329 } 330 // We need to mix in the length of the slice. 331 var validatorsRootsBufRoot [32]byte 332 copy(validatorsRootsBufRoot[:], validatorsRootsBuf.Bytes()) 333 res := htrutils.MixInLength(validatorsRootsRoot, validatorsRootsBufRoot[:]) 334 if hashKey != emptyKey && h.rootsCache != nil { 335 h.rootsCache.Set(string(hashKey[:]), res, 32) 336 } 337 return res, nil 338 } 339 340 func (h *stateRootHasher) validatorRoot(hasher htrutils.HashFn, validator *ethpb.Validator) ([32]byte, error) { 341 if validator == nil { 342 return [32]byte{}, errors.New("nil validator") 343 } 344 345 enc := stateutil.ValidatorEncKey(validator) 346 // Check if it exists in cache: 347 if h.rootsCache != nil { 348 if found, ok := h.rootsCache.Get(string(enc)); found != nil && ok { 349 return found.([32]byte), nil 350 } 351 } 352 353 valRoot, err := stateutil.ValidatorRootWithHasher(hasher, validator) 354 if err != nil { 355 return [32]byte{}, err 356 } 357 358 if h.rootsCache != nil { 359 h.rootsCache.Set(string(enc), valRoot, 32) 360 } 361 return valRoot, nil 362 } 363 364 // ValidatorRegistryRoot computes the HashTreeRoot Merkleization of 365 // a list of validator structs according to the Ethereum 366 // Simple Serialize specification. 367 func ValidatorRegistryRoot(vals []*ethpb.Validator) ([32]byte, error) { 368 if featureconfig.Get().EnableSSZCache { 369 return cachedHasher.validatorRegistryRoot(vals) 370 } 371 return nocachedHasher.validatorRegistryRoot(vals) 372 }