Optimize SubmitAggregateSelectionProof VC action (#13711)

* Optimize `SubscribeCommitteeSubnets` VC action

* test fixes

* remove newline

* Optimize `SubmitAggregateSelectionProof`

* mock

* bzl gzl

* test fixes
This commit is contained in:
Radosław Kapka 2024-03-19 23:09:07 +09:00 committed by GitHub
parent c4f6020677
commit b692722ddf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 44 additions and 219 deletions

View File

@ -15,6 +15,7 @@ go_library(
deps = [ deps = [
"//api/client/beacon:go_default_library", "//api/client/beacon:go_default_library",
"//api/client/event:go_default_library", "//api/client/event:go_default_library",
"//consensus-types/primitives:go_default_library",
"//consensus-types/validator:go_default_library", "//consensus-types/validator:go_default_library",
"//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1:go_default_library",
"//validator/client/iface:go_default_library", "//validator/client/iface:go_default_library",

View File

@ -13,8 +13,8 @@ import (
context "context" context "context"
reflect "reflect" reflect "reflect"
"github.com/prysmaticlabs/prysm/v5/api/client/beacon" event "github.com/prysmaticlabs/prysm/v5/api/client/event"
"github.com/prysmaticlabs/prysm/v5/api/client/event" primitives "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface" iface "github.com/prysmaticlabs/prysm/v5/validator/client/iface"
gomock "go.uber.org/mock/gomock" gomock "go.uber.org/mock/gomock"
@ -113,7 +113,7 @@ func (m *MockValidatorClient) GetAggregatedSyncSelections(arg0 context.Context,
} }
// GetAggregatedSyncSelections indicates an expected call of GetAggregatedSyncSelections. // GetAggregatedSyncSelections indicates an expected call of GetAggregatedSyncSelections.
func (mr *MockValidatorClientMockRecorder) GetAggregatedSyncSelections(arg0, arg1 interface{}) *gomock.Call { func (mr *MockValidatorClientMockRecorder) GetAggregatedSyncSelections(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAggregatedSyncSelections", reflect.TypeOf((*MockValidatorClient)(nil).GetAggregatedSyncSelections), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAggregatedSyncSelections", reflect.TypeOf((*MockValidatorClient)(nil).GetAggregatedSyncSelections), arg0, arg1)
} }
@ -301,70 +301,28 @@ func (mr *MockValidatorClientMockRecorder) ProposeExit(arg0, arg1 any) *gomock.C
// StartEventStream mocks base method. // StartEventStream mocks base method.
func (m *MockValidatorClient) StartEventStream(arg0 context.Context, arg1 []string, arg2 chan<- *event.Event) { func (m *MockValidatorClient) StartEventStream(arg0 context.Context, arg1 []string, arg2 chan<- *event.Event) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
_ = m.ctrl.Call(m, "StartEventStream", arg0,arg1,arg2) m.ctrl.Call(m, "StartEventStream", arg0, arg1, arg2)
} }
// StartEventStream indicates an expected call of StartEventStream. // StartEventStream indicates an expected call of StartEventStream.
func (mr *MockValidatorClientMockRecorder) StartEventStream(arg0,arg1,arg2 interface{}) *gomock.Call { func (mr *MockValidatorClientMockRecorder) StartEventStream(arg0, arg1, arg2 any) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartEventStream", reflect.TypeOf((*MockValidatorClient)(nil).StartEventStream), arg0, arg1, arg2) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartEventStream", reflect.TypeOf((*MockValidatorClient)(nil).StartEventStream), arg0, arg1, arg2)
} }
// ProcessEvent mocks base method.
func (m *MockValidatorClient) ProcessEvent(arg0 *event.Event) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ProcessEvent", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// ProcessEvent indicates an expected call of ProcessEvent.
func (mr *MockValidatorClientMockRecorder) ProcessEvent(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProcessEvent", reflect.TypeOf((*MockValidatorClient)(nil).ProcessEvent), arg0)
}
// NodeIsHealthy mocks base method.
func (m *MockValidatorClient) NodeIsHealthy(arg0 context.Context) bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NodeIsHealthy",arg0)
ret0, _ := ret[0].(bool)
return ret0
}
// NodeIsHealthy indicates an expected call of NodeIsHealthy.
func (mr *MockValidatorClientMockRecorder) NodeIsHealthy(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeIsHealthy", reflect.TypeOf((*MockValidatorClient)(nil).NodeIsHealthy), arg0)
}
// NodeHealthTracker mocks base method.
func (m *MockValidatorClient) NodeHealthTracker() *beacon.NodeHealthTracker {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NodeHealthTracker")
ret0, _ := ret[0].(*beacon.NodeHealthTracker)
return ret0
}
// NodeHealthTracker indicates an expected call of NodeHealthTracker.
func (mr *MockValidatorClientMockRecorder) NodeHealthTracker() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeHealthTracker", reflect.TypeOf((*MockValidatorClient)(nil).NodeHealthTracker))
}
// SubmitAggregateSelectionProof mocks base method. // SubmitAggregateSelectionProof mocks base method.
func (m *MockValidatorClient) SubmitAggregateSelectionProof(arg0 context.Context, arg1 *eth.AggregateSelectionRequest) (*eth.AggregateSelectionResponse, error) { func (m *MockValidatorClient) SubmitAggregateSelectionProof(arg0 context.Context, arg1 *eth.AggregateSelectionRequest, arg2 primitives.ValidatorIndex, arg3 uint64) (*eth.AggregateSelectionResponse, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SubmitAggregateSelectionProof", arg0, arg1) ret := m.ctrl.Call(m, "SubmitAggregateSelectionProof", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*eth.AggregateSelectionResponse) ret0, _ := ret[0].(*eth.AggregateSelectionResponse)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }
// SubmitAggregateSelectionProof indicates an expected call of SubmitAggregateSelectionProof. // SubmitAggregateSelectionProof indicates an expected call of SubmitAggregateSelectionProof.
func (mr *MockValidatorClientMockRecorder) SubmitAggregateSelectionProof(arg0, arg1 any) *gomock.Call { func (mr *MockValidatorClientMockRecorder) SubmitAggregateSelectionProof(arg0, arg1, arg2, arg3 any) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitAggregateSelectionProof", reflect.TypeOf((*MockValidatorClient)(nil).SubmitAggregateSelectionProof), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitAggregateSelectionProof", reflect.TypeOf((*MockValidatorClient)(nil).SubmitAggregateSelectionProof), arg0, arg1, arg2, arg3)
} }
// SubmitSignedAggregateSelectionProof mocks base method. // SubmitSignedAggregateSelectionProof mocks base method.

