Compare commits

...

1 Commits

Author SHA1 Message Date
terence tsao
5ed16d9526 Fix process registry to avoid copying entire validator set 2024-06-19 13:19:42 -07:00
7 changed files with 50 additions and 18 deletions

View File

@@ -7,6 +7,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
@@ -194,10 +195,18 @@ func ProcessConsolidations(ctx context.Context, st state.BeaconState, cs []*ethp
if err != nil {
return err
}
if !helpers.IsActiveValidator(source, currentEpoch) {
sourceValidator, err := state_native.NewValidator(source)
if err != nil {
return err
}
if !helpers.IsActiveValidator(sourceValidator, currentEpoch) {
return errors.New("source is not active")
}
if !helpers.IsActiveValidator(target, currentEpoch) {
targetValidator, err := state_native.NewValidator(target)
if err != nil {
return err
}
if !helpers.IsActiveValidator(targetValidator, currentEpoch) {
return errors.New("target is not active")
}
if source.ExitEpoch != params.BeaconConfig().FarFutureEpoch {

View File

@@ -9,6 +9,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
@@ -123,7 +124,12 @@ func ProcessWithdrawalRequests(ctx context.Context, st state.BeaconState, wrs []
}
// Verify the validator is active.
if !helpers.IsActiveValidator(validator, currentEpoch) {
roValidator, err := state_native.NewValidator(validator)
if err != nil {
return nil, err
}
if !helpers.IsActiveValidator(roValidator, currentEpoch) {
log.Debugln("Skipping execution layer withdrawal request, validator not active")
continue
}

View File

@@ -13,6 +13,7 @@ go_library(
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/core/validators:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//beacon-chain/state/stateutil:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",

View File

@@ -14,6 +14,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
@@ -28,7 +29,7 @@ import (
// by activation epoch and by index number.
type sortableIndices struct {
indices []primitives.ValidatorIndex
validators []*ethpb.Validator
validators []state.ReadOnlyValidator
}
// Len is the number of elements in the collection.
@@ -39,10 +40,10 @@ func (s sortableIndices) Swap(i, j int) { s.indices[i], s.indices[j] = s.indices
// Less reports whether the element with index i must sort before the element with index j.
func (s sortableIndices) Less(i, j int) bool {
if s.validators[s.indices[i]].ActivationEligibilityEpoch == s.validators[s.indices[j]].ActivationEligibilityEpoch {
if s.validators[s.indices[i]].ActivationEligibilityEpoch() == s.validators[s.indices[j]].ActivationEligibilityEpoch() {
return s.indices[i] < s.indices[j]
}
return s.validators[s.indices[i]].ActivationEligibilityEpoch < s.validators[s.indices[j]].ActivationEligibilityEpoch
return s.validators[s.indices[i]].ActivationEligibilityEpoch() < s.validators[s.indices[j]].ActivationEligibilityEpoch()
}
// AttestingBalance returns the total balance from all the attesting indices.
@@ -93,22 +94,30 @@ func AttestingBalance(ctx context.Context, state state.ReadOnlyBeaconState, atts
// validator.activation_epoch = compute_activation_exit_epoch(get_current_epoch(state))
func ProcessRegistryUpdates(ctx context.Context, state state.BeaconState) (state.BeaconState, error) {
currentEpoch := time.CurrentEpoch(state)
vals := state.Validators()
vals := state.ValidatorsReadOnly()
var err error
ejectionBal := params.BeaconConfig().EjectionBalance
activationEligibilityEpoch := time.CurrentEpoch(state) + 1
for idx, validator := range vals {
// Process the validators for activation eligibility.
if helpers.IsEligibleForActivationQueue(validator, currentEpoch) {
validator.ActivationEligibilityEpoch = activationEligibilityEpoch
if err := state.UpdateValidatorAtIndex(primitives.ValidatorIndex(idx), validator); err != nil {
v, err := state.ValidatorAtIndex(primitives.ValidatorIndex(idx))
if err != nil {
return nil, err
}
v.ActivationEligibilityEpoch = activationEligibilityEpoch
if err := state.UpdateValidatorAtIndex(primitives.ValidatorIndex(idx), v); err != nil {
return nil, err
}
validator, err = state_native.NewValidator(v)
if err != nil {
return nil, err
}
}
// Process the validators for ejection.
isActive := helpers.IsActiveValidator(validator, currentEpoch)
belowEjectionBalance := validator.EffectiveBalance <= ejectionBal
belowEjectionBalance := validator.EffectiveBalance() <= ejectionBal
if isActive && belowEjectionBalance {
// Here is fine to do a quadratic loop since this should
// barely happen
@@ -122,6 +131,7 @@ func ProcessRegistryUpdates(ctx context.Context, state state.BeaconState) (state
// Queue validators eligible for activation and not yet dequeued for activation.
var activationQ []primitives.ValidatorIndex
vals = state.ValidatorsReadOnly()
for idx, validator := range vals {
if helpers.IsEligibleForActivation(state, validator) {
activationQ = append(activationQ, primitives.ValidatorIndex(idx))

View File

@@ -41,8 +41,8 @@ var (
// Check if ``validator`` is active.
// """
// return validator.activation_epoch <= epoch < validator.exit_epoch
func IsActiveValidator(validator *ethpb.Validator, epoch primitives.Epoch) bool {
return checkValidatorActiveStatus(validator.ActivationEpoch, validator.ExitEpoch, epoch)
func IsActiveValidator(validator state.ReadOnlyValidator, epoch primitives.Epoch) bool {
return checkValidatorActiveStatus(validator.ActivationEpoch(), validator.ExitEpoch(), epoch)
}
// IsActiveValidatorUsingTrie checks if a read only validator is active.
@@ -404,11 +404,11 @@ func ComputeProposerIndex(bState state.ReadOnlyValidators, activeIndices []primi
// validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH
// and validator.effective_balance >= MIN_ACTIVATION_BALANCE # [Modified in Electra:EIP7251]
// )
func IsEligibleForActivationQueue(validator *ethpb.Validator, currentEpoch primitives.Epoch) bool {
func IsEligibleForActivationQueue(validator state.ReadOnlyValidator, currentEpoch primitives.Epoch) bool {
if currentEpoch >= params.BeaconConfig().ElectraForkEpoch {
return isEligibleForActivationQueueElectra(validator.ActivationEligibilityEpoch, validator.EffectiveBalance)
return isEligibleForActivationQueueElectra(validator.ActivationEligibilityEpoch(), validator.EffectiveBalance())
}
return isEligibleForActivationQueue(validator.ActivationEligibilityEpoch, validator.EffectiveBalance)
return isEligibleForActivationQueue(validator.ActivationEligibilityEpoch(), validator.EffectiveBalance())
}
// isEligibleForActivationQueue carries out the logic for IsEligibleForActivationQueue
@@ -459,9 +459,9 @@ func isEligibleForActivationQueueElectra(activationEligibilityEpoch primitives.E
// # Has not yet been activated
// and validator.activation_epoch == FAR_FUTURE_EPOCH
// )
func IsEligibleForActivation(state state.ReadOnlyCheckpoint, validator *ethpb.Validator) bool {
func IsEligibleForActivation(state state.ReadOnlyCheckpoint, validator state.ReadOnlyValidator) bool {
finalizedEpoch := state.FinalizedCheckpointEpoch()
return isEligibleForActivation(validator.ActivationEligibilityEpoch, validator.ActivationEpoch, finalizedEpoch)
return isEligibleForActivation(validator.ActivationEligibilityEpoch(), validator.ActivationEpoch(), finalizedEpoch)
}
// IsEligibleForActivationUsingTrie checks if the validator is eligible for activation.

View File

@@ -36,6 +36,7 @@ go_library(
"//beacon-chain/p2p:go_default_library",
"//beacon-chain/rpc/core:go_default_library",
"//beacon-chain/state:go_default_library",
"//beacon-chain/state/state-native:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//beacon-chain/sync:go_default_library",
"//cmd:go_default_library",

View File

@@ -15,6 +15,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/validators"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/core"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
"github.com/prysmaticlabs/prysm/v5/cmd"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
@@ -307,7 +308,11 @@ func (bs *Server) ListValidators(
if req.Active {
filteredValidators := make([]*ethpb.Validators_ValidatorContainer, 0)
for _, item := range validatorList {
if helpers.IsActiveValidator(item.Validator, requestedEpoch) {
roVal, err := state_native.NewValidator(item.Validator)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not create read-only validator: %v", err)
}
if helpers.IsActiveValidator(roVal, requestedEpoch) {
filteredValidators = append(filteredValidators, item)
}
}