package beacon import ( "context" "testing" types "github.com/prysmaticlabs/eth2-types" "github.com/prysmaticlabs/prysm/beacon-chain/rpc/testutil" ethpbv2 "github.com/prysmaticlabs/prysm/proto/eth/v2" ethpbalpha "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/shared/bytesutil" "github.com/prysmaticlabs/prysm/shared/params" sharedtestutil "github.com/prysmaticlabs/prysm/shared/testutil" "github.com/prysmaticlabs/prysm/shared/testutil/assert" "github.com/prysmaticlabs/prysm/shared/testutil/require" ) func Test_currentCommitteeIndicesFromState(t *testing.T) { st, _ := sharedtestutil.DeterministicGenesisStateAltair(t, params.BeaconConfig().SyncCommitteeSize) vals := st.Validators() wantedCommittee := make([][]byte, params.BeaconConfig().SyncCommitteeSize) wantedIndices := make([]types.ValidatorIndex, len(wantedCommittee)) for i := 0; i < len(wantedCommittee); i++ { wantedIndices[i] = types.ValidatorIndex(i) wantedCommittee[i] = vals[i].PublicKey } require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{ Pubkeys: wantedCommittee, AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength), })) t.Run("OK", func(t *testing.T) { indices, committee, err := currentCommitteeIndicesFromState(st) require.NoError(t, err) require.DeepEqual(t, wantedIndices, indices) require.DeepEqual(t, wantedCommittee, committee.Pubkeys) }) t.Run("validator in committee not found in state", func(t *testing.T) { wantedCommittee[0] = bytesutil.PadTo([]byte("fakepubkey"), 48) require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{ Pubkeys: wantedCommittee, AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength), })) _, _, err := currentCommitteeIndicesFromState(st) require.ErrorContains(t, "index not found for pubkey", err) }) } func Test_extractSyncSubcommittees(t *testing.T) { st, _ := sharedtestutil.DeterministicGenesisStateAltair(t, params.BeaconConfig().SyncCommitteeSize) vals := st.Validators() syncCommittee := make([][]byte, params.BeaconConfig().SyncCommitteeSize) for i := 0; i < len(syncCommittee); i++ { syncCommittee[i] = vals[i].PublicKey } require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{ Pubkeys: syncCommittee, AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength), })) commSize := params.BeaconConfig().SyncCommitteeSize subCommSize := params.BeaconConfig().SyncCommitteeSize / params.BeaconConfig().SyncCommitteeSubnetCount wantedSubcommitteeValidators := make([][]types.ValidatorIndex, 0) for i := uint64(0); i < commSize; i += subCommSize { sub := make([]types.ValidatorIndex, 0) start := i end := i + subCommSize if end > commSize { end = commSize } for j := start; j < end; j++ { sub = append(sub, types.ValidatorIndex(j)) } wantedSubcommitteeValidators = append(wantedSubcommitteeValidators, sub) } t.Run("OK", func(t *testing.T) { committee, err := st.CurrentSyncCommittee() require.NoError(t, err) subcommittee, err := extractSyncSubcommittees(st, committee) require.NoError(t, err) for i, got := range subcommittee { want := wantedSubcommitteeValidators[i] require.DeepEqual(t, want, got.Validators) } }) t.Run("validator in subcommittee not found in state", func(t *testing.T) { syncCommittee[0] = bytesutil.PadTo([]byte("fakepubkey"), 48) require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{ Pubkeys: syncCommittee, AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength), })) committee, err := st.CurrentSyncCommittee() require.NoError(t, err) _, err = extractSyncSubcommittees(st, committee) require.ErrorContains(t, "index not found for pubkey", err) }) } func TestListSyncCommittees(t *testing.T) { ctx := context.Background() st, _ := sharedtestutil.DeterministicGenesisStateAltair(t, params.BeaconConfig().SyncCommitteeSize) syncCommittee := make([][]byte, params.BeaconConfig().SyncCommitteeSize) vals := st.Validators() for i := 0; i < len(syncCommittee); i++ { syncCommittee[i] = vals[i].PublicKey } require.NoError(t, st.SetCurrentSyncCommittee(ðpbalpha.SyncCommittee{ Pubkeys: syncCommittee, AggregatePubkey: bytesutil.PadTo([]byte{}, params.BeaconConfig().BLSPubkeyLength), })) stRoot, err := st.HashTreeRoot(ctx) require.NoError(t, err) s := &Server{ StateFetcher: &testutil.MockFetcher{ BeaconState: st, }, } req := ðpbv2.StateSyncCommitteesRequest{StateId: stRoot[:]} resp, err := s.ListSyncCommittees(ctx, req) require.NoError(t, err) require.NotNil(t, resp.Data) committeeVals := resp.Data.Validators require.NotNil(t, committeeVals) require.Equal(t, params.BeaconConfig().SyncCommitteeSize, uint64(len(committeeVals)), "incorrect committee size") for i := uint64(0); i < params.BeaconConfig().SyncCommitteeSize; i++ { assert.Equal(t, types.ValidatorIndex(i), committeeVals[i]) } require.NotNil(t, resp.Data.ValidatorAggregates) assert.Equal(t, params.BeaconConfig().SyncCommitteeSubnetCount, uint64(len(resp.Data.ValidatorAggregates))) for i := uint64(0); i < params.BeaconConfig().SyncCommitteeSubnetCount; i++ { vStartIndex := types.ValidatorIndex(params.BeaconConfig().SyncCommitteeSize / params.BeaconConfig().SyncCommitteeSubnetCount * i) vEndIndex := types.ValidatorIndex(params.BeaconConfig().SyncCommitteeSize/params.BeaconConfig().SyncCommitteeSubnetCount*(i+1) - 1) j := 0 for vIndex := vStartIndex; vIndex <= vEndIndex; vIndex++ { assert.Equal(t, vIndex, resp.Data.ValidatorAggregates[i].Validators[j]) j++ } } }