mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-25 12:57:18 +00:00
64c02c405b
To increase DRY and enable DRY in tests and other users of the Beacon Chain state package, an error that was duplicated unnecessarily in each version of the state is moved to the root Beacon Chain state package.
293 lines
7.0 KiB
Go
293 lines
7.0 KiB
Go
package v1
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
types "github.com/prysmaticlabs/eth2-types"
|
|
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
|
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
|
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
|
)
|
|
|
|
// ValidatorIndexOutOfRangeError represents an error scenario where a validator does not exist
|
|
// at a given index in the validator's array.
|
|
type ValidatorIndexOutOfRangeError struct {
|
|
message string
|
|
}
|
|
|
|
// NewValidatorIndexOutOfRangeError creates a new error instance.
|
|
func NewValidatorIndexOutOfRangeError(index types.ValidatorIndex) ValidatorIndexOutOfRangeError {
|
|
return ValidatorIndexOutOfRangeError{
|
|
message: fmt.Sprintf("index %d out of range", index),
|
|
}
|
|
}
|
|
|
|
// Error returns the underlying error message.
|
|
func (e *ValidatorIndexOutOfRangeError) Error() string {
|
|
return e.message
|
|
}
|
|
|
|
// Validators participating in consensus on the beacon chain.
|
|
func (b *BeaconState) Validators() []*ethpb.Validator {
|
|
if !b.hasInnerState() {
|
|
return nil
|
|
}
|
|
if b.state.Validators == nil {
|
|
return nil
|
|
}
|
|
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
return b.validators()
|
|
}
|
|
|
|
// validators participating in consensus on the beacon chain.
|
|
// This assumes that a lock is already held on BeaconState.
|
|
func (b *BeaconState) validators() []*ethpb.Validator {
|
|
if !b.hasInnerState() {
|
|
return nil
|
|
}
|
|
if b.state.Validators == nil {
|
|
return nil
|
|
}
|
|
|
|
res := make([]*ethpb.Validator, len(b.state.Validators))
|
|
for i := 0; i < len(res); i++ {
|
|
val := b.state.Validators[i]
|
|
if val == nil {
|
|
continue
|
|
}
|
|
res[i] = ethpb.CopyValidator(val)
|
|
}
|
|
return res
|
|
}
|
|
|
|
// references of validators participating in consensus on the beacon chain.
|
|
// This assumes that a lock is already held on BeaconState. This does not
|
|
// copy fully and instead just copies the reference.
|
|
func (b *BeaconState) validatorsReferences() []*ethpb.Validator {
|
|
if !b.hasInnerState() {
|
|
return nil
|
|
}
|
|
if b.state.Validators == nil {
|
|
return nil
|
|
}
|
|
|
|
res := make([]*ethpb.Validator, len(b.state.Validators))
|
|
for i := 0; i < len(res); i++ {
|
|
validator := b.state.Validators[i]
|
|
if validator == nil {
|
|
continue
|
|
}
|
|
// copy validator reference instead.
|
|
res[i] = validator
|
|
}
|
|
return res
|
|
}
|
|
|
|
// ValidatorAtIndex is the validator at the provided index.
|
|
func (b *BeaconState) ValidatorAtIndex(idx types.ValidatorIndex) (*ethpb.Validator, error) {
|
|
if !b.hasInnerState() {
|
|
return nil, ErrNilInnerState
|
|
}
|
|
if b.state.Validators == nil {
|
|
return ðpb.Validator{}, nil
|
|
}
|
|
if uint64(len(b.state.Validators)) <= uint64(idx) {
|
|
e := NewValidatorIndexOutOfRangeError(idx)
|
|
return nil, &e
|
|
}
|
|
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
val := b.state.Validators[idx]
|
|
return ethpb.CopyValidator(val), nil
|
|
}
|
|
|
|
// ValidatorAtIndexReadOnly is the validator at the provided index. This method
|
|
// doesn't clone the validator.
|
|
func (b *BeaconState) ValidatorAtIndexReadOnly(idx types.ValidatorIndex) (state.ReadOnlyValidator, error) {
|
|
if !b.hasInnerState() {
|
|
return nil, ErrNilInnerState
|
|
}
|
|
if b.state.Validators == nil {
|
|
return nil, state.ErrNilValidatorsInState
|
|
}
|
|
if uint64(len(b.state.Validators)) <= uint64(idx) {
|
|
e := NewValidatorIndexOutOfRangeError(idx)
|
|
return nil, &e
|
|
}
|
|
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
return NewValidator(b.state.Validators[idx])
|
|
}
|
|
|
|
// ValidatorIndexByPubkey returns a given validator by its 48-byte public key.
|
|
func (b *BeaconState) ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]byte) (types.ValidatorIndex, bool) {
|
|
if b == nil || b.valMapHandler == nil || b.valMapHandler.IsNil() {
|
|
return 0, false
|
|
}
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
numOfVals := len(b.state.Validators)
|
|
|
|
idx, ok := b.valMapHandler.Get(key)
|
|
if ok && numOfVals <= int(idx) {
|
|
return types.ValidatorIndex(0), false
|
|
}
|
|
return idx, ok
|
|
}
|
|
|
|
// PubkeyAtIndex returns the pubkey at the given
|
|
// validator index.
|
|
func (b *BeaconState) PubkeyAtIndex(idx types.ValidatorIndex) [fieldparams.BLSPubkeyLength]byte {
|
|
if !b.hasInnerState() {
|
|
return [fieldparams.BLSPubkeyLength]byte{}
|
|
}
|
|
if uint64(idx) >= uint64(len(b.state.Validators)) {
|
|
return [fieldparams.BLSPubkeyLength]byte{}
|
|
}
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
if b.state.Validators[idx] == nil {
|
|
return [fieldparams.BLSPubkeyLength]byte{}
|
|
}
|
|
return bytesutil.ToBytes48(b.state.Validators[idx].PublicKey)
|
|
}
|
|
|
|
// NumValidators returns the size of the validator registry.
|
|
func (b *BeaconState) NumValidators() int {
|
|
if !b.hasInnerState() {
|
|
return 0
|
|
}
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
return len(b.state.Validators)
|
|
}
|
|
|
|
// ReadFromEveryValidator reads values from every validator and applies it to the provided function.
|
|
// Warning: This method is potentially unsafe, as it exposes the actual validator registry.
|
|
func (b *BeaconState) ReadFromEveryValidator(f func(idx int, val state.ReadOnlyValidator) error) error {
|
|
if !b.hasInnerState() {
|
|
return ErrNilInnerState
|
|
}
|
|
if b.state.Validators == nil {
|
|
return errors.New("nil validators in state")
|
|
}
|
|
b.lock.RLock()
|
|
validators := b.state.Validators
|
|
b.lock.RUnlock()
|
|
|
|
for i, v := range validators {
|
|
v, err := NewValidator(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := f(i, v); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Balances of validators participating in consensus on the beacon chain.
|
|
func (b *BeaconState) Balances() []uint64 {
|
|
if !b.hasInnerState() {
|
|
return nil
|
|
}
|
|
if b.state.Balances == nil {
|
|
return nil
|
|
}
|
|
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
return b.balances()
|
|
}
|
|
|
|
// balances of validators participating in consensus on the beacon chain.
|
|
// This assumes that a lock is already held on BeaconState.
|
|
func (b *BeaconState) balances() []uint64 {
|
|
if !b.hasInnerState() {
|
|
return nil
|
|
}
|
|
if b.state.Balances == nil {
|
|
return nil
|
|
}
|
|
|
|
res := make([]uint64, len(b.state.Balances))
|
|
copy(res, b.state.Balances)
|
|
return res
|
|
}
|
|
|
|
// BalanceAtIndex of validator with the provided index.
|
|
func (b *BeaconState) BalanceAtIndex(idx types.ValidatorIndex) (uint64, error) {
|
|
if !b.hasInnerState() {
|
|
return 0, ErrNilInnerState
|
|
}
|
|
if b.state.Balances == nil {
|
|
return 0, nil
|
|
}
|
|
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
if uint64(len(b.state.Balances)) <= uint64(idx) {
|
|
return 0, fmt.Errorf("index of %d does not exist", idx)
|
|
}
|
|
return b.state.Balances[idx], nil
|
|
}
|
|
|
|
// BalancesLength returns the length of the balances slice.
|
|
func (b *BeaconState) BalancesLength() int {
|
|
if !b.hasInnerState() {
|
|
return 0
|
|
}
|
|
if b.state.Balances == nil {
|
|
return 0
|
|
}
|
|
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
return b.balancesLength()
|
|
}
|
|
|
|
// Slashings of validators on the beacon chain.
|
|
func (b *BeaconState) Slashings() []uint64 {
|
|
if !b.hasInnerState() {
|
|
return nil
|
|
}
|
|
if b.state.Slashings == nil {
|
|
return nil
|
|
}
|
|
|
|
b.lock.RLock()
|
|
defer b.lock.RUnlock()
|
|
|
|
return b.slashings()
|
|
}
|
|
|
|
// slashings of validators on the beacon chain.
|
|
// This assumes that a lock is already held on BeaconState.
|
|
func (b *BeaconState) slashings() []uint64 {
|
|
if !b.hasInnerState() {
|
|
return nil
|
|
}
|
|
if b.state.Slashings == nil {
|
|
return nil
|
|
}
|
|
|
|
res := make([]uint64, len(b.state.Slashings))
|
|
copy(res, b.state.Slashings)
|
|
return res
|
|
}
|