diff --git a/validator/client/beacon-api/BUILD.bazel b/validator/client/beacon-api/BUILD.bazel index fad6d0ea3bb0..d20ebef092a6 100644 --- a/validator/client/beacon-api/BUILD.bazel +++ b/validator/client/beacon-api/BUILD.bazel @@ -66,6 +66,7 @@ go_library( "@com_github_sirupsen_logrus//:go_default_library", "@org_golang_google_grpc//:go_default_library", "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", ], ) @@ -145,5 +146,6 @@ go_test( "@com_github_sirupsen_logrus//hooks/test:go_default_library", "@org_golang_google_protobuf//types/known/emptypb:go_default_library", "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + "@org_golang_google_protobuf//types/known/wrapperspb:go_default_library", ], ) diff --git a/validator/client/beacon-api/beacon_api_validator_client.go b/validator/client/beacon-api/beacon_api_validator_client.go index df7fc6a06333..cd341be7cb95 100644 --- a/validator/client/beacon-api/beacon_api_validator_client.go +++ b/validator/client/beacon-api/beacon_api_validator_client.go @@ -75,7 +75,7 @@ func (c *beaconApiValidatorClient) GetAttestationData(ctx context.Context, in *e } func (c *beaconApiValidatorClient) GetBeaconBlock(ctx context.Context, in *ethpb.BlockRequest) (*ethpb.GenericBeaconBlock, error) { - return c.getBeaconBlock(ctx, in.Slot, in.RandaoReveal, in.Graffiti) + return c.getBeaconBlock(ctx, in.Slot, in.RandaoReveal, in.Graffiti, in.BuilderBoostFactor) } func (c *beaconApiValidatorClient) GetFeeRecipientByPubKey(_ context.Context, _ *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error) { diff --git a/validator/client/beacon-api/get_beacon_block.go b/validator/client/beacon-api/get_beacon_block.go index 5726894fbd3d..7e15d9b60117 100644 --- a/validator/client/beacon-api/get_beacon_block.go +++ b/validator/client/beacon-api/get_beacon_block.go @@ -16,6 +16,7 @@ import ( "github.com/prysmaticlabs/prysm/v4/network/httputil" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/runtime/version" + "google.golang.org/protobuf/types/known/wrapperspb" ) type abstractProduceBlockResponseJson struct { @@ -23,12 +24,19 @@ type abstractProduceBlockResponseJson struct { Data json.RawMessage `json:"data"` } -func (c beaconApiValidatorClient) getBeaconBlock(ctx context.Context, slot primitives.Slot, randaoReveal []byte, graffiti []byte) (*ethpb.GenericBeaconBlock, error) { +func buildGetBeaconBlockUrlValues(randaoReveal []byte, graffiti []byte, builderBoostFactor *wrapperspb.UInt64Value) neturl.Values { queryParams := neturl.Values{} + if builderBoostFactor != nil { + queryParams.Add("builder_boost_factor", fmt.Sprint(builderBoostFactor.Value)) + } queryParams.Add("randao_reveal", hexutil.Encode(randaoReveal)) if len(graffiti) > 0 { queryParams.Add("graffiti", hexutil.Encode(graffiti)) } + return queryParams +} + +func (c beaconApiValidatorClient) getBeaconBlock(ctx context.Context, slot primitives.Slot, randaoReveal []byte, graffiti []byte, builderBoostFactor *wrapperspb.UInt64Value) (*ethpb.GenericBeaconBlock, error) { var ver string var blinded bool @@ -36,7 +44,7 @@ func (c beaconApiValidatorClient) getBeaconBlock(ctx context.Context, slot primi // Try v3 endpoint first. If it's not supported, then we fall back to older endpoints. // We try the blinded block endpoint first. If it fails, we assume that we got a full block and try the full block endpoint. - queryUrl := buildURL(fmt.Sprintf("/eth/v3/validator/blocks/%d", slot), queryParams) + queryUrl := buildURL(fmt.Sprintf("/eth/v3/validator/blocks/%d", slot), buildGetBeaconBlockUrlValues(randaoReveal, graffiti, builderBoostFactor)) produceBlockV3ResponseJson := validator.ProduceBlockV3Response{} err := c.jsonRestHandler.Get(ctx, queryUrl, &produceBlockV3ResponseJson) errJson := &httputil.DefaultJsonError{} @@ -48,14 +56,14 @@ func (c beaconApiValidatorClient) getBeaconBlock(ctx context.Context, slot primi return nil, errJson } log.Debug("Endpoint /eth/v3/validator/blocks is not supported, falling back to older endpoints for block proposal.") - fallbackResp, err := c.fallBackToBlinded(ctx, slot, queryParams) + fallbackResp, err := c.fallBackToBlinded(ctx, slot, buildGetBeaconBlockUrlValues(randaoReveal, graffiti, nil)) errJson = &httputil.DefaultJsonError{} if err != nil { if !errors.As(err, &errJson) { return nil, err } log.Debug("Endpoint /eth/v1/validator/blinded_blocks failed to produce a blinded block, trying /eth/v2/validator/blocks.") - fallbackResp, err = c.fallBackToFull(ctx, slot, queryParams) + fallbackResp, err = c.fallBackToFull(ctx, slot, buildGetBeaconBlockUrlValues(randaoReveal, graffiti, nil)) if err != nil { return nil, err } diff --git a/validator/client/beacon-api/get_beacon_block_test.go b/validator/client/beacon-api/get_beacon_block_test.go index 79e2a1e1e3f3..b21ee6d70bc4 100644 --- a/validator/client/beacon-api/get_beacon_block_test.go +++ b/validator/client/beacon-api/get_beacon_block_test.go @@ -18,6 +18,7 @@ import ( "github.com/prysmaticlabs/prysm/v4/testing/require" "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/mock" test_helpers "github.com/prysmaticlabs/prysm/v4/validator/client/beacon-api/test-helpers" + "google.golang.org/protobuf/types/known/wrapperspb" ) func TestGetBeaconBlock_RequestFailed(t *testing.T) { @@ -36,7 +37,7 @@ func TestGetBeaconBlock_RequestFailed(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - _, err := validatorClient.getBeaconBlock(ctx, 1, []byte{1}, []byte{2}) + _, err := validatorClient.getBeaconBlock(ctx, 1, []byte{1}, []byte{2}, nil) assert.ErrorContains(t, "foo error", err) } @@ -139,7 +140,7 @@ func TestGetBeaconBlock_Error(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - _, err := validatorClient.getBeaconBlock(ctx, 1, []byte{1}, []byte{2}) + _, err := validatorClient.getBeaconBlock(ctx, 1, []byte{1}, []byte{2}, nil) assert.ErrorContains(t, testCase.expectedErrorMessage, err) }) } @@ -175,7 +176,7 @@ func TestGetBeaconBlock_Phase0Valid(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, nil) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -218,7 +219,7 @@ func TestGetBeaconBlock_AltairValid(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, nil) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -262,7 +263,7 @@ func TestGetBeaconBlock_BellatrixValid(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, nil) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -307,7 +308,7 @@ func TestGetBeaconBlock_BlindedBellatrixValid(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, nil) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -352,7 +353,7 @@ func TestGetBeaconBlock_CapellaValid(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, nil) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -397,7 +398,7 @@ func TestGetBeaconBlock_BlindedCapellaValid(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, nil) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -442,7 +443,7 @@ func TestGetBeaconBlock_DenebValid(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, nil) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -473,7 +474,7 @@ func TestGetBeaconBlock_BlindedDenebValid(t *testing.T) { jsonRestHandler := mock.NewMockJsonRestHandler(ctrl) jsonRestHandler.EXPECT().Get( ctx, - fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)), + fmt.Sprintf("/eth/v3/validator/blocks/%d?builder_boost_factor=%s&graffiti=%s&randao_reveal=%s", slot, "100", hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)), &validator.ProduceBlockV3Response{}, ).SetArg( 2, @@ -487,7 +488,7 @@ func TestGetBeaconBlock_BlindedDenebValid(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, &wrapperspb.UInt64Value{Value: 100}) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -518,7 +519,7 @@ func TestGetBeaconBlock_FallbackToBlindedBlock(t *testing.T) { jsonRestHandler := mock.NewMockJsonRestHandler(ctrl) jsonRestHandler.EXPECT().Get( ctx, - fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)), + fmt.Sprintf("/eth/v3/validator/blocks/%d?builder_boost_factor=%s&graffiti=%s&randao_reveal=%s", slot, "100", hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)), &validator.ProduceBlockV3Response{}, ).Return( &httputil.DefaultJsonError{Code: http.StatusNotFound}, @@ -538,7 +539,7 @@ func TestGetBeaconBlock_FallbackToBlindedBlock(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, &wrapperspb.UInt64Value{Value: 100}) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{ @@ -569,7 +570,7 @@ func TestGetBeaconBlock_FallbackToFullBlock(t *testing.T) { jsonRestHandler := mock.NewMockJsonRestHandler(ctrl) jsonRestHandler.EXPECT().Get( ctx, - fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)), + fmt.Sprintf("/eth/v3/validator/blocks/%d?builder_boost_factor=%s&graffiti=%s&randao_reveal=%s", slot, "100", hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)), &validator.ProduceBlockV3Response{}, ).Return( &httputil.DefaultJsonError{Code: http.StatusNotFound}, @@ -596,7 +597,7 @@ func TestGetBeaconBlock_FallbackToFullBlock(t *testing.T) { ).Times(1) validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler} - beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti) + beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti, &wrapperspb.UInt64Value{Value: 100}) require.NoError(t, err) expectedBeaconBlock := ðpb.GenericBeaconBlock{