Fix InitializeProposerLookahead (#15450)

* Fix InitializeProposerLookahead

Get the right Active validator indices for each epoch after the fork
transition.

Co-Authored-By: Claude <noreply@anthropic.com>

* Add test

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com>
This commit is contained in:
Potuz
2025-07-16 00:16:11 -03:00
committed by GitHub
parent 4e5bfa9760
commit 3def16caaa
3 changed files with 49 additions and 4 deletions

View File

@@ -669,11 +669,11 @@ func ComputeCommittee(
// InitializeProposerLookahead computes the list of the proposer indices for the next MIN_SEED_LOOKAHEAD + 1 epochs.
func InitializeProposerLookahead(ctx context.Context, state state.ReadOnlyBeaconState, epoch primitives.Epoch) ([]uint64, error) {
lookAhead := make([]uint64, 0, uint64(params.BeaconConfig().MinSeedLookahead+1)*uint64(params.BeaconConfig().SlotsPerEpoch))
indices, err := ActiveValidatorIndices(ctx, state, epoch)
if err != nil {
return nil, errors.Wrap(err, "could not get active indices")
}
for i := range params.BeaconConfig().MinSeedLookahead + 1 {
indices, err := ActiveValidatorIndices(ctx, state, epoch+i)
if err != nil {
return nil, errors.Wrap(err, "could not get active indices")
}
proposerIndices, err := PrecomputeProposerIndices(state, indices, epoch+i)
if err != nil {
return nil, errors.Wrap(err, "could not compute proposer indices")

View File

@@ -916,3 +916,46 @@ func TestAssignmentForValidator(t *testing.T) {
require.DeepEqual(t, &helpers.LiteAssignment{}, got)
})
}
// Regression for #15450
func TestInitializeProposerLookahead_RegressionTest(t *testing.T) {
ctx := t.Context()
state, _ := util.DeterministicGenesisState(t, 128)
// Set some validators to activate in epoch 3 instead of 0
validators := state.Validators()
for i := 64; i < 128; i++ {
validators[i].ActivationEpoch = 3
}
require.NoError(t, state.SetValidators(validators))
require.NoError(t, state.SetSlot(64)) // epoch 2
epoch := slots.ToEpoch(state.Slot())
proposerLookahead, err := helpers.InitializeProposerLookahead(ctx, state, epoch)
require.NoError(t, err)
slotsPerEpoch := int(params.BeaconConfig().SlotsPerEpoch)
for epochOffset := primitives.Epoch(0); epochOffset < 2; epochOffset++ {
targetEpoch := epoch + epochOffset
activeIndices, err := helpers.ActiveValidatorIndices(ctx, state, targetEpoch)
require.NoError(t, err)
expectedProposers, err := helpers.PrecomputeProposerIndices(state, activeIndices, targetEpoch)
require.NoError(t, err)
startIdx := int(epochOffset) * slotsPerEpoch
endIdx := startIdx + slotsPerEpoch
actualProposers := proposerLookahead[startIdx:endIdx]
expectedUint64 := make([]uint64, len(expectedProposers))
for i, proposer := range expectedProposers {
expectedUint64[i] = uint64(proposer)
}
// This assertion would fail with the original bug:
for i, expected := range expectedUint64 {
require.Equal(t, expected, actualProposers[i],
"Proposer index mismatch at slot %d in epoch %d", i, targetEpoch)
}
}
}

View File

@@ -0,0 +1,2 @@
### Fixed
- Fixed lookahead initialization at the fulu fork.