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

Add (lack of) REST implementation for GetFeeRecipientByPubKey #11991

Merged
merged 6 commits into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 validator/client/beacon-api/beacon_api_validator_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,8 @@ func (c *beaconApiValidatorClient) GetBeaconBlock(ctx context.Context, in *ethpb
return c.getBeaconBlock(ctx, in.Slot, in.RandaoReveal, in.Graffiti)
}

func (c *beaconApiValidatorClient) GetFeeRecipientByPubKey(ctx context.Context, in *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error) {
if c.fallbackClient != nil {
return c.fallbackClient.GetFeeRecipientByPubKey(ctx, in)
}

// TODO: Implement me
panic("beaconApiValidatorClient.GetFeeRecipientByPubKey is not implemented. To use a fallback client, create this validator with NewBeaconApiValidatorClientWithFallback instead.")
func (c *beaconApiValidatorClient) GetFeeRecipientByPubKey(_ context.Context, _ *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error) {
return nil, nil
}

func (c *beaconApiValidatorClient) GetSyncCommitteeContribution(ctx context.Context, in *ethpb.SyncCommitteeContributionRequest) (*ethpb.SyncCommitteeContribution, error) {
Expand Down
11 changes: 11 additions & 0 deletions validator/client/beacon-api/beacon_api_validator_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
"github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api/mock"
)

Expand Down Expand Up @@ -95,6 +96,16 @@ func TestBeaconApiValidatorClient_GetAttestationDataError(t *testing.T) {
assert.DeepEqual(t, expectedResp, resp)
}

func TestBeaconApiValidatorClient_GetFeeRecipientByPubKey(t *testing.T) {
ctx := context.Background()
validatorClient := beaconApiValidatorClient{}
var expected *ethpb.FeeRecipientByPubKeyResponse = nil

resp, err := validatorClient.GetFeeRecipientByPubKey(ctx, nil)
require.NoError(t, err)
require.Equal(t, expected, resp)
}

func TestBeaconApiValidatorClient_DomainDataValid(t *testing.T) {
const genesisValidatorRoot = "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
epoch := params.BeaconConfig().AltairForkEpoch
Expand Down
39 changes: 20 additions & 19 deletions validator/rpc/standard_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,27 +535,15 @@ func (s *Server) ListFeeRecipientByPubkey(ctx context.Context, req *ethpbservice

finalResp := &ethpbservice.GetFeeRecipientByPubkeyResponse{
Data: &ethpbservice.GetFeeRecipientByPubkeyResponse_FeeRecipient{
Pubkey: validatorKey,
Ethaddress: params.BeaconConfig().DefaultFeeRecipient.Bytes(),
Pubkey: validatorKey,
},
}

// If no proposer settings is set, use beacon node default (if possible)
if s.validatorService.ProposerSettings() == nil {
resp, err := s.beaconNodeValidatorClient.GetFeeRecipientByPubKey(ctx, &eth.FeeRecipientByPubKeyRequest{
PublicKey: validatorKey,
})

if resp != nil && len(resp.FeeRecipient) != 0 && err == nil {
finalResp.Data.Ethaddress = resp.FeeRecipient
}

return finalResp, nil
}
proposerSettings := s.validatorService.ProposerSettings()

// If fee recipient is defined for this specific pubkey in proposer configuration, use it
if s.validatorService.ProposerSettings().ProposeConfig != nil {
proposerOption, found := s.validatorService.ProposerSettings().ProposeConfig[bytesutil.ToBytes48(validatorKey)]
if proposerSettings != nil && proposerSettings.ProposeConfig != nil {
proposerOption, found := proposerSettings.ProposeConfig[bytesutil.ToBytes48(validatorKey)]

if found && proposerOption.FeeRecipientConfig != nil {
finalResp.Data.Ethaddress = proposerOption.FeeRecipientConfig.FeeRecipient.Bytes()
Expand All @@ -564,13 +552,26 @@ func (s *Server) ListFeeRecipientByPubkey(ctx context.Context, req *ethpbservice
}

// If fee recipient is defined in default configuration, use it
if s.validatorService.ProposerSettings().DefaultConfig != nil && s.validatorService.ProposerSettings().DefaultConfig.FeeRecipientConfig != nil {
if proposerSettings != nil && proposerSettings.DefaultConfig != nil && proposerSettings.DefaultConfig.FeeRecipientConfig != nil {
finalResp.Data.Ethaddress = s.validatorService.ProposerSettings().DefaultConfig.FeeRecipientConfig.FeeRecipient.Bytes()
return finalResp, nil
}

// Default case
return finalResp, nil
// Else, use the one defined in beacon node
resp, err := s.beaconNodeValidatorClient.GetFeeRecipientByPubKey(ctx, &eth.FeeRecipientByPubKeyRequest{
PublicKey: validatorKey,
})

if err != nil {
return nil, status.Error(codes.Internal, "Failed to retrieve default fee recipient from beacon node")
}

if resp != nil && len(resp.FeeRecipient) != 0 {
finalResp.Data.Ethaddress = resp.FeeRecipient
return finalResp, nil
}

return nil, status.Error(codes.InvalidArgument, "No fee recipient set")
}

// SetFeeRecipientByPubkey updates the eth address mapped to the public key.
Expand Down
138 changes: 60 additions & 78 deletions validator/rpc/standard_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"testing"

Expand All @@ -13,7 +14,6 @@ import (
"github.com/golang/protobuf/ptypes/empty"
"github.com/google/uuid"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/pkg/errors"
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
"github.com/prysmaticlabs/prysm/v3/config/params"
validatorserviceconfig "github.com/prysmaticlabs/prysm/v3/config/validator/service"
Expand Down Expand Up @@ -705,34 +705,13 @@ func TestServer_ListFeeRecipientByPubkey(t *testing.T) {
}

tests := []struct {
name string
args *validatorserviceconfig.ProposerSettings
want *want
cached *eth.FeeRecipientByPubKeyResponse
wantErr bool
name string
args *validatorserviceconfig.ProposerSettings
want *want
cached *eth.FeeRecipientByPubKeyResponse
}{
{
name: "ProposerSettings is nil",
args: nil,
want: &want{
EthAddress: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9",
},
cached: &eth.FeeRecipientByPubKeyResponse{
FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9").Bytes(),
},
wantErr: false,
},
{
name: "ProposerSettings is nil - Beacon node error",
args: nil,
want: &want{
EthAddress: "0x0000000000000000000000000000000000000000",
},
cached: nil,
wantErr: true,
},
{
name: "ProposerSettings.ProposeConfig.FeeRecipientConfig defined for pubkey",
name: "ProposerSettings.ProposeConfig.FeeRecipientConfig defined for pubkey (and ProposerSettings.DefaultConfig.FeeRecipientConfig defined)",
args: &validatorserviceconfig.ProposerSettings{
ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{
bytesutil.ToBytes48(byteval): {
Expand All @@ -750,7 +729,6 @@ func TestServer_ListFeeRecipientByPubkey(t *testing.T) {
want: &want{
EthAddress: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9",
},
wantErr: false,
},
{
name: "ProposerSettings.ProposeConfig.FeeRecipientConfig NOT defined for pubkey and ProposerSettings.DefaultConfig.FeeRecipientConfig defined",
Expand All @@ -765,56 +743,16 @@ func TestServer_ListFeeRecipientByPubkey(t *testing.T) {
want: &want{
EthAddress: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9",
},
wantErr: false,
},
{
name: "ProposerSettings.ProposeConfig.FeeRecipientConfig NOT defined for pubkey and ProposerSettings.DefaultConfig is nil",
args: &validatorserviceconfig.ProposerSettings{
ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{},
DefaultConfig: nil,
},
want: &want{
EthAddress: "0x0000000000000000000000000000000000000000",
},
wantErr: false,
},
{
name: "ProposerSettings.ProposeConfig is nil and ProposerSettings.DefaultConfig is nil",
args: &validatorserviceconfig.ProposerSettings{
ProposeConfig: nil,
DefaultConfig: nil,
},
want: &want{
EthAddress: "0x0000000000000000000000000000000000000000",
},
wantErr: false,
},
{
name: "ProposerSettings.ProposeConfig is nil and ProposerSettings.DefaultConfig.FeeRecipientConfig is nil",
args: &validatorserviceconfig.ProposerSettings{
ProposeConfig: nil,
DefaultConfig: &validatorserviceconfig.ProposerOption{
FeeRecipientConfig: nil,
},
},
want: &want{
EthAddress: "0x0000000000000000000000000000000000000000",
},
wantErr: false,
},
{
name: "ProposerSettings.ProposerConfig.FeeRecipientConfig NOT defined for pubkey, ProposerSettings.DefaultConfig.FeeRecipientConfig defined",
args: &validatorserviceconfig.ProposerSettings{
DefaultConfig: &validatorserviceconfig.ProposerOption{
FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{
FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9"),
},
},
},
name: "ProposerSettings is nil and beacon node response is correct",
args: nil,
want: &want{
EthAddress: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9",
},
wantErr: false,
cached: &eth.FeeRecipientByPubKeyResponse{
FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9").Bytes(),
},
},
}
for _, tt := range tests {
Expand All @@ -826,11 +764,7 @@ func TestServer_ListFeeRecipientByPubkey(t *testing.T) {
m.SetProposerSettings(tt.args)

if tt.args == nil {
var err error = nil
if tt.wantErr {
err = errors.New("custom error")
}
mockValidatorClient.EXPECT().GetFeeRecipientByPubKey(gomock.Any(), gomock.Any()).Return(tt.cached, err)
mockValidatorClient.EXPECT().GetFeeRecipientByPubKey(gomock.Any(), gomock.Any()).Return(tt.cached, nil)
}

vs, err := client.NewValidatorService(ctx, &client.Config{
Expand All @@ -851,6 +785,54 @@ func TestServer_ListFeeRecipientByPubkey(t *testing.T) {
}
}

func TestServer_ListFeeRecipientByPubKey_BeaconNodeError(t *testing.T) {
ctx := context.Background()
byteval, err := hexutil.Decode("0xaf2e7ba294e03438ea819bd4033c6c1bf6b04320ee2075b77273c08d02f8a61bcc303c2c06bd3713cb442072ae591493")
require.NoError(t, err)

ctrl := gomock.NewController(t)
mockValidatorClient := mock2.NewMockValidatorClient(ctrl)

mockValidatorClient.EXPECT().GetFeeRecipientByPubKey(gomock.Any(), gomock.Any()).Return(nil, errors.New("custom error"))

vs, err := client.NewValidatorService(ctx, &client.Config{
Validator: &mock.MockValidator{},
})
require.NoError(t, err)

s := &Server{
validatorService: vs,
beaconNodeValidatorClient: mockValidatorClient,
}

_, err = s.ListFeeRecipientByPubkey(ctx, &ethpbservice.PubkeyRequest{Pubkey: byteval})
require.ErrorContains(t, "Failed to retrieve default fee recipient from beacon node", err)
}

func TestServer_ListFeeRecipientByPubKey_NoFeeRecipientSet(t *testing.T) {
ctx := context.Background()
byteval, err := hexutil.Decode("0xaf2e7ba294e03438ea819bd4033c6c1bf6b04320ee2075b77273c08d02f8a61bcc303c2c06bd3713cb442072ae591493")
require.NoError(t, err)

ctrl := gomock.NewController(t)
mockValidatorClient := mock2.NewMockValidatorClient(ctrl)

mockValidatorClient.EXPECT().GetFeeRecipientByPubKey(gomock.Any(), gomock.Any()).Return(nil, nil)

vs, err := client.NewValidatorService(ctx, &client.Config{
Validator: &mock.MockValidator{},
})
require.NoError(t, err)

s := &Server{
validatorService: vs,
beaconNodeValidatorClient: mockValidatorClient,
}

_, err = s.ListFeeRecipientByPubkey(ctx, &ethpbservice.PubkeyRequest{Pubkey: byteval})
require.ErrorContains(t, "No fee recipient set", err)
}

func TestServer_ListFeeRecipientByPubkey_ValidatorServiceNil(t *testing.T) {
ctx := grpc.NewContextWithServerTransportStream(context.Background(), &runtime.ServerTransportStream{})

Expand Down