View File

@ -84,7 +84,7 @@ func (v *validator) SubmitAggregateAndProof(ctx context.Context, slot primitives
CommitteeIndex: duty.CommitteeIndex, CommitteeIndex: duty.CommitteeIndex,
PublicKey: pubKey[:], PublicKey: pubKey[:],
SlotSignature: slotSig, SlotSignature: slotSig,
}) }, duty.ValidatorIndex, uint64(len(duty.Committee)))
if err != nil { if err != nil {
// handle grpc not found // handle grpc not found
s, ok := status.FromError(err) s, ok := status.FromError(err)

View File

@ -63,6 +63,8 @@ func TestSubmitAggregateAndProof_SignFails(t *testing.T) {
m.validatorClient.EXPECT().SubmitAggregateSelectionProof( m.validatorClient.EXPECT().SubmitAggregateSelectionProof(
gomock.Any(), // ctx gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}), gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}),
gomock.Any(),
gomock.Any(),
).Return(&ethpb.AggregateSelectionResponse{ ).Return(&ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{ AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0, AggregatorIndex: 0,
@ -106,6 +108,8 @@ func TestSubmitAggregateAndProof_Ok(t *testing.T) {
m.validatorClient.EXPECT().SubmitAggregateSelectionProof( m.validatorClient.EXPECT().SubmitAggregateSelectionProof(
gomock.Any(), // ctx gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}), gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}),
gomock.Any(),
gomock.Any(),
).Return(&ethpb.AggregateSelectionResponse{ ).Return(&ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{ AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0, AggregatorIndex: 0,
@ -166,6 +170,8 @@ func TestSubmitAggregateAndProof_Distributed(t *testing.T) {
m.validatorClient.EXPECT().SubmitAggregateSelectionProof( m.validatorClient.EXPECT().SubmitAggregateSelectionProof(
gomock.Any(), // ctx gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}), gomock.AssignableToTypeOf(&ethpb.AggregateSelectionRequest{}),
gomock.Any(),
gomock.Any(),
).Return(&ethpb.AggregateSelectionResponse{ ).Return(&ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{ AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: 0, AggregatorIndex: 0,

View File

@ -8,6 +8,7 @@ import (
"github.com/golang/protobuf/ptypes/empty" "github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v5/api/client/event" "github.com/prysmaticlabs/prysm/v5/api/client/event"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface" "github.com/prysmaticlabs/prysm/v5/validator/client/iface"
@ -135,9 +136,9 @@ func (c *beaconApiValidatorClient) StreamBlocksAltair(ctx context.Context, in *e
return c.streamBlocks(ctx, in, time.Second), nil return c.streamBlocks(ctx, in, time.Second), nil
} }
func (c *beaconApiValidatorClient) SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest) (*ethpb.AggregateSelectionResponse, error) { func (c *beaconApiValidatorClient) SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest, index primitives.ValidatorIndex, committeeLength uint64) (*ethpb.AggregateSelectionResponse, error) {
return wrapInMetrics[*ethpb.AggregateSelectionResponse]("SubmitAggregateSelectionProof", func() (*ethpb.AggregateSelectionResponse, error) { return wrapInMetrics[*ethpb.AggregateSelectionResponse]("SubmitAggregateSelectionProof", func() (*ethpb.AggregateSelectionResponse, error) {
return c.submitAggregateSelectionProof(ctx, in) return c.submitAggregateSelectionProof(ctx, in, index, committeeLength)
}) })
} }

View File

@ -11,10 +11,14 @@ import (
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/time/slots"
) )
func (c *beaconApiValidatorClient) submitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest) (*ethpb.AggregateSelectionResponse, error) { func (c *beaconApiValidatorClient) submitAggregateSelectionProof(
ctx context.Context,
in *ethpb.AggregateSelectionRequest,
index primitives.ValidatorIndex,
committeeLength uint64,
) (*ethpb.AggregateSelectionResponse, error) {
isOptimistic, err := c.isOptimistic(ctx) isOptimistic, err := c.isOptimistic(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
@ -25,29 +29,7 @@ func (c *beaconApiValidatorClient) submitAggregateSelectionProof(ctx context.Con
return nil, errors.New("the node is currently optimistic and cannot serve validators") return nil, errors.New("the node is currently optimistic and cannot serve validators")
} }
validatorIndexResponse, err := c.validatorIndex(ctx, &ethpb.ValidatorIndexRequest{PublicKey: in.PublicKey}) isAggregator, err := helpers.IsAggregator(committeeLength, in.SlotSignature)
if err != nil {
return nil, errors.Wrap(err, "failed to get validator index")
}
attesterDuties, err := c.dutiesProvider.GetAttesterDuties(ctx, slots.ToEpoch(in.Slot), []primitives.ValidatorIndex{validatorIndexResponse.Index})
if err != nil {
return nil, errors.Wrap(err, "failed to get attester duties")
}
if len(attesterDuties) == 0 {
return nil, errors.Errorf("no attester duty for the given slot %d", in.Slot)
}
// First attester duty is required since we requested attester duties for one validator index.
attesterDuty := attesterDuties[0]
committeeLen, err := strconv.ParseUint(attesterDuty.CommitteeLength, 10, 64)
if err != nil {
return nil, errors.Wrap(err, "failed to parse committee length")
}
isAggregator, err := helpers.IsAggregator(committeeLen, in.SlotSignature)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to get aggregator status") return nil, errors.Wrap(err, "failed to get aggregator status")
} }
@ -77,7 +59,7 @@ func (c *beaconApiValidatorClient) submitAggregateSelectionProof(ctx context.Con
return &ethpb.AggregateSelectionResponse{ return &ethpb.AggregateSelectionResponse{
AggregateAndProof: &ethpb.AggregateAttestationAndProof{ AggregateAndProof: &ethpb.AggregateAttestationAndProof{
AggregatorIndex: validatorIndexResponse.Index, AggregatorIndex: index,
Aggregate: aggregatedAttestation, Aggregate: aggregatedAttestation,
SelectionProof: in.SlotSignature, SelectionProof: in.SlotSignature,
}, },

View File

@ -1,12 +1,9 @@
package beacon_api package beacon_api
import ( import (
"bytes"
"context" "context"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"net/url"
"testing" "testing"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
@ -15,7 +12,6 @@ import (
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/testing/assert" "github.com/prysmaticlabs/prysm/v5/testing/assert"
"github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/require"
"github.com/prysmaticlabs/prysm/v5/time/slots"
"github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock" "github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/mock"
test_helpers "github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/test-helpers" test_helpers "github.com/prysmaticlabs/prysm/v5/validator/client/beacon-api/test-helpers"
"go.uber.org/mock/gomock" "go.uber.org/mock/gomock"
@ -25,26 +21,15 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
const ( const (
pubkeyStr = "0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13" pubkeyStr = "0x8000091c2ae64ee414a54c1cc1fc67dec663408bc636cb86756e0200e41a75c8f86603f104f02c856983d2783116be13"
syncingEndpoint = "/eth/v1/node/syncing" syncingEndpoint = "/eth/v1/node/syncing"
attesterDutiesEndpoint = "/eth/v1/validator/duties/attester"
validatorsEndpoint = "/eth/v1/beacon/states/head/validators"
attestationDataEndpoint = "/eth/v1/validator/attestation_data" attestationDataEndpoint = "/eth/v1/validator/attestation_data"
aggregateAttestationEndpoint = "/eth/v1/validator/aggregate_attestation" aggregateAttestationEndpoint = "/eth/v1/validator/aggregate_attestation"
validatorIndex = "55293" validatorIndex = primitives.ValidatorIndex(55293)
slotSignature = "0x8776a37d6802c4797d113169c5fcfda50e68a32058eb6356a6f00d06d7da64c841a00c7c38b9b94a204751eca53707bd03523ce4797827d9bacff116a6e776a20bbccff4b683bf5201b610797ed0502557a58a65c8395f8a1649b976c3112d15" slotSignature = "0x8776a37d6802c4797d113169c5fcfda50e68a32058eb6356a6f00d06d7da64c841a00c7c38b9b94a204751eca53707bd03523ce4797827d9bacff116a6e776a20bbccff4b683bf5201b610797ed0502557a58a65c8395f8a1649b976c3112d15"
slot = primitives.Slot(123) slot = primitives.Slot(123)
committeeIndex = primitives.CommitteeIndex(1) committeeIndex = primitives.CommitteeIndex(1)
committeesAtSlot = uint64(1)
) )
attesterDuties := []*structs.AttesterDuty{
{
Pubkey: pubkeyStr,
ValidatorIndex: validatorIndex,
Slot: "123",
CommitteeIndex: "1",
CommitteeLength: "3",
},
}
attestationDataResponse := generateValidAttestation(uint64(slot), uint64(committeeIndex)) attestationDataResponse := generateValidAttestation(uint64(slot), uint64(committeeIndex))
attestationDataProto, err := attestationDataResponse.Data.ToConsensus() attestationDataProto, err := attestationDataResponse.Data.ToConsensus()
require.NoError(t, err) require.NoError(t, err)
@ -64,22 +49,15 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
name string name string
isOptimistic bool isOptimistic bool
syncingErr error syncingErr error
validatorsErr error
dutiesErr error
attestationDataErr error attestationDataErr error
aggregateAttestationErr error aggregateAttestationErr error
duties []*structs.AttesterDuty
validatorsCalled int
attesterDutiesCalled int
attestationDataCalled int attestationDataCalled int
aggregateAttestationCalled int aggregateAttestationCalled int
expectedErrorMsg string expectedErrorMsg string
committeesAtSlot uint64
}{ }{
{ {
name: "success", name: "success",
duties: attesterDuties,
validatorsCalled: 1,
attesterDutiesCalled: 1,
attestationDataCalled: 1, attestationDataCalled: 1,
aggregateAttestationCalled: 1, aggregateAttestationCalled: 1,
}, },
@ -93,34 +71,14 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
syncingErr: errors.New("bad request"), syncingErr: errors.New("bad request"),
expectedErrorMsg: "failed to get syncing status", expectedErrorMsg: "failed to get syncing status",
}, },
{
name: "validator index error",
validatorsCalled: 1,
validatorsErr: errors.New("bad request"),
expectedErrorMsg: "failed to get validator index",
},
{
name: "attester duties error",
duties: attesterDuties,
validatorsCalled: 1,
attesterDutiesCalled: 1,
dutiesErr: errors.New("bad request"),
expectedErrorMsg: "failed to get attester duties",
},
{ {
name: "attestation data error", name: "attestation data error",
duties: attesterDuties,
validatorsCalled: 1,
attesterDutiesCalled: 1,
attestationDataCalled: 1, attestationDataCalled: 1,
attestationDataErr: errors.New("bad request"), attestationDataErr: errors.New("bad request"),
expectedErrorMsg: fmt.Sprintf("failed to get attestation data for slot=%d and committee_index=%d", slot, committeeIndex), expectedErrorMsg: fmt.Sprintf("failed to get attestation data for slot=%d and committee_index=%d", slot, committeeIndex),
}, },
{ {
name: "aggregate attestation error", name: "aggregate attestation error",
duties: attesterDuties,
validatorsCalled: 1,
attesterDutiesCalled: 1,
attestationDataCalled: 1, attestationDataCalled: 1,
aggregateAttestationCalled: 1, aggregateAttestationCalled: 1,
aggregateAttestationErr: errors.New("bad request"), aggregateAttestationErr: errors.New("bad request"),
@ -128,26 +86,9 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
}, },
{ {
name: "validator is not an aggregator", name: "validator is not an aggregator",
duties: []*structs.AttesterDuty{ committeesAtSlot: 64,
{
Pubkey: pubkeyStr,
ValidatorIndex: validatorIndex,
Slot: "123",
CommitteeIndex: "1",
CommitteeLength: "64",
},
},
validatorsCalled: 1,
attesterDutiesCalled: 1,
expectedErrorMsg: "validator is not an aggregator", expectedErrorMsg: "validator is not an aggregator",
}, },
{
name: "no attester duties",
duties: []*structs.AttesterDuty{},
validatorsCalled: 1,
attesterDutiesCalled: 1,
expectedErrorMsg: fmt.Sprintf("no attester duty for the given slot %d", slot),
},
} }
for _, test := range tests { for _, test := range tests {
@ -171,76 +112,6 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
test.syncingErr, test.syncingErr,
).Times(1) ).Times(1)
valsReq := &structs.GetValidatorsRequest{
Ids: []string{stringPubKey},
Statuses: []string{},
}
valReqBytes, err := json.Marshal(valsReq)
require.NoError(t, err)
// Call validators endpoint to get validator index.
jsonRestHandler.EXPECT().Post(
ctx,
validatorsEndpoint,
nil,
bytes.NewBuffer(valReqBytes),
&structs.GetValidatorsResponse{},
).SetArg(
4,
structs.GetValidatorsResponse{
Data: []*structs.ValidatorContainer{
{
Index: validatorIndex,
Status: "active_ongoing",
Validator: &structs.Validator{
Pubkey: pubkeyStr,
},
},
},
},
).Return(
test.validatorsErr,
).Times(test.validatorsCalled)
if test.validatorsErr != nil {
// Then try the GET call which will also return error.
queryParams := url.Values{}
for _, id := range valsReq.Ids {
queryParams.Add("id", id)
}
for _, st := range valsReq.Statuses {
queryParams.Add("status", st)
}
query := buildURL("/eth/v1/beacon/states/head/validators", queryParams)
jsonRestHandler.EXPECT().Get(
ctx,
query,
&structs.GetValidatorsResponse{},
).Return(
test.validatorsErr,
).Times(1)
}
// Call attester duties endpoint to get attester duties.
validatorIndicesBytes, err := json.Marshal([]string{validatorIndex})
require.NoError(t, err)
jsonRestHandler.EXPECT().Post(
ctx,
fmt.Sprintf("%s/%d", attesterDutiesEndpoint, slots.ToEpoch(slot)),
nil,
bytes.NewBuffer(validatorIndicesBytes),
&structs.GetAttesterDutiesResponse{},
).SetArg(
4,
structs.GetAttesterDutiesResponse{
Data: test.duties,
},
).Return(
test.dutiesErr,
).Times(test.attesterDutiesCalled)
// Call attestation data to get attestation data root to query aggregate attestation. // Call attestation data to get attestation data root to query aggregate attestation.
jsonRestHandler.EXPECT().Get( jsonRestHandler.EXPECT().Get(
ctx, ctx,
@ -290,12 +161,17 @@ func TestSubmitAggregateSelectionProof(t *testing.T) {
jsonRestHandler: jsonRestHandler, jsonRestHandler: jsonRestHandler,
}, },
} }
committees := committeesAtSlot
if test.committeesAtSlot != 0 {
committees = test.committeesAtSlot
}
actualResponse, err := validatorClient.submitAggregateSelectionProof(ctx, &ethpb.AggregateSelectionRequest{ actualResponse, err := validatorClient.submitAggregateSelectionProof(ctx, &ethpb.AggregateSelectionRequest{
Slot: slot, Slot: slot,
CommitteeIndex: committeeIndex, CommitteeIndex: committeeIndex,
PublicKey: pubkey, PublicKey: pubkey,
SlotSignature: slotSignatureBytes, SlotSignature: slotSignatureBytes,
}) }, validatorIndex, committees)
if test.expectedErrorMsg == "" { if test.expectedErrorMsg == "" {
require.NoError(t, err) require.NoError(t, err)
assert.DeepEqual(t, expectedResponse, actualResponse) assert.DeepEqual(t, expectedResponse, actualResponse)

View File

@ -10,6 +10,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/api/client" "github.com/prysmaticlabs/prysm/v5/api/client"
eventClient "github.com/prysmaticlabs/prysm/v5/api/client/event" eventClient "github.com/prysmaticlabs/prysm/v5/api/client/event"
"github.com/prysmaticlabs/prysm/v5/api/server/structs" "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" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v5/validator/client/iface" "github.com/prysmaticlabs/prysm/v5/validator/client/iface"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -82,7 +83,7 @@ func (c *grpcValidatorClient) StreamBlocksAltair(ctx context.Context, in *ethpb.
return c.beaconNodeValidatorClient.StreamBlocksAltair(ctx, in) return c.beaconNodeValidatorClient.StreamBlocksAltair(ctx, in)
} }
func (c *grpcValidatorClient) SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest) (*ethpb.AggregateSelectionResponse, error) { func (c *grpcValidatorClient) SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest, _ primitives.ValidatorIndex, _ uint64) (*ethpb.AggregateSelectionResponse, error) {
return c.beaconNodeValidatorClient.SubmitAggregateSelectionProof(ctx, in) return c.beaconNodeValidatorClient.SubmitAggregateSelectionProof(ctx, in)
} }

View File

@ -135,7 +135,7 @@ type ValidatorClient interface {
GetFeeRecipientByPubKey(ctx context.Context, in *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error) GetFeeRecipientByPubKey(ctx context.Context, in *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error)
GetAttestationData(ctx context.Context, in *ethpb.AttestationDataRequest) (*ethpb.AttestationData, error) GetAttestationData(ctx context.Context, in *ethpb.AttestationDataRequest) (*ethpb.AttestationData, error)
ProposeAttestation(ctx context.Context, in *ethpb.Attestation) (*ethpb.AttestResponse, error) ProposeAttestation(ctx context.Context, in *ethpb.Attestation) (*ethpb.AttestResponse, error)
SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest) (*ethpb.AggregateSelectionResponse, error) SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest, index primitives.ValidatorIndex, committeeLength uint64) (*ethpb.AggregateSelectionResponse, error)
SubmitSignedAggregateSelectionProof(ctx context.Context, in *ethpb.SignedAggregateSubmitRequest) (*ethpb.SignedAggregateSubmitResponse, error) SubmitSignedAggregateSelectionProof(ctx context.Context, in *ethpb.SignedAggregateSubmitRequest) (*ethpb.SignedAggregateSubmitResponse, error)
ProposeExit(ctx context.Context, in *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error) ProposeExit(ctx context.Context, in *ethpb.SignedVoluntaryExit) (*ethpb.ProposeExitResponse, error)
SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, duties []*ethpb.DutiesResponse_Duty) (*empty.Empty, error) SubscribeCommitteeSubnets(ctx context.Context, in *ethpb.CommitteeSubnetsSubscribeRequest, duties []*ethpb.DutiesResponse_Duty) (*empty.Empty, error)