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 &ethpb.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  }