Skip to content

Commit

Permalink
Use BeaconCommittees helper to get the ptc (#14286)
Browse files Browse the repository at this point in the history
  • Loading branch information
potuz committed Aug 2, 2024
1 parent fa979b4 commit 8ec449e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 69 deletions.
4 changes: 4 additions & 0 deletions beacon-chain/core/helpers/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/cache:go_default_library",
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/forkchoice/types:go_default_library",
"//beacon-chain/state:go_default_library",
Expand Down Expand Up @@ -72,6 +73,7 @@ go_test(
tags = ["CI_race_detection"],
deps = [
"//beacon-chain/cache:go_default_library",
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/forkchoice/types:go_default_library",
"//beacon-chain/state:go_default_library",
Expand All @@ -81,7 +83,9 @@ go_test(
"//consensus-types/epbs:go_default_library",
"//consensus-types/primitives:go_default_library",
"//container/slice:go_default_library",
"//crypto/bls:go_default_library",
"//crypto/hash:go_default_library",
"//crypto/rand:go_default_library",
"//encoding/bytesutil:go_default_library",
"//math:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
Expand Down
67 changes: 18 additions & 49 deletions beacon-chain/core/helpers/beacon_committee.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ func CommitteeAssignments(ctx context.Context, state state.BeaconState, epoch pr
if err := verifyAssignmentEpoch(epoch, state); err != nil {
return nil, err
}
startSlot, err := slots.EpochStart(epoch)
slot, err := slots.EpochStart(epoch)
if err != nil {
return nil, err
}
Expand All @@ -305,20 +305,16 @@ func CommitteeAssignments(ctx context.Context, state state.BeaconState, epoch pr
}
assignments := make(map[primitives.ValidatorIndex]*CommitteeAssignment)

activeValidatorCount, err := ActiveValidatorCount(ctx, state, epoch)
committees, err := BeaconCommittees(ctx, state, slot)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "could not compute beacon committees")
}
ptcPerSlot, PtcMembersPerCommittee := PtcAllocation(activeValidatorCount)

ptcPerSlot, ptcMembersPerCommittee := PtcAllocation(len(committees))
// Compute committee assignments for each slot in the epoch.
for slot := startSlot; slot < startSlot+params.BeaconConfig().SlotsPerEpoch; slot++ {
committees, err := BeaconCommittees(ctx, state, slot)
if err != nil {
return nil, errors.Wrap(err, "could not compute beacon committees")
}
endSlot := slot + params.BeaconConfig().SlotsPerEpoch
for {
for j, committee := range committees {
for _, vIndex := range committee {
for i, vIndex := range committee {
if _, ok := vals[vIndex]; !ok { // Skip if the validator is not in the provided validators slice.
continue
}
Expand All @@ -328,48 +324,21 @@ func CommitteeAssignments(ctx context.Context, state state.BeaconState, epoch pr
assignments[vIndex].Committee = committee
assignments[vIndex].AttesterSlot = slot
assignments[vIndex].CommitteeIndex = primitives.CommitteeIndex(j)
}

// We only need to assign PTC slots for the first `PTCPerSlot` committees of a given slot.
if uint64(j) < ptcPerSlot {
assignments = PTCAssignments(committee, assignments, PtcMembersPerCommittee, slot)
if uint64(j) < ptcPerSlot && uint64(i) < ptcMembersPerCommittee {
assignments[vIndex].PtcSlot = slot
}
}
}
}
return assignments, nil
}

// PTCAssignments updates the PTC slot assignments for the given committee members.
// committee: a slice of ValidatorIndex representing committee members.
// assignments: a map of ValidatorIndex to CommitteeAssignment where assignments will be updated.
// membersPerCommittee: the number of members to be assigned to the PTC committee.
// slot: the slot to be assigned for PTC assignment.
// Returns the updated assignments map.
func PTCAssignments(committee []primitives.ValidatorIndex,
assignments map[primitives.ValidatorIndex]*CommitteeAssignment,
membersPerCommittee uint64,
slot primitives.Slot) map[primitives.ValidatorIndex]*CommitteeAssignment {
committeeLength := uint64(len(committee))
// If the number of PTC members is greater than Beacon members,
// return the current assignments without changes.
if membersPerCommittee > committeeLength {
return assignments
}

// Loop through the selected committee members for PTC assignments.
for i := uint64(0); i < membersPerCommittee; i++ {
vIndex := committee[i]

assignment, exists := assignments[vIndex]
if !exists {
assignment = &CommitteeAssignment{}
assignments[vIndex] = assignment
slot++
if slot == endSlot {
break
}
committees, err = BeaconCommittees(ctx, state, slot)
if err != nil {
return nil, errors.Wrap(err, "could not compute beacon committees")
}

assignment.PtcSlot = slot
}

return assignments
return assignments, nil
}

// VerifyBitfieldLength verifies that a bitfield length matches the given committee size.
Expand Down
19 changes: 8 additions & 11 deletions beacon-chain/core/helpers/payload_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,14 @@ func GetPayloadTimelinessCommittee(ctx context.Context, state state.ReadOnlyBeac
if state.Version() < version.EPBS {
return nil, errPreEPBSState
}
epoch := slots.ToEpoch(slot)
activeCount, err := ActiveValidatorCount(ctx, state, epoch)
committees, err := BeaconCommittees(ctx, state, slot)
if err != nil {
return nil, errors.Wrap(err, "could not compute active validator count")
return nil, errors.Wrap(err, "could not get beacon committees")
}
committeesPerSlot, membersPerCommittee := PtcAllocation(activeCount)
for i := uint64(0); i < committeesPerSlot; i++ {
committee, err := BeaconCommitteeFromState(ctx, state, slot, primitives.CommitteeIndex(i))
if err != nil {
return nil, err
committeesPerSlot, membersPerCommittee := PtcAllocation(len(committees))
for i, committee := range committees {
if uint64(i) >= committeesPerSlot {
return
}
if uint64(len(committee)) < membersPerCommittee {
return nil, errCommitteeOverflow
Expand All @@ -96,9 +94,8 @@ func GetPayloadTimelinessCommittee(ctx context.Context, state state.ReadOnlyBeac
// PtcAllocation returns:
// 1. The number of beacon committees that PTC will borrow from in a slot.
// 2. The number of validators that PTC will borrow from in a beacon committee.
func PtcAllocation(totalActive uint64) (committeesPerSlot, membersPerCommittee uint64) {
slotCommittees := SlotCommitteeCount(totalActive)
committeesPerSlot = math.LargestPowerOfTwo(math.Min(slotCommittees, fieldparams.PTCSize))
func PtcAllocation(slotCommittees int) (committeesPerSlot, membersPerCommittee uint64) {
committeesPerSlot = math.LargestPowerOfTwo(math.Min(uint64(slotCommittees), fieldparams.PTCSize))
membersPerCommittee = fieldparams.PTCSize / committeesPerSlot
return
}
Expand Down
18 changes: 9 additions & 9 deletions beacon-chain/core/helpers/payload_attestation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,24 @@ func TestGetPayloadTimelinessCommittee(t *testing.T) {

func Test_PtcAllocation(t *testing.T) {
tests := []struct {
totalActive uint64
committeeCount int
memberPerCommittee uint64
committeesPerSlot uint64
}{
{64, 512, 1},
{params.BeaconConfig().MinGenesisActiveValidatorCount, 128, 4},
{25600, 128, 4},
{256000, 16, 32},
{1024000, 8, 64},
{1, 512, 1},
{4, 128, 4},
{128, 4, 128},
{512, 1, 512},
{1024, 1, 512},
}

for _, test := range tests {
committeesPerSlot, memberPerCommittee := helpers.PtcAllocation(test.totalActive)
committeesPerSlot, memberPerCommittee := helpers.PtcAllocation(test.committeeCount)
if memberPerCommittee != test.memberPerCommittee {
t.Errorf("memberPerCommittee(%d) = %d; expected %d", test.totalActive, memberPerCommittee, test.memberPerCommittee)
t.Errorf("memberPerCommittee(%d) = %d; expected %d", test.committeeCount, memberPerCommittee, test.memberPerCommittee)
}
if committeesPerSlot != test.committeesPerSlot {
t.Errorf("committeesPerSlot(%d) = %d; expected %d", test.totalActive, committeesPerSlot, test.committeesPerSlot)
t.Errorf("committeesPerSlot(%d) = %d; expected %d", test.committeeCount, committeesPerSlot, test.committeesPerSlot)
}
}
}
Expand Down

0 comments on commit 8ec449e

Please sign in to comment.