mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Optimize SubscribeCommitteeSubnets VC action (#13702)
* Optimize `SubscribeCommitteeSubnets` VC action * test fixes * remove newline * review
This commit is contained in:
1742
proto/prysm/v1alpha1/beacon_block.pb.go
generated
1742
proto/prysm/v1alpha1/beacon_block.pb.go
generated
File diff suppressed because it is too large
Load Diff
1249
proto/prysm/v1alpha1/validator.pb.go
generated
1249
proto/prysm/v1alpha1/validator.pb.go
generated
File diff suppressed because it is too large
Load Diff
@@ -537,6 +537,9 @@ message DutiesResponse {
|
||||
|
||||
// Whether the validator belongs in the sync committee and has to perform sync committee duty.
|
||||
bool is_sync_committee = 8;
|
||||
|
||||
// The number of committees in the duty's slot.
|
||||
uint64 committees_at_slot = 9;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ go_library(
|
||||
importpath = "github.com/prysmaticlabs/prysm/v5/testing/validator-mock",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//validator/client/iface:go_default_library",
|
||||
|
||||
3
testing/validator-mock/validator_client_mock.go
generated
3
testing/validator-mock/validator_client_mock.go
generated
@@ -13,7 +13,6 @@ import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
primitives "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
@@ -402,7 +401,7 @@ func (mr *MockValidatorClientMockRecorder) SubmitValidatorRegistrations(arg0, ar
|
||||
}
|
||||
|
||||
// SubscribeCommitteeSubnets mocks base method.
|
||||
func (m *MockValidatorClient) SubscribeCommitteeSubnets(arg0 context.Context, arg1 *eth.CommitteeSubnetsSubscribeRequest, arg2 []primitives.ValidatorIndex) (*emptypb.Empty, error) {
|
||||
func (m *MockValidatorClient) SubscribeCommitteeSubnets(arg0 context.Context, arg1 *eth.CommitteeSubnetsSubscribeRequest, arg2 []*eth.DutiesResponse_Duty) (*emptypb.Empty, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SubscribeCommitteeSubnets", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(*emptypb.Empty)
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
|
||||
@@ -174,9 +173,9 @@ func (c *beaconApiValidatorClient) SubmitValidatorRegistrations(ctx context.Cont
|
||||
})
|
||||
}
|
||||
|
||||
func (c *beaconApiValidatorClient) SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, validatorIndices []primitives.ValidatorIndex) (*empty.Empty, error) {
|
||||
func (c *beaconApiValidatorClient) SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, duties []*ethpb.DutiesResponse_Duty) (*empty.Empty, error) {
|
||||
return wrapInMetrics[*empty.Empty]("SubscribeCommitteeSubnets", func() (*empty.Empty, error) {
|
||||
return new(empty.Empty), c.subscribeCommitteeSubnets(ctx, in, validatorIndices)
|
||||
return new(empty.Empty), c.subscribeCommitteeSubnets(ctx, in, duties)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,14 @@ func (c beaconApiValidatorClient) getDutiesForEpoch(
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get committees for epoch `%d`", epoch)
|
||||
}
|
||||
slotCommittees := make(map[string]uint64)
|
||||
for _, c := range committees {
|
||||
n, ok := slotCommittees[c.Slot]
|
||||
if !ok {
|
||||
n = 0
|
||||
}
|
||||
slotCommittees[c.Slot] = n + 1
|
||||
}
|
||||
|
||||
// Mapping from a validator index to its attesting committee's index and slot
|
||||
attesterDutiesMapping := make(map[primitives.ValidatorIndex]committeeIndexSlotPair)
|
||||
@@ -195,14 +203,15 @@ func (c beaconApiValidatorClient) getDutiesForEpoch(
|
||||
}
|
||||
|
||||
duties[index] = ðpb.DutiesResponse_Duty{
|
||||
Committee: committeeValidatorIndices,
|
||||
CommitteeIndex: committeeIndex,
|
||||
AttesterSlot: attesterSlot,
|
||||
ProposerSlots: proposerDutySlots[validatorIndex],
|
||||
PublicKey: pubkey,
|
||||
Status: validatorStatus.Status,
|
||||
ValidatorIndex: validatorIndex,
|
||||
IsSyncCommittee: syncDutiesMapping[validatorIndex],
|
||||
Committee: committeeValidatorIndices,
|
||||
CommitteeIndex: committeeIndex,
|
||||
AttesterSlot: attesterSlot,
|
||||
ProposerSlots: proposerDutySlots[validatorIndex],
|
||||
PublicKey: pubkey,
|
||||
Status: validatorStatus.Status,
|
||||
ValidatorIndex: validatorIndex,
|
||||
IsSyncCommittee: syncDutiesMapping[validatorIndex],
|
||||
CommitteesAtSlot: slotCommittees[strconv.FormatUint(uint64(attesterSlot), 10)],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -880,69 +880,75 @@ func TestGetDutiesForEpoch_Valid(t *testing.T) {
|
||||
validatorIndices[0],
|
||||
validatorIndices[1],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[0],
|
||||
AttesterSlot: committeeSlots[0],
|
||||
PublicKey: pubkeys[0],
|
||||
Status: statuses[0],
|
||||
ValidatorIndex: validatorIndices[0],
|
||||
CommitteeIndex: committeeIndices[0],
|
||||
AttesterSlot: committeeSlots[0],
|
||||
PublicKey: pubkeys[0],
|
||||
Status: statuses[0],
|
||||
ValidatorIndex: validatorIndices[0],
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[0],
|
||||
validatorIndices[1],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[0],
|
||||
AttesterSlot: committeeSlots[0],
|
||||
PublicKey: pubkeys[1],
|
||||
Status: statuses[1],
|
||||
ValidatorIndex: validatorIndices[1],
|
||||
CommitteeIndex: committeeIndices[0],
|
||||
AttesterSlot: committeeSlots[0],
|
||||
PublicKey: pubkeys[1],
|
||||
Status: statuses[1],
|
||||
ValidatorIndex: validatorIndices[1],
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[2],
|
||||
validatorIndices[3],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[1],
|
||||
AttesterSlot: committeeSlots[1],
|
||||
PublicKey: pubkeys[2],
|
||||
Status: statuses[2],
|
||||
ValidatorIndex: validatorIndices[2],
|
||||
CommitteeIndex: committeeIndices[1],
|
||||
AttesterSlot: committeeSlots[1],
|
||||
PublicKey: pubkeys[2],
|
||||
Status: statuses[2],
|
||||
ValidatorIndex: validatorIndices[2],
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[2],
|
||||
validatorIndices[3],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[1],
|
||||
AttesterSlot: committeeSlots[1],
|
||||
PublicKey: pubkeys[3],
|
||||
Status: statuses[3],
|
||||
ValidatorIndex: validatorIndices[3],
|
||||
CommitteeIndex: committeeIndices[1],
|
||||
AttesterSlot: committeeSlots[1],
|
||||
PublicKey: pubkeys[3],
|
||||
Status: statuses[3],
|
||||
ValidatorIndex: validatorIndices[3],
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[4],
|
||||
validatorIndices[5],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[2],
|
||||
AttesterSlot: committeeSlots[2],
|
||||
PublicKey: pubkeys[4],
|
||||
Status: statuses[4],
|
||||
ValidatorIndex: validatorIndices[4],
|
||||
ProposerSlots: expectedProposerSlots1,
|
||||
CommitteeIndex: committeeIndices[2],
|
||||
AttesterSlot: committeeSlots[2],
|
||||
PublicKey: pubkeys[4],
|
||||
Status: statuses[4],
|
||||
ValidatorIndex: validatorIndices[4],
|
||||
ProposerSlots: expectedProposerSlots1,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
Committee: []primitives.ValidatorIndex{
|
||||
validatorIndices[4],
|
||||
validatorIndices[5],
|
||||
},
|
||||
CommitteeIndex: committeeIndices[2],
|
||||
AttesterSlot: committeeSlots[2],
|
||||
PublicKey: pubkeys[5],
|
||||
Status: statuses[5],
|
||||
ValidatorIndex: validatorIndices[5],
|
||||
ProposerSlots: expectedProposerSlots2,
|
||||
IsSyncCommittee: testCase.fetchSyncDuties,
|
||||
CommitteeIndex: committeeIndices[2],
|
||||
AttesterSlot: committeeSlots[2],
|
||||
PublicKey: pubkeys[5],
|
||||
Status: statuses[5],
|
||||
ValidatorIndex: validatorIndices[5],
|
||||
ProposerSlots: expectedProposerSlots2,
|
||||
IsSyncCommittee: testCase.fetchSyncDuties,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
PublicKey: pubkeys[6],
|
||||
|
||||
@@ -8,63 +8,26 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/api/server/structs"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
)
|
||||
|
||||
func (c beaconApiValidatorClient) subscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, validatorIndices []primitives.ValidatorIndex) error {
|
||||
func (c beaconApiValidatorClient) subscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, duties []*ethpb.DutiesResponse_Duty) error {
|
||||
if in == nil {
|
||||
return errors.New("committee subnets subscribe request is nil")
|
||||
}
|
||||
|
||||
if len(in.CommitteeIds) != len(in.Slots) || len(in.CommitteeIds) != len(in.IsAggregator) || len(in.CommitteeIds) != len(validatorIndices) {
|
||||
return errors.New("arrays `in.CommitteeIds`, `in.Slots`, `in.IsAggregator` and `validatorIndices` don't have the same length")
|
||||
if len(in.CommitteeIds) != len(in.Slots) || len(in.CommitteeIds) != len(in.IsAggregator) || len(in.CommitteeIds) != len(duties) {
|
||||
return errors.New("arrays `in.CommitteeIds`, `in.Slots`, `in.IsAggregator` and `duties` don't have the same length")
|
||||
}
|
||||
|
||||
slotToCommitteesAtSlotMap := make(map[primitives.Slot]uint64)
|
||||
jsonCommitteeSubscriptions := make([]*structs.BeaconCommitteeSubscription, len(in.CommitteeIds))
|
||||
for index := range in.CommitteeIds {
|
||||
subscribeSlot := in.Slots[index]
|
||||
subscribeCommitteeId := in.CommitteeIds[index]
|
||||
subscribeIsAggregator := in.IsAggregator[index]
|
||||
subscribeValidatorIndex := validatorIndices[index]
|
||||
|
||||
committeesAtSlot, foundSlot := slotToCommitteesAtSlotMap[subscribeSlot]
|
||||
if !foundSlot {
|
||||
// Lazily fetch the committeesAtSlot from the beacon node if they are not already in the map
|
||||
epoch := slots.ToEpoch(subscribeSlot)
|
||||
duties, err := c.dutiesProvider.GetAttesterDuties(ctx, epoch, validatorIndices)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get duties for epoch `%d`", epoch)
|
||||
}
|
||||
|
||||
for _, duty := range duties {
|
||||
dutySlot, err := strconv.ParseUint(duty.Slot, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse slot `%s`", duty.Slot)
|
||||
}
|
||||
|
||||
committees, err := strconv.ParseUint(duty.CommitteesAtSlot, 10, 64)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse CommitteesAtSlot `%s`", duty.CommitteesAtSlot)
|
||||
}
|
||||
|
||||
slotToCommitteesAtSlotMap[primitives.Slot(dutySlot)] = committees
|
||||
}
|
||||
|
||||
// If the slot still isn't in the map, we either received bad data from the beacon node or the caller of this function gave us bad data
|
||||
if committeesAtSlot, foundSlot = slotToCommitteesAtSlotMap[subscribeSlot]; !foundSlot {
|
||||
return errors.Errorf("failed to get committees for slot `%d`", subscribeSlot)
|
||||
}
|
||||
}
|
||||
|
||||
jsonCommitteeSubscriptions[index] = &structs.BeaconCommitteeSubscription{
|
||||
CommitteeIndex: strconv.FormatUint(uint64(subscribeCommitteeId), 10),
|
||||
CommitteesAtSlot: strconv.FormatUint(committeesAtSlot, 10),
|
||||
Slot: strconv.FormatUint(uint64(subscribeSlot), 10),
|
||||
IsAggregator: subscribeIsAggregator,
|
||||
ValidatorIndex: strconv.FormatUint(uint64(subscribeValidatorIndex), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(in.CommitteeIds[index]), 10),
|
||||
CommitteesAtSlot: strconv.FormatUint(duties[index].CommitteesAtSlot, 10),
|
||||
Slot: strconv.FormatUint(uint64(in.Slots[index]), 10),
|
||||
IsAggregator: in.IsAggregator[index],
|
||||
ValidatorIndex: strconv.FormatUint(uint64(duties[index].ValidatorIndex), 10),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
|
||||
"go.uber.org/mock/gomock"
|
||||
)
|
||||
@@ -67,43 +66,8 @@ func TestSubscribeCommitteeSubnets_Valid(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Even though we have 3 distinct slots, the first 2 ones are in the same epoch so we should only send 2 requests to the beacon node
|
||||
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
|
||||
dutiesProvider.EXPECT().GetAttesterDuties(
|
||||
ctx,
|
||||
slots.ToEpoch(subscribeSlots[0]),
|
||||
validatorIndices,
|
||||
).Return(
|
||||
[]*structs.AttesterDuty{
|
||||
{
|
||||
CommitteesAtSlot: strconv.FormatUint(committeesAtSlot[0], 10),
|
||||
Slot: strconv.FormatUint(uint64(subscribeSlots[0]), 10),
|
||||
},
|
||||
{
|
||||
CommitteesAtSlot: strconv.FormatUint(committeesAtSlot[1], 10),
|
||||
Slot: strconv.FormatUint(uint64(subscribeSlots[1]), 10),
|
||||
},
|
||||
},
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
dutiesProvider.EXPECT().GetAttesterDuties(
|
||||
ctx,
|
||||
slots.ToEpoch(subscribeSlots[2]),
|
||||
validatorIndices,
|
||||
).Return(
|
||||
[]*structs.AttesterDuty{
|
||||
{
|
||||
CommitteesAtSlot: strconv.FormatUint(committeesAtSlot[2], 10),
|
||||
Slot: strconv.FormatUint(uint64(subscribeSlots[2]), 10),
|
||||
},
|
||||
},
|
||||
nil,
|
||||
).Times(1)
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
dutiesProvider: dutiesProvider,
|
||||
}
|
||||
err = validatorClient.subscribeCommitteeSubnets(
|
||||
ctx,
|
||||
@@ -112,21 +76,31 @@ func TestSubscribeCommitteeSubnets_Valid(t *testing.T) {
|
||||
CommitteeIds: committeeIndices,
|
||||
IsAggregator: isAggregator,
|
||||
},
|
||||
validatorIndices,
|
||||
[]*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
ValidatorIndex: validatorIndices[0],
|
||||
CommitteesAtSlot: committeesAtSlot[0],
|
||||
},
|
||||
{
|
||||
ValidatorIndex: validatorIndices[1],
|
||||
CommitteesAtSlot: committeesAtSlot[1],
|
||||
},
|
||||
{
|
||||
ValidatorIndex: validatorIndices[2],
|
||||
CommitteesAtSlot: committeesAtSlot[2],
|
||||
},
|
||||
},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
|
||||
const arraySizeMismatchErrorMessage = "arrays `in.CommitteeIds`, `in.Slots`, `in.IsAggregator` and `validatorIndices` don't have the same length"
|
||||
const arraySizeMismatchErrorMessage = "arrays `in.CommitteeIds`, `in.Slots`, `in.IsAggregator` and `duties` don't have the same length"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
subscribeRequest *ethpb.CommitteeSubnetsSubscribeRequest
|
||||
validatorIndices []primitives.ValidatorIndex
|
||||
attesterDuty *structs.AttesterDuty
|
||||
dutiesError error
|
||||
expectGetDutiesQuery bool
|
||||
duties []*ethpb.DutiesResponse_Duty
|
||||
expectSubscribeRestCall bool
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
@@ -142,7 +116,16 @@ func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
|
||||
Slots: []primitives.Slot{1, 2},
|
||||
IsAggregator: []bool{false, true},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{1, 2},
|
||||
duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
ValidatorIndex: 1,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
ValidatorIndex: 2,
|
||||
CommitteesAtSlot: 2,
|
||||
},
|
||||
},
|
||||
expectedErrorMessage: arraySizeMismatchErrorMessage,
|
||||
},
|
||||
{
|
||||
@@ -152,7 +135,16 @@ func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
|
||||
Slots: []primitives.Slot{1},
|
||||
IsAggregator: []bool{false, true},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{1, 2},
|
||||
duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
ValidatorIndex: 1,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
ValidatorIndex: 2,
|
||||
CommitteesAtSlot: 2,
|
||||
},
|
||||
},
|
||||
expectedErrorMessage: arraySizeMismatchErrorMessage,
|
||||
},
|
||||
{
|
||||
@@ -162,76 +154,33 @@ func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
|
||||
Slots: []primitives.Slot{1, 2},
|
||||
IsAggregator: []bool{false},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{1, 2},
|
||||
duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
ValidatorIndex: 1,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
{
|
||||
ValidatorIndex: 2,
|
||||
CommitteesAtSlot: 2,
|
||||
},
|
||||
},
|
||||
expectedErrorMessage: arraySizeMismatchErrorMessage,
|
||||
},
|
||||
{
|
||||
name: "ValidatorIndices size mismatch",
|
||||
name: "duties size mismatch",
|
||||
subscribeRequest: ðpb.CommitteeSubnetsSubscribeRequest{
|
||||
CommitteeIds: []primitives.CommitteeIndex{1, 2},
|
||||
Slots: []primitives.Slot{1, 2},
|
||||
IsAggregator: []bool{false, true},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{1},
|
||||
duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
ValidatorIndex: 1,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
},
|
||||
expectedErrorMessage: arraySizeMismatchErrorMessage,
|
||||
},
|
||||
{
|
||||
name: "bad duties query",
|
||||
subscribeRequest: ðpb.CommitteeSubnetsSubscribeRequest{
|
||||
Slots: []primitives.Slot{1},
|
||||
CommitteeIds: []primitives.CommitteeIndex{2},
|
||||
IsAggregator: []bool{false},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{3},
|
||||
dutiesError: errors.New("foo error"),
|
||||
expectGetDutiesQuery: true,
|
||||
expectedErrorMessage: "failed to get duties for epoch `0`: foo error",
|
||||
},
|
||||
{
|
||||
name: "bad duty slot",
|
||||
subscribeRequest: ðpb.CommitteeSubnetsSubscribeRequest{
|
||||
Slots: []primitives.Slot{1},
|
||||
CommitteeIds: []primitives.CommitteeIndex{2},
|
||||
IsAggregator: []bool{false},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{3},
|
||||
attesterDuty: &structs.AttesterDuty{
|
||||
Slot: "foo",
|
||||
CommitteesAtSlot: "1",
|
||||
},
|
||||
expectGetDutiesQuery: true,
|
||||
expectedErrorMessage: "failed to parse slot `foo`",
|
||||
},
|
||||
{
|
||||
name: "bad duty committees at slot",
|
||||
subscribeRequest: ðpb.CommitteeSubnetsSubscribeRequest{
|
||||
Slots: []primitives.Slot{1},
|
||||
CommitteeIds: []primitives.CommitteeIndex{2},
|
||||
IsAggregator: []bool{false},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{3},
|
||||
attesterDuty: &structs.AttesterDuty{
|
||||
Slot: "1",
|
||||
CommitteesAtSlot: "foo",
|
||||
},
|
||||
expectGetDutiesQuery: true,
|
||||
expectedErrorMessage: "failed to parse CommitteesAtSlot `foo`",
|
||||
},
|
||||
{
|
||||
name: "missing slot in duties",
|
||||
subscribeRequest: ðpb.CommitteeSubnetsSubscribeRequest{
|
||||
Slots: []primitives.Slot{1},
|
||||
CommitteeIds: []primitives.CommitteeIndex{2},
|
||||
IsAggregator: []bool{false},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{3},
|
||||
attesterDuty: &structs.AttesterDuty{
|
||||
Slot: "2",
|
||||
CommitteesAtSlot: "3",
|
||||
},
|
||||
expectGetDutiesQuery: true,
|
||||
expectedErrorMessage: "failed to get committees for slot `1`",
|
||||
},
|
||||
{
|
||||
name: "bad POST request",
|
||||
subscribeRequest: ðpb.CommitteeSubnetsSubscribeRequest{
|
||||
@@ -239,12 +188,12 @@ func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
|
||||
CommitteeIds: []primitives.CommitteeIndex{2},
|
||||
IsAggregator: []bool{false},
|
||||
},
|
||||
validatorIndices: []primitives.ValidatorIndex{3},
|
||||
attesterDuty: &structs.AttesterDuty{
|
||||
Slot: "1",
|
||||
CommitteesAtSlot: "2",
|
||||
duties: []*ethpb.DutiesResponse_Duty{
|
||||
{
|
||||
ValidatorIndex: 1,
|
||||
CommitteesAtSlot: 1,
|
||||
},
|
||||
},
|
||||
expectGetDutiesQuery: true,
|
||||
expectSubscribeRestCall: true,
|
||||
expectedErrorMessage: "foo error",
|
||||
},
|
||||
@@ -257,18 +206,6 @@ func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
dutiesProvider := mock.NewMockdutiesProvider(ctrl)
|
||||
if testCase.expectGetDutiesQuery {
|
||||
dutiesProvider.EXPECT().GetAttesterDuties(
|
||||
ctx,
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).Return(
|
||||
[]*structs.AttesterDuty{testCase.attesterDuty},
|
||||
testCase.dutiesError,
|
||||
).Times(1)
|
||||
}
|
||||
|
||||
jsonRestHandler := mock.NewMockJsonRestHandler(ctrl)
|
||||
if testCase.expectSubscribeRestCall {
|
||||
jsonRestHandler.EXPECT().Post(
|
||||
@@ -284,9 +221,8 @@ func TestSubscribeCommitteeSubnets_Error(t *testing.T) {
|
||||
|
||||
validatorClient := &beaconApiValidatorClient{
|
||||
jsonRestHandler: jsonRestHandler,
|
||||
dutiesProvider: dutiesProvider,
|
||||
}
|
||||
err := validatorClient.subscribeCommitteeSubnets(ctx, testCase.subscribeRequest, testCase.validatorIndices)
|
||||
err := validatorClient.subscribeCommitteeSubnets(ctx, testCase.subscribeRequest, testCase.duties)
|
||||
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/validator/client/iface"
|
||||
"google.golang.org/grpc"
|
||||
@@ -99,7 +98,7 @@ func (c *grpcValidatorClient) SubmitValidatorRegistrations(ctx context.Context,
|
||||
return c.beaconNodeValidatorClient.SubmitValidatorRegistrations(ctx, in)
|
||||
}
|
||||
|
||||
func (c *grpcValidatorClient) SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, _ []primitives.ValidatorIndex) (*empty.Empty, error) {
|
||||
func (c *grpcValidatorClient) SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, _ []*ethpb.DutiesResponse_Duty) (*empty.Empty, error) {
|
||||
return c.beaconNodeValidatorClient.SubscribeCommitteeSubnets(ctx, in)
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ type ValidatorClient interface {
|
||||
SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest) (*ethpb.AggregateSelectionResponse, error)
|
||||
SubmitSignedAggregateSelectionProof(ctx context.Context, in *ethpb.SignedAggregateSubmitRequest) (*ethpb.SignedAggregateSubmitResponse, error)
|
||||
ProposeExit(ctx context.Context, in *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error)
|
||||
SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, validatorIndices []primitives.ValidatorIndex) (*empty.Empty, error)
|
||||
SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, duties []*ethpb.DutiesResponse_Duty) (*empty.Empty, error)
|
||||
CheckDoppelGanger(ctx context.Context, in *ethpb.DoppelGangerRequest) (*ethpb.DoppelGangerResponse, error)
|
||||
GetSyncMessageBlockRoot(ctx context.Context, in *empty.Empty) (*ethpb.SyncMessageBlockRootResponse, error)
|
||||
SubmitSyncMessage(ctx context.Context, in *ethpb.SyncCommitteeMessage) (*empty.Empty, error)
|
||||
|
||||
@@ -629,7 +629,7 @@ func (v *validator) subscribeToSubnets(ctx context.Context, res *ethpb.DutiesRes
|
||||
subscribeSlots := make([]primitives.Slot, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties))
|
||||
subscribeCommitteeIndices := make([]primitives.CommitteeIndex, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties))
|
||||
subscribeIsAggregator := make([]bool, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties))
|
||||
subscribeValidatorIndices := make([]primitives.ValidatorIndex, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties))
|
||||
activeDuties := make([]*ethpb.DutiesResponse_Duty, 0, len(res.CurrentEpochDuties)+len(res.NextEpochDuties))
|
||||
alreadySubscribed := make(map[[64]byte]bool)
|
||||
|
||||
if v.distributed {
|
||||
@@ -662,7 +662,7 @@ func (v *validator) subscribeToSubnets(ctx context.Context, res *ethpb.DutiesRes
|
||||
subscribeSlots = append(subscribeSlots, attesterSlot)
|
||||
subscribeCommitteeIndices = append(subscribeCommitteeIndices, committeeIndex)
|
||||
subscribeIsAggregator = append(subscribeIsAggregator, aggregator)
|
||||
subscribeValidatorIndices = append(subscribeValidatorIndices, validatorIndex)
|
||||
activeDuties = append(activeDuties, duty)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ func (v *validator) subscribeToSubnets(ctx context.Context, res *ethpb.DutiesRes
|
||||
subscribeSlots = append(subscribeSlots, attesterSlot)
|
||||
subscribeCommitteeIndices = append(subscribeCommitteeIndices, committeeIndex)
|
||||
subscribeIsAggregator = append(subscribeIsAggregator, aggregator)
|
||||
subscribeValidatorIndices = append(subscribeValidatorIndices, validatorIndex)
|
||||
activeDuties = append(activeDuties, duty)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,7 +698,7 @@ func (v *validator) subscribeToSubnets(ctx context.Context, res *ethpb.DutiesRes
|
||||
CommitteeIds: subscribeCommitteeIndices,
|
||||
IsAggregator: subscribeIsAggregator,
|
||||
},
|
||||
subscribeValidatorIndices,
|
||||
activeDuties,
|
||||
)
|
||||
|
||||
return err
|
||||
|
||||
@@ -520,7 +520,7 @@ func TestUpdateDuties_OK(t *testing.T) {
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).DoAndReturn(func(_ context.Context, _ *ethpb.CommitteeSubnetsSubscribeRequest, _ []primitives.ValidatorIndex) (*emptypb.Empty, error) {
|
||||
).DoAndReturn(func(_ context.Context, _ *ethpb.CommitteeSubnetsSubscribeRequest, _ []*ethpb.DutiesResponse_Duty) (*emptypb.Empty, error) {
|
||||
wg.Done()
|
||||
return nil, nil
|
||||
})
|
||||
@@ -568,7 +568,7 @@ func TestUpdateDuties_OK_FilterBlacklistedPublicKeys(t *testing.T) {
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).DoAndReturn(func(_ context.Context, _ *ethpb.CommitteeSubnetsSubscribeRequest, _ []primitives.ValidatorIndex) (*emptypb.Empty, error) {
|
||||
).DoAndReturn(func(_ context.Context, _ *ethpb.CommitteeSubnetsSubscribeRequest, _ []*ethpb.DutiesResponse_Duty) (*emptypb.Empty, error) {
|
||||
wg.Done()
|
||||
return nil, nil
|
||||
})
|
||||
@@ -700,7 +700,7 @@ func TestUpdateDuties_Distributed(t *testing.T) {
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
gomock.Any(),
|
||||
).DoAndReturn(func(_ context.Context, _ *ethpb.CommitteeSubnetsSubscribeRequest, _ []primitives.ValidatorIndex) (*emptypb.Empty, error) {
|
||||
).DoAndReturn(func(_ context.Context, _ *ethpb.CommitteeSubnetsSubscribeRequest, _ []*ethpb.DutiesResponse_Duty) (*emptypb.Empty, error) {
|
||||
wg.Done()
|
||||
return nil, nil
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user