Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ListBeaconCommittees RPC Method #3977

Merged
merged 108 commits into from
Nov 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
b3714e8
Update seed domains (#3872)
terencechain Oct 29, 2019
8eebd52
Remove Transfers (#3870)
terencechain Oct 29, 2019
b6645d6
Remove active index roots and compact committee roots (#3869)
terencechain Oct 30, 2019
cf169c8
Update inclusion reward (#3886)
terencechain Oct 30, 2019
6294037
Alter proposer selection logic (#3884)
terencechain Oct 30, 2019
d2f4b2b
Fix early committee bias (#3888)
terencechain Oct 30, 2019
c864627
Remove shards and committees (#3896)
terencechain Oct 31, 2019
2c88364
Epoch spec tests v0.9 (#3907)
terencechain Oct 31, 2019
acbc400
Block spec test v0.9 (#3905)
terencechain Nov 1, 2019
59f528f
Update deposit contract (#3906)
mcdee Nov 2, 2019
9bc9b91
Proto spec tests v0.9 (#3908)
terencechain Nov 2, 2019
2b87f39
Unskip block util tests (#3910)
terencechain Nov 2, 2019
064e963
Slot processing spec test V0.9 (#3912)
terencechain Nov 4, 2019
5d2f142
Unskip minimal spec test for finalization (#3920)
terencechain Nov 4, 2019
842a5ac
Remove outdated interop tests (#3922)
terencechain Nov 4, 2019
4e22ca2
Update validator to use proposer slot (#3919)
terencechain Nov 5, 2019
8617344
Fix committee assignment (#3931)
terencechain Nov 5, 2019
b20fc61
Replace shard with committee index (#3930)
terencechain Nov 5, 2019
03f2cb0
Conflict
terencechain Nov 6, 2019
6806e33
Conflict
terencechain Nov 6, 2019
a35da60
Clean up (#3933)
terencechain Nov 6, 2019
d5c2e0c
Remove shard filter in db (#3936)
terencechain Nov 6, 2019
4dab4c0
Merge branch 'master' into v0.9
terencechain Nov 6, 2019
53c4c18
Merge branch 'master' into v0.9
rauljordan Nov 6, 2019
45a88bb
Remove lightouse compatibility test (#3939)
terencechain Nov 6, 2019
a2814d6
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
terencechain Nov 6, 2019
d27bd4e
Merge branch 'master' of github.com:prysmaticlabs/prysm into v0.9
prestonvanloon Nov 6, 2019
29b6d18
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
terencechain Nov 6, 2019
4b4a761
Merge branch 'v0.9' of https://github.com/prysmaticlabs/prysm into v0.9
terencechain Nov 6, 2019
bb64762
Update Committee Cache for v0.9 (#3948)
terencechain Nov 7, 2019
1b1476b
Merge branch 'master' into v0.9
terencechain Nov 7, 2019
e6a487e
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
terencechain Nov 8, 2019
ddd4149
Conflict
terencechain Nov 8, 2019
b925684
Safeguard against nil head state
terencechain Nov 8, 2019
bbe9908
address edge case
nisdas Nov 8, 2019
6bec964
add test
nisdas Nov 8, 2019
29237a5
Merge remote-tracking branch 'origin/syncRejectionFix' into v0.9
terencechain Nov 8, 2019
166dc3b
Fixed TestRoundRobinSync by doubling the epochs
terencechain Nov 8, 2019
ad1daa1
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
terencechain Nov 8, 2019
df3f012
Unskip TestProtoCompatability (#3958)
terencechain Nov 8, 2019
ceddcf4
Fix minimal config (#3959)
prestonvanloon Nov 8, 2019
0438c52
Simplify verify att time (#3961)
terencechain Nov 9, 2019
e5ff555
Merge branch 'master' into v0.9
prestonvanloon Nov 10, 2019
4376e01
update readme for deposit contract, regen bindings for vyper 0.1.0b12…
prestonvanloon Nov 10, 2019
11cc97e
Check nil base state (#3964)
prestonvanloon Nov 10, 2019
4f2a781
Copy Block When Receiving it From Sync (#3966)
nisdas Nov 11, 2019
e2467ef
Change logging of Bitfield (#3956)
nisdas Nov 11, 2019
393e9b7
Merge branch 'master' into v0.9
rauljordan Nov 11, 2019
828046e
Unskip Beacon Server Test (#3962)
nisdas Nov 11, 2019
fce0fb4
Merge branch 'v0.9' of github.com:prysmaticlabs/prysm into v0.9
rauljordan Nov 11, 2019
d22319c
Merge branch 'master' into v0.9
prestonvanloon Nov 11, 2019
15a3da0
Merge branch 'v0.9' of github.com:prysmaticlabs/prysm into v0.9
rauljordan Nov 11, 2019
f38fb07
setup request/response types for the committees
rauljordan Nov 11, 2019
b9dce72
list beacon committees impl
rauljordan Nov 11, 2019
ec296e7
beacon committees fetch from archive
rauljordan Nov 11, 2019
3259f79
full list beacon committees implementation
rauljordan Nov 11, 2019
8a517cf
list beacon committees added more useful fields
rauljordan Nov 11, 2019
be31ef3
actually paginate
rauljordan Nov 11, 2019
88893da
attester server split into subpackage
rauljordan Nov 11, 2019
780a130
attester impl split up successfully
rauljordan Nov 11, 2019
47d0b96
validator cleaned up
rauljordan Nov 11, 2019
16489aa
all packages isolated
rauljordan Nov 11, 2019
42a89b3
master sync
rauljordan Nov 11, 2019
70ab2c8
include proposer
rauljordan Nov 11, 2019
2beddda
proper naming
rauljordan Nov 11, 2019
386e90b
test fix
rauljordan Nov 11, 2019
018f2c6
proper viz
rauljordan Nov 11, 2019
f9a555f
updated protos
rauljordan Nov 11, 2019
f028119
naming
rauljordan Nov 11, 2019
1392f11
resolved timeout due to config values
rauljordan Nov 12, 2019
e9d3b05
init use minimal
rauljordan Nov 12, 2019
629320d
added all subfiles
rauljordan Nov 12, 2019
64a256c
subfile split and gazelle
rauljordan Nov 12, 2019
7526b5b
shards
rauljordan Nov 12, 2019
c5d1879
validator folder
rauljordan Nov 12, 2019
adf1dda
cleanup val
rauljordan Nov 12, 2019
a17b4ed
shay feedback
rauljordan Nov 12, 2019
89a7dcd
confs
rauljordan Nov 12, 2019
b103c9c
include latest changes
rauljordan Nov 12, 2019
412dc8c
include committees
rauljordan Nov 12, 2019
de55d8a
initial pagination tests passing
rauljordan Nov 12, 2019
1891298
Merge branch 'master' into beacon-committees-rpc
rauljordan Nov 12, 2019
81f6166
paginated tests pass
rauljordan Nov 12, 2019
7f4300e
fix bug regarding total count
rauljordan Nov 12, 2019
f06df62
Merge branch 'beacon-committees-rpc' of github.com:prysmaticlabs/prys…
rauljordan Nov 12, 2019
a7dff12
pagination tests pass
rauljordan Nov 12, 2019
77e4f96
adding final test, archive
rauljordan Nov 12, 2019
1da9753
archive test works
rauljordan Nov 12, 2019
df35233
regen protos for archival
rauljordan Nov 12, 2019
450b50d
resolve broken test
rauljordan Nov 12, 2019
632a7a8
test pass
rauljordan Nov 12, 2019
a4e5965
broken archive test
rauljordan Nov 12, 2019
8b9b560
rem helpers
rauljordan Nov 12, 2019
ebfeb34
gaz
rauljordan Nov 12, 2019
aeb3557
fix kv test
rauljordan Nov 12, 2019
c1db234
useful gRPC error code standards
rauljordan Nov 12, 2019
4d6462a
format
rauljordan Nov 12, 2019
24d13e7
resolved bad test
rauljordan Nov 12, 2019
2fbc45a
test resolution
rauljordan Nov 12, 2019
4100411
ux improvements and bug fixes
rauljordan Nov 12, 2019
370db85
complete
rauljordan Nov 12, 2019
0bf6266
comments
rauljordan Nov 12, 2019
fc979b6
Update beacon-chain/archiver/service.go
rauljordan Nov 12, 2019
37f9b74
Update beacon-chain/rpc/beacon/committees.go
rauljordan Nov 12, 2019
3ead960
elim bad test
rauljordan Nov 12, 2019
7ea385a
Merge branch 'beacon-committees-rpc' of github.com:prysmaticlabs/prys…
rauljordan Nov 12, 2019
fc526b0
preston feedback
rauljordan Nov 13, 2019
f09c38b
Merge branch 'master' into beacon-committees-rpc
rauljordan Nov 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions beacon-chain/archiver/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ func (s *Service) Status() error {
// We archive committee information pertaining to the head state's epoch.
func (s *Service) archiveCommitteeInfo(ctx context.Context, headState *pb.BeaconState) error {
currentEpoch := helpers.SlotToEpoch(headState.Slot)
committeeCount, err := helpers.CommitteeCountAtSlot(headState, helpers.StartSlot(currentEpoch))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong, we shouldn't store this because it can change on a slot by slot basis

if err != nil {
return errors.Wrap(err, "could not get committee count")
}
proposerSeed, err := helpers.Seed(headState, currentEpoch, params.BeaconConfig().DomainBeaconProposer)
if err != nil {
return errors.Wrap(err, "could not generate seed")
Expand All @@ -83,9 +79,8 @@ func (s *Service) archiveCommitteeInfo(ctx context.Context, headState *pb.Beacon
}

info := &ethpb.ArchivedCommitteeInfo{
ProposerSeed: proposerSeed[:],
AttesterSeed: attesterSeed[:],
CommitteeCount: committeeCount * params.BeaconConfig().SlotsPerEpoch,
ProposerSeed: proposerSeed[:],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two seeds are really all we need to determine historical assignments alongside historical balances

AttesterSeed: attesterSeed[:],
}
if err := s.beaconDB.SaveArchivedCommitteeInfo(ctx, currentEpoch, info); err != nil {
return errors.Wrap(err, "could not archive committee info")
Expand Down
9 changes: 2 additions & 7 deletions beacon-chain/archiver/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,6 @@ func TestArchiverService_SavesCommitteeInfo(t *testing.T) {
triggerNewHeadEvent(t, svc, [32]byte{})

currentEpoch := helpers.CurrentEpoch(headState)
committeeCount, err := helpers.CommitteeCountAtSlot(headState, helpers.StartSlot(currentEpoch))
if err != nil {
t.Fatal(err)
}
proposerSeed, err := helpers.Seed(headState, currentEpoch, params.BeaconConfig().DomainBeaconProposer)
if err != nil {
t.Fatal(err)
Expand All @@ -141,9 +137,8 @@ func TestArchiverService_SavesCommitteeInfo(t *testing.T) {
t.Fatal(err)
}
wanted := &ethpb.ArchivedCommitteeInfo{
ProposerSeed: proposerSeed[:],
AttesterSeed: attesterSeed[:],
CommitteeCount: committeeCount * params.BeaconConfig().SlotsPerEpoch,
ProposerSeed: proposerSeed[:],
AttesterSeed: attesterSeed[:],
}

retrieved, err := svc.beaconDB.ArchivedCommitteeInfo(svc.ctx, helpers.CurrentEpoch(headState))
Expand Down
5 changes: 2 additions & 3 deletions beacon-chain/db/kv/archive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,8 @@ func TestStore_ArchivedCommitteeInfo(t *testing.T) {
ctx := context.Background()
someSeed := [32]byte{1, 2, 3}
info := &ethpb.ArchivedCommitteeInfo{
ProposerSeed: someSeed[:],
AttesterSeed: someSeed[:],
CommitteeCount: 4096,
ProposerSeed: someSeed[:],
AttesterSeed: someSeed[:],
}
epoch := uint64(10)
if err := db.SaveArchivedCommitteeInfo(ctx, epoch, info); err != nil {
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ func (b *BeaconNode) registerArchiverService(ctx *cli.Context) error {
}
svc := archiver.NewArchiverService(context.Background(), &archiver.Config{
BeaconDB: b.db,
HeadFetcher: chainService,
NewHeadNotifier: chainService,
})
return b.services.RegisterService(svc)
Expand Down
2 changes: 2 additions & 0 deletions beacon-chain/rpc/beacon/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ go_library(
"assignments.go",
"attestations.go",
"blocks.go",
"committees.go",
"server.go",
"validators.go",
],
Expand Down Expand Up @@ -39,6 +40,7 @@ go_test(
"assignments_test.go",
"attestations_test.go",
"blocks_test.go",
"committees_test.go",
"validators_test.go",
],
embed = [":go_default_library"],
Expand Down
4 changes: 2 additions & 2 deletions beacon-chain/rpc/beacon/assignments.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ func archivedValidatorCommittee(
activeIndices []uint64,
archivedBalances []uint64,
) ([]uint64, uint64, uint64, uint64, error) {
committeeCount := archivedInfo.CommitteeCount
proposerSeed := bytesutil.ToBytes32(archivedInfo.ProposerSeed)
attesterSeed := bytesutil.ToBytes32(archivedInfo.AttesterSeed)

Expand All @@ -188,7 +187,8 @@ func archivedValidatorCommittee(
}
for i := uint64(0); i < countAtSlot; i++ {
epochOffset := i + (slot%params.BeaconConfig().SlotsPerEpoch)*countAtSlot
committee, err := helpers.ComputeCommittee(activeIndices, attesterSeed, epochOffset, committeeCount)
totalCount := countAtSlot * params.BeaconConfig().SlotsPerEpoch
committee, err := helpers.ComputeCommittee(activeIndices, attesterSeed, epochOffset, totalCount)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a bug that was not caught earlier - the argument to ComputeCommittee needs to be the total committees count in that epoch

if err != nil {
return nil, 0, 0, 0, errors.Wrap(err, "could not compute committee")
}
Expand Down
20 changes: 8 additions & 12 deletions beacon-chain/rpc/beacon/assignments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"testing"

"github.com/prysmaticlabs/go-ssz"

mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
Expand Down Expand Up @@ -76,14 +75,17 @@ func TestServer_ListAssignments_Pagination_DefaultPageSize_NoArchive(t *testing.
// Mark the validators with index divisible by 3 inactive.
if i%3 == 0 {
validators = append(validators, &ethpb.Validator{
PublicKey: pubKey[:],
ExitEpoch: 0,
PublicKey: pubKey[:],
ExitEpoch: 0,
ActivationEpoch: 0,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
})
} else {
validators = append(validators, &ethpb.Validator{
PublicKey: pubKey[:],
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance,
ActivationEpoch: 0,
})
}
}
Expand Down Expand Up @@ -120,7 +122,6 @@ func TestServer_ListAssignments_Pagination_DefaultPageSize_NoArchive(t *testing.

res, err := bs.ListValidatorAssignments(context.Background(), &ethpb.ListValidatorAssignmentsRequest{
QueryFilter: &ethpb.ListValidatorAssignmentsRequest_Genesis{Genesis: true},
PublicKeys: [][]byte{[]byte("311")},
})
if err != nil {
t.Fatal(err)
Expand All @@ -147,7 +148,7 @@ func TestServer_ListAssignments_Pagination_DefaultPageSize_NoArchive(t *testing.
})
}

if !reflect.DeepEqual(res.Assignments[0], wanted[207]) {
if !reflect.DeepEqual(res.Assignments, wanted) {
t.Error("Did not receive wanted assignments")
}
}
Expand Down Expand Up @@ -219,10 +220,6 @@ func TestServer_ListAssignments_Pagination_DefaultPageSize_FromArchive(t *testin

// We then store archived data into the DB.
currentEpoch := helpers.CurrentEpoch(s)
committeeCount, err := helpers.CommitteeCountAtSlot(s, helpers.StartSlot(currentEpoch))
if err != nil {
t.Fatal(err)
}
proposerSeed, err := helpers.Seed(s, currentEpoch, params.BeaconConfig().DomainBeaconProposer)
if err != nil {
t.Fatal(err)
Expand All @@ -232,9 +229,8 @@ func TestServer_ListAssignments_Pagination_DefaultPageSize_FromArchive(t *testin
t.Fatal(err)
}
if err := db.SaveArchivedCommitteeInfo(context.Background(), 0, &ethpb.ArchivedCommitteeInfo{
ProposerSeed: proposerSeed[:],
AttesterSeed: attesterSeed[:],
CommitteeCount: committeeCount * params.BeaconConfig().SlotsPerEpoch,
ProposerSeed: proposerSeed[:],
AttesterSeed: attesterSeed[:],
}); err != nil {
t.Fatal(err)
}
Expand Down
151 changes: 151 additions & 0 deletions beacon-chain/rpc/beacon/committees.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package beacon

import (
"context"

"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/pagination"
"github.com/prysmaticlabs/prysm/shared/params"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// ListBeaconCommittees for a given epoch.
//
// If no filter criteria is specified, the response returns
// all beacon committees for the current epoch. The results are paginated by default.
func (bs *Server) ListBeaconCommittees(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this we might need more options for the req *ethpb.ListCommitteesRequest. Along with epoch we also need to give a query option, where we can provide the state root.

In the event of a fork in the network, you could have two chains with different committees at the same epoch. To differentiate on the two sets of committees we would need to be able to identify committees from forked chains, so the state root is a good way to identify them. @shayzluf and I discussed this offline, in the event of a fork in the network , we need to be able to get the appropriate committees from each forked chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point, that's a neat suggestion. So what happens if you provide a state root that doesnt match head state?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can do this in a follow-up PR as that will increase the diff quite a lot.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it would mean we are asking for the committees from a forked chain :) This would be important for the slasher, as it needs to be able to detect malicious attestations in the event of a fork. Sounds good, we can do it in a follow up PR

ctx context.Context,
req *ethpb.ListCommitteesRequest,
) (*ethpb.BeaconCommittees, error) {
if int(req.PageSize) > params.BeaconConfig().MaxPageSize {
return nil, status.Errorf(
codes.InvalidArgument,
"requested page size %d can not be greater than max size %d",
req.PageSize,
params.BeaconConfig().MaxPageSize,
)
}

headState := bs.HeadFetcher.HeadState()
var requestingGenesis bool
var startSlot uint64
switch q := req.QueryFilter.(type) {
case *ethpb.ListCommitteesRequest_Epoch:
startSlot = helpers.StartSlot(q.Epoch)
case *ethpb.ListCommitteesRequest_Genesis:
requestingGenesis = q.Genesis
default:
startSlot = headState.Slot
}

var attesterSeed [32]byte
var activeIndices []uint64
var err error
// This is the archival condition, if the requested epoch is < current epoch or if we are
// requesting data from the genesis epoch.
if requestingGenesis || helpers.SlotToEpoch(startSlot) < helpers.SlotToEpoch(headState.Slot) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the archival condition

activeIndices, err = helpers.ActiveValidatorIndices(headState, helpers.SlotToEpoch(startSlot))
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not retrieve active indices for epoch %d: %v",
helpers.SlotToEpoch(startSlot),
err,
)
}
archivedCommitteeInfo, err := bs.BeaconDB.ArchivedCommitteeInfo(ctx, helpers.SlotToEpoch(startSlot))
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not request archival data for epoch %d: %v",
helpers.SlotToEpoch(startSlot),
err,
)
}
if archivedCommitteeInfo == nil {
return nil, status.Errorf(
codes.NotFound,
"could not request data for epoch %d, perhaps --archive in the running beacon node is disabled",
helpers.SlotToEpoch(startSlot),
)
}
attesterSeed = bytesutil.ToBytes32(archivedCommitteeInfo.AttesterSeed)
} else if !requestingGenesis && helpers.SlotToEpoch(startSlot) == helpers.SlotToEpoch(headState.Slot) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise if requesting current epoch, return current results

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add these as comments? it seems helpful

// Otherwise, we use data from the current epoch.
currentEpoch := helpers.SlotToEpoch(headState.Slot)
activeIndices, err = helpers.ActiveValidatorIndices(headState, currentEpoch)
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not retrieve active indices for current epoch %d: %v",
currentEpoch,
err,
)
}
attesterSeed, err = helpers.Seed(headState, currentEpoch, params.BeaconConfig().DomainBeaconAttester)
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not retrieve attester seed for current epoch %d: %v",
currentEpoch,
err,
)
}
} else {
// Otherwise, we are requesting data from the future and we return an error.
return nil, status.Errorf(
codes.FailedPrecondition,
"cannot retrieve information about an epoch in the future, current epoch %d, requesting %d",
helpers.SlotToEpoch(headState.Slot),
helpers.StartSlot(startSlot),
)
}

committees := make([]*ethpb.BeaconCommittees_CommitteeItem, 0)
for slot := startSlot; slot < startSlot+params.BeaconConfig().SlotsPerEpoch; slot++ {
var countAtSlot = uint64(len(activeIndices)) / params.BeaconConfig().SlotsPerEpoch / params.BeaconConfig().TargetCommitteeSize
if countAtSlot > params.BeaconConfig().MaxCommitteesPerSlot {
countAtSlot = params.BeaconConfig().MaxCommitteesPerSlot
}
if countAtSlot == 0 {
countAtSlot = 1
}
for i := uint64(0); i < countAtSlot; i++ {
epochOffset := i + (slot%params.BeaconConfig().SlotsPerEpoch)*countAtSlot
totalCount := countAtSlot * params.BeaconConfig().SlotsPerEpoch
committee, err := helpers.ComputeCommittee(activeIndices, attesterSeed, epochOffset, totalCount)
if err != nil {
return nil, status.Errorf(
codes.Internal,
"could not compute committee for slot %d: %v",
slot,
err,
)
}
committees = append(committees, &ethpb.BeaconCommittees_CommitteeItem{
Committee: committee,
Slot: slot,
})
}
}

numCommittees := len(committees)
start, end, nextPageToken, err := pagination.StartAndEndPage(req.PageToken, int(req.PageSize), numCommittees)
if err != nil {
return nil, status.Errorf(
codes.FailedPrecondition,
"could not paginate results: %v",
err,
)
}
return &ethpb.BeaconCommittees{
Epoch: helpers.SlotToEpoch(startSlot),
ActiveValidatorCount: uint64(len(activeIndices)),
Committees: committees[start:end],
TotalSize: int32(numCommittees),
NextPageToken: nextPageToken,
}, nil
}
Loading