diff --git a/validator/client/beacon-api/BUILD.bazel b/validator/client/beacon-api/BUILD.bazel index de88e0a0d..abfcf4be5 100644 --- a/validator/client/beacon-api/BUILD.bazel +++ b/validator/client/beacon-api/BUILD.bazel @@ -42,6 +42,7 @@ go_library( "//beacon-chain/core/helpers:go_default_library", "//beacon-chain/core/signing:go_default_library", "//beacon-chain/rpc/apimiddleware:go_default_library", + "//beacon-chain/rpc/prysm/validator:go_default_library", "//config/params:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", @@ -106,6 +107,7 @@ go_test( "//api/gateway/apimiddleware:go_default_library", "//beacon-chain/rpc/apimiddleware:go_default_library", "//beacon-chain/rpc/eth/helpers:go_default_library", + "//beacon-chain/rpc/prysm/validator:go_default_library", "//config/params:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", diff --git a/validator/client/beacon-api/beacon_api_beacon_chain_client.go b/validator/client/beacon-api/beacon_api_beacon_chain_client.go index f5f9bf6de..b11d6a6ec 100644 --- a/validator/client/beacon-api/beacon_api_beacon_chain_client.go +++ b/validator/client/beacon-api/beacon_api_beacon_chain_client.go @@ -1,7 +1,9 @@ package beacon_api import ( + "bytes" "context" + "encoding/json" "net/http" "reflect" "strconv" @@ -11,6 +13,7 @@ import ( "github.com/golang/protobuf/ptypes/empty" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware" + "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator" "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/time/slots" @@ -23,6 +26,8 @@ type beaconApiBeaconChainClient struct { stateValidatorsProvider stateValidatorsProvider } +const getValidatorPerformanceEndpoint = "/eth/v1/beacon/validators/performance" + func (c beaconApiBeaconChainClient) getHeadBlockHeaders(ctx context.Context) (*apimiddleware.BlockHeaderResponseJson, error) { blockHeader := apimiddleware.BlockHeaderResponseJson{} if _, err := c.jsonRestHandler.GetRestJsonResponse(ctx, "/eth/v1/beacon/headers/head", &blockHeader); err != nil { @@ -317,12 +322,35 @@ func (c beaconApiBeaconChainClient) GetValidatorQueue(ctx context.Context, in *e } func (c beaconApiBeaconChainClient) GetValidatorPerformance(ctx context.Context, in *ethpb.ValidatorPerformanceRequest) (*ethpb.ValidatorPerformanceResponse, error) { - if c.fallbackClient != nil { - return c.fallbackClient.GetValidatorPerformance(ctx, in) + request, err := json.Marshal(validator.ValidatorPerformanceRequest{ + PublicKeys: in.PublicKeys, + Indices: in.Indices, + }) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal request") + } + resp := &validator.ValidatorPerformanceResponse{} + if _, err := c.jsonRestHandler.PostRestJson( + ctx, + getValidatorPerformanceEndpoint, + nil, + bytes.NewBuffer(request), + resp, + ); err != nil { + return nil, errors.Wrap(err, "failed to get validator performance") } - // TODO: Implement me - panic("beaconApiBeaconChainClient.GetValidatorPerformance is not implemented. To use a fallback client, pass a fallback client as the last argument of NewBeaconApiBeaconChainClientWithFallback.") + return ðpb.ValidatorPerformanceResponse{ + CurrentEffectiveBalances: resp.CurrentEffectiveBalances, + CorrectlyVotedSource: resp.CorrectlyVotedSource, + CorrectlyVotedTarget: resp.CorrectlyVotedTarget, + CorrectlyVotedHead: resp.CorrectlyVotedHead, + BalancesBeforeEpochTransition: resp.BalancesBeforeEpochTransition, + BalancesAfterEpochTransition: resp.BalancesAfterEpochTransition, + MissingValidators: resp.MissingValidators, + PublicKeys: resp.PublicKeys, + InactivityScores: resp.InactivityScores, + }, nil } func (c beaconApiBeaconChainClient) GetValidatorParticipation(ctx context.Context, in *ethpb.GetValidatorParticipationRequest) (*ethpb.ValidatorParticipationResponse, error) { diff --git a/validator/client/beacon-api/beacon_api_beacon_chain_client_test.go b/validator/client/beacon-api/beacon_api_beacon_chain_client_test.go index 96934660e..6aa86af70 100644 --- a/validator/client/beacon-api/beacon_api_beacon_chain_client_test.go +++ b/validator/client/beacon-api/beacon_api_beacon_chain_client_test.go @@ -1,7 +1,9 @@ package beacon_api import ( + "bytes" "context" + "encoding/json" "errors" "fmt" "math" @@ -10,8 +12,11 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/golang/mock/gomock" + gatewaymiddleware "github.com/prysmaticlabs/prysm/v4/api/gateway/apimiddleware" "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware" + "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/prysm/validator" "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/testing/assert" "github.com/prysmaticlabs/prysm/v4/testing/require" @@ -925,3 +930,44 @@ func TestGetChainHead(t *testing.T) { assert.DeepEqual(t, expectedChainHead, chainHead) }) } + +func Test_beaconApiBeaconChainClient_GetValidatorPerformance(t *testing.T) { + publicKeys := [][48]byte{ + bytesutil.ToBytes48([]byte{1}), + bytesutil.ToBytes48([]byte{2}), + bytesutil.ToBytes48([]byte{3}), + } + + ctx := context.Background() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + request, err := json.Marshal(validator.ValidatorPerformanceRequest{ + PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]}, + }) + require.NoError(t, err) + + wantResponse := &validator.ValidatorPerformanceResponse{} + want := ðpb.ValidatorPerformanceResponse{} + jsonRestHandler := mock.NewMockjsonRestHandler(ctrl) + jsonRestHandler.EXPECT().PostRestJson( + ctx, + getValidatorPerformanceEndpoint, + nil, + bytes.NewBuffer(request), + wantResponse, + ).Return( + &gatewaymiddleware.DefaultErrorJson{}, + nil, + ) + + c := beaconApiBeaconChainClient{ + jsonRestHandler: jsonRestHandler, + } + + got, err := c.GetValidatorPerformance(ctx, ðpb.ValidatorPerformanceRequest{ + PublicKeys: [][]byte{publicKeys[0][:], publicKeys[2][:], publicKeys[1][:]}, + }) + require.NoError(t, err) + require.DeepEqual(t, want.PublicKeys, got.PublicKeys) +}