mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
fix: reject out-of-range attestation committee index (#15855)
* reject committee index >= committees_per_slot in unaggregated attestation validation * Create phrwlk_fix-attestation-committee-index-bound.md * add a unit test * fix test * fixing test --------- Co-authored-by: james-prysm <90280386+james-prysm@users.noreply.github.com> Co-authored-by: james-prysm <james@prysmaticlabs.com>
This commit is contained in:
@@ -94,9 +94,11 @@ func TestVerifyIndexInCommittee_ExistsInBeaconCommittee(t *testing.T) {
|
||||
assert.ErrorContains(t, wanted, err)
|
||||
assert.Equal(t, pubsub.ValidationReject, result)
|
||||
|
||||
att.Data.CommitteeIndex = 10000
|
||||
// Test the edge case where committee index equals count (should be rejected)
|
||||
// With 64 validators and minimal config, count = 2, so valid indices are 0 and 1
|
||||
att.Data.CommitteeIndex = 2
|
||||
_, _, result, err = service.validateCommitteeIndexAndCount(ctx, att, s)
|
||||
require.ErrorContains(t, "committee index 10000 > 2", err)
|
||||
require.ErrorContains(t, "committee index 2 >= 2", err)
|
||||
assert.Equal(t, pubsub.ValidationReject, result)
|
||||
}
|
||||
|
||||
|
||||
@@ -278,8 +278,8 @@ func (s *Service) validateCommitteeIndexAndCount(
|
||||
} else {
|
||||
ci = a.GetCommitteeIndex()
|
||||
}
|
||||
if uint64(ci) > count {
|
||||
return 0, 0, pubsub.ValidationReject, fmt.Errorf("committee index %d > %d", ci, count)
|
||||
if uint64(ci) >= count {
|
||||
return 0, 0, pubsub.ValidationReject, fmt.Errorf("committee index %d >= %d", ci, count)
|
||||
}
|
||||
return ci, valCount, pubsub.ValidationAccept, nil
|
||||
}
|
||||
|
||||
@@ -611,3 +611,41 @@ func TestService_setSeenUnaggregatedAtt(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func Test_validateCommitteeIndexAndCount_Boundary(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
|
||||
// Create a minimal state with a known number of validators.
|
||||
validators := uint64(64)
|
||||
bs, _ := util.DeterministicGenesisState(t, validators)
|
||||
require.NoError(t, bs.SetSlot(1))
|
||||
|
||||
s := &Service{}
|
||||
|
||||
// Build a minimal Phase0 attestation (unaggregated path).
|
||||
att := ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
CommitteeIndex: 0,
|
||||
},
|
||||
}
|
||||
|
||||
// First call to obtain the active validator count used to derive committees per slot.
|
||||
_, valCount, res, err := s.validateCommitteeIndexAndCount(ctx, att, bs)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pubsub.ValidationAccept, res)
|
||||
|
||||
count := helpers.SlotCommitteeCount(valCount)
|
||||
|
||||
// committee_index == count - 1 should be accepted.
|
||||
att.Data.CommitteeIndex = primitives.CommitteeIndex(count - 1)
|
||||
_, _, res, err = s.validateCommitteeIndexAndCount(ctx, att, bs)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pubsub.ValidationAccept, res)
|
||||
|
||||
// committee_index == count should be rejected (out of range).
|
||||
att.Data.CommitteeIndex = primitives.CommitteeIndex(count)
|
||||
_, _, res, err = s.validateCommitteeIndexAndCount(ctx, att, bs)
|
||||
require.ErrorContains(t, "committee index", err)
|
||||
require.Equal(t, pubsub.ValidationReject, res)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
### Fixed
|
||||
|
||||
- reject committee index >= committees_per_slot in unaggregated attestation validation
|
||||
Reference in New Issue
Block a user