Skip to content

Commit

Permalink
Simplify ExitedValidatorIndices (#14587)
Browse files Browse the repository at this point in the history
* fix

* add to comment

* modify test

* remove unused parameter

* changelog

* exclude ejected from exited

* fix linter

---------

Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
  • Loading branch information
saolyn and james-prysm authored Oct 31, 2024
1 parent 8fe024f commit f264680
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 53 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
- Updated the `beacon-chain/monitor` package to Electra. [PR](https://github.com/prysmaticlabs/prysm/pull/14562)
- Added ListAttestationsV2 endpoint.
- Add ability to rollback node's internal state during processing.
- Simplified `EjectedValidatorIndices`.

### Changed

Expand All @@ -36,6 +35,8 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
- Updated pgo profile for beacon chain with holesky data. This improves the profile guided
optimizations in the go compiler.
- Use read only state when computing the active validator list.
- Simplified `ExitedValidatorIndices`.
- Simplified `EjectedValidatorIndices`.

### Deprecated

Expand Down
38 changes: 8 additions & 30 deletions beacon-chain/core/validators/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,38 +241,16 @@ func SlashedValidatorIndices(epoch primitives.Epoch, validators []*ethpb.Validat
return slashed
}

// ExitedValidatorIndices determines the indices exited during the current epoch.
func ExitedValidatorIndices(epoch primitives.Epoch, validators []*ethpb.Validator, activeValidatorCount uint64) ([]primitives.ValidatorIndex, error) {
// ExitedValidatorIndices returns the indices of validators who exited during the specified epoch.
//
// A validator is considered to have exited during an epoch if their ExitEpoch equals the epoch and
// excludes validators that have been ejected.
// This function simplifies the exit determination by directly checking the validator's ExitEpoch,
// avoiding the complexities and potential inaccuracies of calculating withdrawable epochs.
func ExitedValidatorIndices(epoch primitives.Epoch, validators []*ethpb.Validator) ([]primitives.ValidatorIndex, error) {
exited := make([]primitives.ValidatorIndex, 0)
exitEpochs := make([]primitives.Epoch, 0)
for i := 0; i < len(validators); i++ {
val := validators[i]
if val.ExitEpoch != params.BeaconConfig().FarFutureEpoch {
exitEpochs = append(exitEpochs, val.ExitEpoch)
}
}
exitQueueEpoch := primitives.Epoch(0)
for _, i := range exitEpochs {
if exitQueueEpoch < i {
exitQueueEpoch = i
}
}

// We use the exit queue churn to determine if we have passed a churn limit.
exitQueueChurn := uint64(0)
for _, val := range validators {
if val.ExitEpoch == exitQueueEpoch {
exitQueueChurn++
}
}
churn := helpers.ValidatorExitChurnLimit(activeValidatorCount)
if churn < exitQueueChurn {
exitQueueEpoch++
}
withdrawableEpoch := exitQueueEpoch + params.BeaconConfig().MinValidatorWithdrawabilityDelay
for i, val := range validators {
if val.ExitEpoch == epoch && val.WithdrawableEpoch == withdrawableEpoch &&
val.EffectiveBalance > params.BeaconConfig().EjectionBalance {
if val.ExitEpoch == epoch && val.EffectiveBalance > params.BeaconConfig().EjectionBalance {
exited = append(exited, primitives.ValidatorIndex(i))
}
}
Expand Down
21 changes: 7 additions & 14 deletions beacon-chain/core/validators/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,19 +389,16 @@ func TestExitedValidatorIndices(t *testing.T) {
state: &ethpb.BeaconState{
Validators: []*ethpb.Validator{
{
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
ExitEpoch: 0,
WithdrawableEpoch: params.BeaconConfig().MinValidatorWithdrawabilityDelay,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
ExitEpoch: 0,
},
{
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
ExitEpoch: 0,
WithdrawableEpoch: 10,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
ExitEpoch: 10,
},
{
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
ExitEpoch: 0,
WithdrawableEpoch: params.BeaconConfig().MinValidatorWithdrawabilityDelay,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
ExitEpoch: 0,
},
},
},
Expand Down Expand Up @@ -433,11 +430,7 @@ func TestExitedValidatorIndices(t *testing.T) {
},
}
for _, tt := range tests {
s, err := state_native.InitializeFromProtoPhase0(tt.state)
require.NoError(t, err)
activeCount, err := helpers.ActiveValidatorCount(context.Background(), s, time.PrevEpoch(s))
require.NoError(t, err)
exitedIndices, err := validators.ExitedValidatorIndices(0, tt.state.Validators, activeCount)
exitedIndices, err := validators.ExitedValidatorIndices(0, tt.state.Validators)
require.NoError(t, err)
assert.DeepEqual(t, tt.wanted, exitedIndices)
}
Expand Down
9 changes: 1 addition & 8 deletions beacon-chain/rpc/core/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -869,16 +869,9 @@ func (s *Service) ValidatorActiveSetChanges(
}
}

activeValidatorCount, err := helpers.ActiveValidatorCount(ctx, requestedState, coreTime.CurrentEpoch(requestedState))
if err != nil {
return nil, &RpcError{
Err: errors.Wrap(err, "could not get active validator count"),
Reason: Internal,
}
}
vs := requestedState.Validators()
activatedIndices := validators.ActivatedValidatorIndices(coreTime.CurrentEpoch(requestedState), vs)
exitedIndices, err := validators.ExitedValidatorIndices(coreTime.CurrentEpoch(requestedState), vs, activeValidatorCount)
exitedIndices, err := validators.ExitedValidatorIndices(coreTime.CurrentEpoch(requestedState), vs)
if err != nil {
return nil, &RpcError{
Err: errors.Wrap(err, "could not determine exited validator indices"),
Expand Down

0 comments on commit f264680

Please sign in to comment.