Fix block proposals in the REST validator client (#13116)

* Fix block proposals in the REST validator client

* fix graffiti test

* return empty graffiti

* fallback to old endpoints

* logs

* handle 404

* everything passes

* review from James

* log undecoded value

* test fixes and additions

---------

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
Radosław Kapka
2023-10-30 19:15:45 +01:00
committed by GitHub
parent 047613069e
commit 2ef0b3526d
11 changed files with 2612 additions and 226 deletions

View File

@@ -5,111 +5,160 @@ import (
"context"
"encoding/json"
"fmt"
"net/http"
neturl "net/url"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/runtime/version"
)
type abstractProduceBlockResponseJson struct {
Version string `json:"version" enum:"true"`
Version string `json:"version"`
Data json.RawMessage `json:"data"`
}
func (c beaconApiValidatorClient) getBeaconBlock(ctx context.Context, slot primitives.Slot, randaoReveal []byte, graffiti []byte) (*ethpb.GenericBeaconBlock, error) {
queryParams := neturl.Values{}
queryParams.Add("randao_reveal", hexutil.Encode(randaoReveal))
if len(graffiti) > 0 {
queryParams.Add("graffiti", hexutil.Encode(graffiti))
}
queryUrl := buildURL(fmt.Sprintf("/eth/v2/validator/blocks/%d", slot), queryParams)
var ver string
var blinded bool
var decoder *json.Decoder
// Since we don't know yet what the json looks like, we unmarshal into an abstract structure that has only a version
// and a blob of data
produceBlockResponseJson := abstractProduceBlockResponseJson{}
if _, err := c.jsonRestHandler.GetRestJsonResponse(ctx, queryUrl, &produceBlockResponseJson); err != nil {
// 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)
produceBlockV3ResponseJson := validator.ProduceBlockV3Response{}
errJson, err := c.jsonRestHandler.GetRestJsonResponse(ctx, queryUrl, &produceBlockV3ResponseJson)
if err == nil {
ver = produceBlockV3ResponseJson.Version
blinded = produceBlockV3ResponseJson.ExecutionPayloadBlinded
decoder = json.NewDecoder(bytes.NewReader(produceBlockV3ResponseJson.Data))
} else if errJson == nil {
return nil, errors.Wrap(err, "failed to query GET REST endpoint")
} else if errJson.Code == http.StatusNotFound {
log.Debug("Endpoint /eth/v3/validator/blocks is not supported, falling back to older endpoints for block proposal.")
produceBlindedBlockResponseJson := abstractProduceBlockResponseJson{}
queryUrl = buildURL(fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d", slot), queryParams)
errJson, err = c.jsonRestHandler.GetRestJsonResponse(ctx, queryUrl, &produceBlindedBlockResponseJson)
if err == nil {
ver = produceBlindedBlockResponseJson.Version
blinded = true
decoder = json.NewDecoder(bytes.NewReader(produceBlindedBlockResponseJson.Data))
} else {
log.Debug("Endpoint /eth/v1/validator/blinded_blocks failed to produce a blinded block, trying /eth/v2/validator/blocks.")
produceBlockResponseJson := abstractProduceBlockResponseJson{}
queryUrl = buildURL(fmt.Sprintf("/eth/v2/validator/blocks/%d", slot), queryParams)
errJson, err = c.jsonRestHandler.GetRestJsonResponse(ctx, queryUrl, &produceBlockResponseJson)
if err != nil {
return nil, errors.Wrap(err, "failed to query GET REST endpoint")
}
ver = produceBlockResponseJson.Version
blinded = false
decoder = json.NewDecoder(bytes.NewReader(produceBlockResponseJson.Data))
}
} else {
return nil, fmt.Errorf("failed to query GET REST endpoint: %s (status code %d)", errJson.Message, errJson.Code)
}
// Once we know what the consensus version is, we can go ahead and unmarshal into the specific structs unique to each version
decoder := json.NewDecoder(bytes.NewReader(produceBlockResponseJson.Data))
response := &ethpb.GenericBeaconBlock{}
switch produceBlockResponseJson.Version {
case "phase0":
jsonPhase0Block := apimiddleware.BeaconBlockJson{}
var response *ethpb.GenericBeaconBlock
switch ver {
case version.String(version.Phase0):
jsonPhase0Block := shared.BeaconBlock{}
if err := decoder.Decode(&jsonPhase0Block); err != nil {
return nil, errors.Wrap(err, "failed to decode phase0 block response json")
}
phase0Block, err := c.beaconBlockConverter.ConvertRESTPhase0BlockToProto(&jsonPhase0Block)
genericBlock, err := jsonPhase0Block.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "failed to get phase0 block")
}
response.Block = &ethpb.GenericBeaconBlock_Phase0{
Phase0: phase0Block,
}
case "altair":
jsonAltairBlock := apimiddleware.BeaconBlockAltairJson{}
response = genericBlock
case version.String(version.Altair):
jsonAltairBlock := shared.BeaconBlockAltair{}
if err := decoder.Decode(&jsonAltairBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode altair block response json")
}
altairBlock, err := c.beaconBlockConverter.ConvertRESTAltairBlockToProto(&jsonAltairBlock)
genericBlock, err := jsonAltairBlock.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "failed to get altair block")
}
response.Block = &ethpb.GenericBeaconBlock_Altair{
Altair: altairBlock,
}
case "bellatrix":
jsonBellatrixBlock := apimiddleware.BeaconBlockBellatrixJson{}
if err := decoder.Decode(&jsonBellatrixBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode bellatrix block response json")
}
bellatrixBlock, err := c.beaconBlockConverter.ConvertRESTBellatrixBlockToProto(&jsonBellatrixBlock)
if err != nil {
return nil, errors.Wrap(err, "failed to get bellatrix block")
}
response.Block = &ethpb.GenericBeaconBlock_Bellatrix{
Bellatrix: bellatrixBlock,
}
case "capella":
jsonCapellaBlock := apimiddleware.BeaconBlockCapellaJson{}
if err := decoder.Decode(&jsonCapellaBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode capella block response json")
}
capellaBlock, err := c.beaconBlockConverter.ConvertRESTCapellaBlockToProto(&jsonCapellaBlock)
if err != nil {
return nil, errors.Wrap(err, "failed to get capella block")
}
response.Block = &ethpb.GenericBeaconBlock_Capella{
Capella: capellaBlock,
}
case "deneb":
jsonDenebBlockContents := shared.BeaconBlockContentsDeneb{}
if err := decoder.Decode(&jsonDenebBlockContents); err != nil {
return nil, errors.Wrap(err, "failed to decode deneb block response json")
}
genericBlock, err := jsonDenebBlockContents.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "could not convert deneb block contents to generic block")
}
response = genericBlock
case version.String(version.Bellatrix):
if blinded {
jsonBellatrixBlock := shared.BlindedBeaconBlockBellatrix{}
if err := decoder.Decode(&jsonBellatrixBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode blinded bellatrix block response json")
}
genericBlock, err := jsonBellatrixBlock.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "failed to get blinded bellatrix block")
}
response = genericBlock
} else {
jsonBellatrixBlock := shared.BeaconBlockBellatrix{}
if err := decoder.Decode(&jsonBellatrixBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode bellatrix block response json")
}
genericBlock, err := jsonBellatrixBlock.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "failed to get bellatrix block")
}
response = genericBlock
}
case version.String(version.Capella):
if blinded {
jsonCapellaBlock := shared.BlindedBeaconBlockCapella{}
if err := decoder.Decode(&jsonCapellaBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode blinded capella block response json")
}
genericBlock, err := jsonCapellaBlock.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "failed to get blinded capella block")
}
response = genericBlock
} else {
jsonCapellaBlock := shared.BeaconBlockCapella{}
if err := decoder.Decode(&jsonCapellaBlock); err != nil {
return nil, errors.Wrap(err, "failed to decode capella block response json")
}
genericBlock, err := jsonCapellaBlock.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "failed to get capella block")
}
response = genericBlock
}
case version.String(version.Deneb):
if blinded {
jsonDenebBlockContents := shared.BlindedBeaconBlockContentsDeneb{}
if err := decoder.Decode(&jsonDenebBlockContents); err != nil {
return nil, errors.Wrap(err, "failed to decode blinded deneb block response json")
}
genericBlock, err := jsonDenebBlockContents.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "failed to get blinded deneb block")
}
response = genericBlock
} else {
jsonDenebBlockContents := shared.BeaconBlockContentsDeneb{}
if err := decoder.Decode(&jsonDenebBlockContents); err != nil {
return nil, errors.Wrap(err, "failed to decode deneb block response json")
}
genericBlock, err := jsonDenebBlockContents.ToGeneric()
if err != nil {
return nil, errors.Wrap(err, "failed to get deneb block")
}
response = genericBlock
}
default:
return nil, errors.Errorf("unsupported consensus version `%s`", produceBlockResponseJson.Version)
return nil, errors.Errorf("unsupported consensus version `%s`", ver)
}
return response, nil
}

View File

@@ -5,13 +5,13 @@ import (
"encoding/json"
"errors"
"fmt"
http2 "net/http"
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/mock/gomock"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
rpctesting "github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared/testing"
"github.com/prysmaticlabs/prysm/v4/api/gateway/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/validator"
"github.com/prysmaticlabs/prysm/v4/consensus-types/primitives"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/v4/testing/assert"
@@ -43,20 +43,12 @@ func TestGetBeaconBlock_RequestFailed(t *testing.T) {
}
func TestGetBeaconBlock_Error(t *testing.T) {
phase0BeaconBlockBytes, err := json.Marshal(apimiddleware.BeaconBlockJson{})
require.NoError(t, err)
altairBeaconBlockBytes, err := json.Marshal(apimiddleware.BeaconBlockAltairJson{})
require.NoError(t, err)
bellatrixBeaconBlockBytes, err := json.Marshal(apimiddleware.BeaconBlockBellatrixJson{})
require.NoError(t, err)
capellaBeaconBlockBytes, err := json.Marshal(apimiddleware.BeaconBlockCapellaJson{})
require.NoError(t, err)
testCases := []struct {
name string
beaconBlock interface{}
expectedErrorMessage string
consensusVersion string
blinded bool
data json.RawMessage
}{
{
@@ -65,49 +57,59 @@ func TestGetBeaconBlock_Error(t *testing.T) {
consensusVersion: "phase0",
data: []byte{},
},
{
name: "phase0 block conversion failed",
expectedErrorMessage: "failed to get phase0 block",
consensusVersion: "phase0",
data: phase0BeaconBlockBytes,
},
{
name: "altair block decoding failed",
expectedErrorMessage: "failed to decode altair block response json",
consensusVersion: "altair",
data: []byte{},
},
{
name: "altair block conversion failed",
expectedErrorMessage: "failed to get altair block",
consensusVersion: "altair",
data: altairBeaconBlockBytes,
},
{
name: "bellatrix block decoding failed",
expectedErrorMessage: "failed to decode bellatrix block response json",
beaconBlock: "foo",
consensusVersion: "bellatrix",
blinded: false,
data: []byte{},
},
{
name: "bellatrix block conversion failed",
expectedErrorMessage: "failed to get bellatrix block",
name: "blinded bellatrix block decoding failed",
expectedErrorMessage: "failed to decode bellatrix block response json",
beaconBlock: "foo",
consensusVersion: "bellatrix",
data: bellatrixBeaconBlockBytes,
blinded: true,
data: []byte{},
},
{
name: "capella block decoding failed",
expectedErrorMessage: "failed to decode capella block response json",
beaconBlock: "foo",
consensusVersion: "capella",
blinded: false,
data: []byte{},
},
{
name: "capella block conversion failed",
expectedErrorMessage: "failed to get capella block",
name: "blinded capella block decoding failed",
expectedErrorMessage: "failed to decode capella block response json",
beaconBlock: "foo",
consensusVersion: "capella",
data: capellaBeaconBlockBytes,
blinded: true,
data: []byte{},
},
{
name: "deneb block decoding failed",
expectedErrorMessage: "failed to decode deneb block response json",
beaconBlock: "foo",
consensusVersion: "deneb",
blinded: false,
data: []byte{},
},
{
name: "blinded deneb block decoding failed",
expectedErrorMessage: "failed to decode deneb block response json",
beaconBlock: "foo",
consensusVersion: "deneb",
blinded: true,
data: []byte{},
},
{
name: "unsupported consensus version",
@@ -127,10 +129,10 @@ func TestGetBeaconBlock_Error(t *testing.T) {
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
gomock.Any(),
&abstractProduceBlockResponseJson{},
&validator.ProduceBlockV3Response{},
).SetArg(
2,
abstractProduceBlockResponseJson{
validator.ProduceBlockV3Response{
Version: testCase.consensusVersion,
Data: testCase.data,
},
@@ -139,36 +141,7 @@ func TestGetBeaconBlock_Error(t *testing.T) {
nil,
).Times(1)
beaconBlockConverter := mock.NewMockbeaconBlockConverter(ctrl)
beaconBlockConverter.EXPECT().ConvertRESTPhase0BlockToProto(
gomock.Any(),
).Return(
nil,
errors.New(testCase.expectedErrorMessage),
).AnyTimes()
beaconBlockConverter.EXPECT().ConvertRESTAltairBlockToProto(
gomock.Any(),
).Return(
nil,
errors.New(testCase.expectedErrorMessage),
).AnyTimes()
beaconBlockConverter.EXPECT().ConvertRESTBellatrixBlockToProto(
gomock.Any(),
).Return(
nil,
errors.New(testCase.expectedErrorMessage),
).AnyTimes()
beaconBlockConverter.EXPECT().ConvertRESTCapellaBlockToProto(
gomock.Any(),
).Return(
nil,
errors.New(testCase.expectedErrorMessage),
).AnyTimes()
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
_, err := validatorClient.getBeaconBlock(ctx, 1, []byte{1}, []byte{2})
assert.ErrorContains(t, testCase.expectedErrorMessage, err)
})
@@ -179,9 +152,9 @@ func TestGetBeaconBlock_Phase0Valid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
phase0ProtoBeaconBlock := test_helpers.GenerateProtoPhase0BeaconBlock()
phase0BeaconBlock := test_helpers.GenerateJsonPhase0BeaconBlock()
phase0BeaconBlockBytes, err := json.Marshal(phase0BeaconBlock)
proto := test_helpers.GenerateProtoPhase0BeaconBlock()
block := test_helpers.GenerateJsonPhase0BeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
@@ -192,34 +165,26 @@ func TestGetBeaconBlock_Phase0Valid(t *testing.T) {
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v2/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).SetArg(
2,
abstractProduceBlockResponseJson{
validator.ProduceBlockV3Response{
Version: "phase0",
Data: phase0BeaconBlockBytes,
Data: bytes,
},
).Return(
nil,
nil,
).Times(1)
beaconBlockConverter := mock.NewMockbeaconBlockConverter(ctrl)
beaconBlockConverter.EXPECT().ConvertRESTPhase0BlockToProto(
phase0BeaconBlock,
).Return(
phase0ProtoBeaconBlock,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Phase0{
Phase0: phase0ProtoBeaconBlock,
Phase0: proto,
},
}
@@ -230,9 +195,9 @@ func TestGetBeaconBlock_AltairValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
altairProtoBeaconBlock := test_helpers.GenerateProtoAltairBeaconBlock()
altairBeaconBlock := test_helpers.GenerateJsonAltairBeaconBlock()
altairBeaconBlockBytes, err := json.Marshal(altairBeaconBlock)
proto := test_helpers.GenerateProtoAltairBeaconBlock()
block := test_helpers.GenerateJsonAltairBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
@@ -244,34 +209,26 @@ func TestGetBeaconBlock_AltairValid(t *testing.T) {
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v2/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).SetArg(
2,
abstractProduceBlockResponseJson{
validator.ProduceBlockV3Response{
Version: "altair",
Data: altairBeaconBlockBytes,
Data: bytes,
},
).Return(
nil,
nil,
).Times(1)
beaconBlockConverter := mock.NewMockbeaconBlockConverter(ctrl)
beaconBlockConverter.EXPECT().ConvertRESTAltairBlockToProto(
altairBeaconBlock,
).Return(
altairProtoBeaconBlock,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Altair{
Altair: altairProtoBeaconBlock,
Altair: proto,
},
}
@@ -282,9 +239,9 @@ func TestGetBeaconBlock_BellatrixValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
bellatrixProtoBeaconBlock := test_helpers.GenerateProtoBellatrixBeaconBlock()
bellatrixBeaconBlock := test_helpers.GenerateJsonBellatrixBeaconBlock()
bellatrixBeaconBlockBytes, err := json.Marshal(bellatrixBeaconBlock)
proto := test_helpers.GenerateProtoBellatrixBeaconBlock()
block := test_helpers.GenerateJsonBellatrixBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
@@ -296,35 +253,75 @@ func TestGetBeaconBlock_BellatrixValid(t *testing.T) {
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v2/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).SetArg(
2,
abstractProduceBlockResponseJson{
Version: "bellatrix",
Data: bellatrixBeaconBlockBytes,
validator.ProduceBlockV3Response{
Version: "bellatrix",
ExecutionPayloadBlinded: false,
Data: bytes,
},
).Return(
nil,
nil,
).Times(1)
beaconBlockConverter := mock.NewMockbeaconBlockConverter(ctrl)
beaconBlockConverter.EXPECT().ConvertRESTBellatrixBlockToProto(
bellatrixBeaconBlock,
).Return(
bellatrixProtoBeaconBlock,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Bellatrix{
Bellatrix: bellatrixProtoBeaconBlock,
Bellatrix: proto,
},
IsBlinded: false,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_BlindedBellatrixValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := test_helpers.GenerateProtoBlindedBellatrixBeaconBlock()
block := test_helpers.GenerateJsonBlindedBellatrixBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
randaoReveal := []byte{2}
graffiti := []byte{3}
ctx := context.Background()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).SetArg(
2,
validator.ProduceBlockV3Response{
Version: "bellatrix",
ExecutionPayloadBlinded: true,
Data: bytes,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_BlindedBellatrix{
BlindedBellatrix: proto,
},
IsBlinded: true,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
@@ -334,9 +331,9 @@ func TestGetBeaconBlock_CapellaValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
capellaProtoBeaconBlock := test_helpers.GenerateProtoCapellaBeaconBlock()
capellaBeaconBlock := test_helpers.GenerateJsonCapellaBeaconBlock()
capellaBeaconBlockBytes, err := json.Marshal(capellaBeaconBlock)
proto := test_helpers.GenerateProtoCapellaBeaconBlock()
block := test_helpers.GenerateJsonCapellaBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
@@ -348,35 +345,75 @@ func TestGetBeaconBlock_CapellaValid(t *testing.T) {
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v2/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).SetArg(
2,
abstractProduceBlockResponseJson{
Version: "capella",
Data: capellaBeaconBlockBytes,
validator.ProduceBlockV3Response{
Version: "capella",
ExecutionPayloadBlinded: false,
Data: bytes,
},
).Return(
nil,
nil,
).Times(1)
beaconBlockConverter := mock.NewMockbeaconBlockConverter(ctrl)
beaconBlockConverter.EXPECT().ConvertRESTCapellaBlockToProto(
capellaBeaconBlock,
).Return(
capellaProtoBeaconBlock,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler, beaconBlockConverter: beaconBlockConverter}
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Capella{
Capella: capellaProtoBeaconBlock,
Capella: proto,
},
IsBlinded: false,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_BlindedCapellaValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := test_helpers.GenerateProtoBlindedCapellaBeaconBlock()
block := test_helpers.GenerateJsonBlindedCapellaBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
randaoReveal := []byte{2}
graffiti := []byte{3}
ctx := context.Background()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).SetArg(
2,
validator.ProduceBlockV3Response{
Version: "capella",
ExecutionPayloadBlinded: true,
Data: bytes,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_BlindedCapella{
BlindedCapella: proto,
},
IsBlinded: true,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
@@ -386,20 +423,179 @@ func TestGetBeaconBlock_DenebValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
var blockContents shared.SignedBeaconBlockContentsDeneb
err := json.Unmarshal([]byte(rpctesting.DenebBlockContents), &blockContents)
proto := test_helpers.GenerateProtoDenebBeaconBlock()
block := test_helpers.GenerateJsonDenebBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
denebBeaconBlockBytes, err := json.Marshal(blockContents.ToUnsigned())
require.NoError(t, err)
ctx := context.Background()
const slot = primitives.Slot(1)
randaoReveal, err := hexutil.Decode("0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505")
require.NoError(t, err)
graffiti, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2")
require.NoError(t, err)
randaoReveal := []byte{2}
graffiti := []byte{3}
ctx := context.Background()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).SetArg(
2,
validator.ProduceBlockV3Response{
Version: "deneb",
ExecutionPayloadBlinded: false,
Data: bytes,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Deneb{
Deneb: proto,
},
IsBlinded: false,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_BlindedDenebValid(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := test_helpers.GenerateProtoBlindedDenebBeaconBlock()
block := test_helpers.GenerateJsonBlindedDenebBeaconBlock()
bytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
randaoReveal := []byte{2}
graffiti := []byte{3}
ctx := context.Background()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).SetArg(
2,
validator.ProduceBlockV3Response{
Version: "deneb",
ExecutionPayloadBlinded: true,
Data: bytes,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_BlindedDeneb{
BlindedDeneb: proto,
},
IsBlinded: true,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_FallbackToBlindedBlock(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := test_helpers.GenerateProtoBlindedDenebBeaconBlock()
block := test_helpers.GenerateJsonBlindedDenebBeaconBlock()
blockBytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
randaoReveal := []byte{2}
graffiti := []byte{3}
ctx := context.Background()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).Return(
&apimiddleware.DefaultErrorJson{Code: http2.StatusNotFound},
errors.New("foo"),
).Times(1)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
).SetArg(
2,
abstractProduceBlockResponseJson{
Version: "deneb",
Data: blockBytes,
},
).Return(
nil,
nil,
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_BlindedDeneb{
BlindedDeneb: proto,
},
IsBlinded: true,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}
func TestGetBeaconBlock_FallbackToFullBlock(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
proto := test_helpers.GenerateProtoDenebBeaconBlock()
block := test_helpers.GenerateJsonDenebBeaconBlock()
blockBytes, err := json.Marshal(block)
require.NoError(t, err)
const slot = primitives.Slot(1)
randaoReveal := []byte{2}
graffiti := []byte{3}
ctx := context.Background()
jsonRestHandler := mock.NewMockjsonRestHandler(ctrl)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v3/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&validator.ProduceBlockV3Response{},
).Return(
&apimiddleware.DefaultErrorJson{Code: http2.StatusNotFound},
errors.New("foo"),
).Times(1)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v1/validator/blinded_blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
&abstractProduceBlockResponseJson{},
).Return(
&apimiddleware.DefaultErrorJson{Code: http2.StatusInternalServerError},
errors.New("foo"),
).Times(1)
jsonRestHandler.EXPECT().GetRestJsonResponse(
ctx,
fmt.Sprintf("/eth/v2/validator/blocks/%d?graffiti=%s&randao_reveal=%s", slot, hexutil.Encode(graffiti), hexutil.Encode(randaoReveal)),
@@ -408,7 +604,7 @@ func TestGetBeaconBlock_DenebValid(t *testing.T) {
2,
abstractProduceBlockResponseJson{
Version: "deneb",
Data: denebBeaconBlockBytes,
Data: blockBytes,
},
).Return(
nil,
@@ -416,12 +612,15 @@ func TestGetBeaconBlock_DenebValid(t *testing.T) {
).Times(1)
validatorClient := &beaconApiValidatorClient{jsonRestHandler: jsonRestHandler}
beaconBlock, err := validatorClient.getBeaconBlock(ctx, slot, randaoReveal, graffiti)
require.NoError(t, err)
expectedBeaconBlock, err := blockContents.ToUnsigned().ToGeneric()
require.NoError(t, err)
expectedBeaconBlock := &ethpb.GenericBeaconBlock{
Block: &ethpb.GenericBeaconBlock_Deneb{
Deneb: proto,
},
IsBlinded: false,
}
assert.DeepEqual(t, expectedBeaconBlock, beaconBlock)
}

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"github.com/pkg/errors"
@@ -88,14 +89,25 @@ func decodeJsonResp(resp *http.Response, responseJson interface{}) (*apimiddlewa
if resp.StatusCode != http.StatusOK {
errorJson := &apimiddleware.DefaultErrorJson{}
if err := decoder.Decode(errorJson); err != nil {
return nil, errors.Wrapf(err, "failed to decode error json for %s", resp.Request.URL)
if resp.StatusCode == http.StatusNotFound {
errorJson = &apimiddleware.DefaultErrorJson{Code: http.StatusNotFound, Message: "Resource not found"}
} else {
remaining, readErr := io.ReadAll(decoder.Buffered())
if readErr == nil {
log.Debugf("Undecoded value: %s", string(remaining))
}
return nil, errors.Wrapf(err, "failed to decode error json for %s", resp.Request.URL)
}
}
return errorJson, errors.Errorf("error %d: %s", errorJson.Code, errorJson.Message)
}
if responseJson != nil {
if err := decoder.Decode(responseJson); err != nil {
remaining, readErr := io.ReadAll(decoder.Buffered())
if readErr == nil {
log.Debugf("Undecoded value: %s", string(remaining))
}
return nil, errors.Wrapf(err, "failed to decode response json for %s", resp.Request.URL)
}
}

View File

@@ -138,6 +138,17 @@ func TestGetRestJsonResponse_Error(t *testing.T) {
timeout: 1,
responseJson: &beacon.GetGenesisResponse{},
},
{
name: "resource not found",
funcHandler: resourceNotFoundHandler,
expectedErrorMessage: "error 404: Resource not found",
expectedErrorJson: &apimiddleware.DefaultErrorJson{
Code: 404,
Message: "Resource not found",
},
timeout: time.Second * 5,
responseJson: &beacon.GetGenesisResponse{},
},
}
for _, testCase := range testCases {
@@ -420,8 +431,12 @@ func httpErrorJsonHandler(statusCode int, errorMessage string) func(w http.Respo
}
}
func invalidJsonErrHandler(w http.ResponseWriter, _ *http.Request) {
func resourceNotFoundHandler(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusNotFound)
}
func invalidJsonErrHandler(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
_, err := w.Write([]byte("foo"))
if err != nil {
panic(err)

View File

@@ -7,6 +7,7 @@ go_library(
"altair_beacon_block_test_helpers.go",
"bellatrix_beacon_block_test_helpers.go",
"capella_beacon_block_test_helpers.go",
"deneb_beacon_block_test_helpers.go",
"phase0_beacon_block_test_helpers.go",
"test_helpers.go",
],
@@ -14,6 +15,7 @@ go_library(
visibility = ["//validator:__subpackages__"],
deps = [
"//beacon-chain/rpc/apimiddleware:go_default_library",
"//beacon-chain/rpc/eth/shared:go_default_library",
"//encoding/bytesutil:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",

View File

@@ -2,6 +2,7 @@ package test_helpers
import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
@@ -240,6 +241,236 @@ func GenerateProtoBellatrixBeaconBlock() *ethpb.BeaconBlockBellatrix {
}
}
func GenerateProtoBlindedBellatrixBeaconBlock() *ethpb.BlindedBeaconBlockBellatrix {
return &ethpb.BlindedBeaconBlockBellatrix{
Slot: 1,
ProposerIndex: 2,
ParentRoot: FillByteSlice(32, 3),
StateRoot: FillByteSlice(32, 4),
Body: &ethpb.BlindedBeaconBlockBodyBellatrix{
RandaoReveal: FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: FillByteSlice(32, 8),
},
Graffiti: FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: FillByteSlice(32, 12),
StateRoot: FillByteSlice(32, 13),
BodyRoot: FillByteSlice(32, 14),
},
Signature: FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: FillByteSlice(32, 18),
StateRoot: FillByteSlice(32, 19),
BodyRoot: FillByteSlice(32, 20),
},
Signature: FillByteSlice(96, 21),
},
},
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: FillByteSlice(32, 24),
StateRoot: FillByteSlice(32, 25),
BodyRoot: FillByteSlice(32, 26),
},
Signature: FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: FillByteSlice(32, 30),
StateRoot: FillByteSlice(32, 31),
BodyRoot: FillByteSlice(32, 32),
},
Signature: FillByteSlice(96, 33),
},
},
},
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{34, 35},
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: FillByteSlice(32, 42),
},
},
Signature: FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: FillByteSlice(32, 52),
},
},
Signature: FillByteSlice(96, 53),
},
},
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{54, 55},
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: FillByteSlice(32, 62),
},
},
Signature: FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: FillByteSlice(32, 72),
},
},
Signature: FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: FillByteSlice(32, 81),
},
},
Signature: FillByteSlice(96, 82),
},
{
AggregationBits: FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: FillByteSlice(32, 90),
},
},
Signature: FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 94),
WithdrawalCredentials: FillByteSlice(32, 95),
Amount: 96,
Signature: FillByteSlice(96, 97),
},
},
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 100),
WithdrawalCredentials: FillByteSlice(32, 101),
Amount: 102,
Signature: FillByteSlice(96, 103),
},
},
},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 104,
ValidatorIndex: 105,
},
Signature: FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: FillByteSlice(96, 109),
},
},
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: FillByteSlice(64, 110),
SyncCommitteeSignature: FillByteSlice(96, 111),
},
ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeader{
ParentHash: FillByteSlice(32, 112),
FeeRecipient: FillByteSlice(20, 113),
StateRoot: FillByteSlice(32, 114),
ReceiptsRoot: FillByteSlice(32, 115),
LogsBloom: FillByteSlice(256, 116),
PrevRandao: FillByteSlice(32, 117),
BlockNumber: 118,
GasLimit: 119,
GasUsed: 120,
Timestamp: 121,
ExtraData: FillByteSlice(32, 122),
BaseFeePerGas: FillByteSlice(32, 123),
BlockHash: FillByteSlice(32, 124),
TransactionsRoot: FillByteSlice(32, 125),
},
},
}
}
func GenerateJsonBellatrixBeaconBlock() *apimiddleware.BeaconBlockBellatrixJson {
return &apimiddleware.BeaconBlockBellatrixJson{
Slot: "1",
@@ -472,3 +703,233 @@ func GenerateJsonBellatrixBeaconBlock() *apimiddleware.BeaconBlockBellatrixJson
},
}
}
func GenerateJsonBlindedBellatrixBeaconBlock() *shared.BlindedBeaconBlockBellatrix {
return &shared.BlindedBeaconBlockBellatrix{
Slot: "1",
ProposerIndex: "2",
ParentRoot: FillEncodedByteSlice(32, 3),
StateRoot: FillEncodedByteSlice(32, 4),
Body: &shared.BlindedBeaconBlockBodyBellatrix{
RandaoReveal: FillEncodedByteSlice(96, 5),
Eth1Data: &shared.Eth1Data{
DepositRoot: FillEncodedByteSlice(32, 6),
DepositCount: "7",
BlockHash: FillEncodedByteSlice(32, 8),
},
Graffiti: FillEncodedByteSlice(32, 9),
ProposerSlashings: []*shared.ProposerSlashing{
{
SignedHeader1: &shared.SignedBeaconBlockHeader{
Message: &shared.BeaconBlockHeader{
Slot: "10",
ProposerIndex: "11",
ParentRoot: FillEncodedByteSlice(32, 12),
StateRoot: FillEncodedByteSlice(32, 13),
BodyRoot: FillEncodedByteSlice(32, 14),
},
Signature: FillEncodedByteSlice(96, 15),
},
SignedHeader2: &shared.SignedBeaconBlockHeader{
Message: &shared.BeaconBlockHeader{
Slot: "16",
ProposerIndex: "17",
ParentRoot: FillEncodedByteSlice(32, 18),
StateRoot: FillEncodedByteSlice(32, 19),
BodyRoot: FillEncodedByteSlice(32, 20),
},
Signature: FillEncodedByteSlice(96, 21),
},
},
{
SignedHeader1: &shared.SignedBeaconBlockHeader{
Message: &shared.BeaconBlockHeader{
Slot: "22",
ProposerIndex: "23",
ParentRoot: FillEncodedByteSlice(32, 24),
StateRoot: FillEncodedByteSlice(32, 25),
BodyRoot: FillEncodedByteSlice(32, 26),
},
Signature: FillEncodedByteSlice(96, 27),
},
SignedHeader2: &shared.SignedBeaconBlockHeader{
Message: &shared.BeaconBlockHeader{
Slot: "28",
ProposerIndex: "29",
ParentRoot: FillEncodedByteSlice(32, 30),
StateRoot: FillEncodedByteSlice(32, 31),
BodyRoot: FillEncodedByteSlice(32, 32),
},
Signature: FillEncodedByteSlice(96, 33),
},
},
},
AttesterSlashings: []*shared.AttesterSlashing{
{
Attestation1: &shared.IndexedAttestation{
AttestingIndices: []string{"34", "35"},
Data: &shared.AttestationData{
Slot: "36",
CommitteeIndex: "37",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "39",
Root: FillEncodedByteSlice(32, 40),
},
Target: &shared.Checkpoint{
Epoch: "41",
Root: FillEncodedByteSlice(32, 42),
},
},
Signature: FillEncodedByteSlice(96, 43),
},
Attestation2: &shared.IndexedAttestation{
AttestingIndices: []string{"44", "45"},
Data: &shared.AttestationData{
Slot: "46",
CommitteeIndex: "47",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "49",
Root: FillEncodedByteSlice(32, 50),
},
Target: &shared.Checkpoint{
Epoch: "51",
Root: FillEncodedByteSlice(32, 52),
},
},
Signature: FillEncodedByteSlice(96, 53),
},
},
{
Attestation1: &shared.IndexedAttestation{
AttestingIndices: []string{"54", "55"},
Data: &shared.AttestationData{
Slot: "56",
CommitteeIndex: "57",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "59",
Root: FillEncodedByteSlice(32, 60),
},
Target: &shared.Checkpoint{
Epoch: "61",
Root: FillEncodedByteSlice(32, 62),
},
},
Signature: FillEncodedByteSlice(96, 63),
},
Attestation2: &shared.IndexedAttestation{
AttestingIndices: []string{"64", "65"},
Data: &shared.AttestationData{
Slot: "66",
CommitteeIndex: "67",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "69",
Root: FillEncodedByteSlice(32, 70),
},
Target: &shared.Checkpoint{
Epoch: "71",
Root: FillEncodedByteSlice(32, 72),
},
},
Signature: FillEncodedByteSlice(96, 73),
},
},
},
Attestations: []*shared.Attestation{
{
AggregationBits: FillEncodedByteSlice(4, 74),
Data: &shared.AttestationData{
Slot: "75",
CommitteeIndex: "76",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "78",
Root: FillEncodedByteSlice(32, 79),
},
Target: &shared.Checkpoint{
Epoch: "80",
Root: FillEncodedByteSlice(32, 81),
},
},
Signature: FillEncodedByteSlice(96, 82),
},
{
AggregationBits: FillEncodedByteSlice(4, 83),
Data: &shared.AttestationData{
Slot: "84",
CommitteeIndex: "85",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "87",
Root: FillEncodedByteSlice(32, 88),
},
Target: &shared.Checkpoint{
Epoch: "89",
Root: FillEncodedByteSlice(32, 90),
},
},
Signature: FillEncodedByteSlice(96, 91),
},
},
Deposits: []*shared.Deposit{
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 92)),
Data: &shared.DepositData{
Pubkey: FillEncodedByteSlice(48, 94),
WithdrawalCredentials: FillEncodedByteSlice(32, 95),
Amount: "96",
Signature: FillEncodedByteSlice(96, 97),
},
},
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 98)),
Data: &shared.DepositData{
Pubkey: FillEncodedByteSlice(48, 100),
WithdrawalCredentials: FillEncodedByteSlice(32, 101),
Amount: "102",
Signature: FillEncodedByteSlice(96, 103),
},
},
},
VoluntaryExits: []*shared.SignedVoluntaryExit{
{
Message: &shared.VoluntaryExit{
Epoch: "104",
ValidatorIndex: "105",
},
Signature: FillEncodedByteSlice(96, 106),
},
{
Message: &shared.VoluntaryExit{
Epoch: "107",
ValidatorIndex: "108",
},
Signature: FillEncodedByteSlice(96, 109),
},
},
SyncAggregate: &shared.SyncAggregate{
SyncCommitteeBits: FillEncodedByteSlice(64, 110),
SyncCommitteeSignature: FillEncodedByteSlice(96, 111),
},
ExecutionPayloadHeader: &shared.ExecutionPayloadHeader{
ParentHash: FillEncodedByteSlice(32, 112),
FeeRecipient: FillEncodedByteSlice(20, 113),
StateRoot: FillEncodedByteSlice(32, 114),
ReceiptsRoot: FillEncodedByteSlice(32, 115),
LogsBloom: FillEncodedByteSlice(256, 116),
PrevRandao: FillEncodedByteSlice(32, 117),
BlockNumber: "118",
GasLimit: "119",
GasUsed: "120",
Timestamp: "121",
ExtraData: FillEncodedByteSlice(32, 122),
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(FillByteSlice(32, 123)).String(),
BlockHash: FillEncodedByteSlice(32, 124),
TransactionsRoot: FillEncodedByteSlice(32, 125),
},
},
}
}

View File

@@ -2,6 +2,7 @@ package test_helpers
import (
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/apimiddleware"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/rpc/eth/shared"
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
@@ -272,6 +273,255 @@ func GenerateProtoCapellaBeaconBlock() *ethpb.BeaconBlockCapella {
}
}
func GenerateProtoBlindedCapellaBeaconBlock() *ethpb.BlindedBeaconBlockCapella {
return &ethpb.BlindedBeaconBlockCapella{
Slot: 1,
ProposerIndex: 2,
ParentRoot: FillByteSlice(32, 3),
StateRoot: FillByteSlice(32, 4),
Body: &ethpb.BlindedBeaconBlockBodyCapella{
RandaoReveal: FillByteSlice(96, 5),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: FillByteSlice(32, 6),
DepositCount: 7,
BlockHash: FillByteSlice(32, 8),
},
Graffiti: FillByteSlice(32, 9),
ProposerSlashings: []*ethpb.ProposerSlashing{
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 10,
ProposerIndex: 11,
ParentRoot: FillByteSlice(32, 12),
StateRoot: FillByteSlice(32, 13),
BodyRoot: FillByteSlice(32, 14),
},
Signature: FillByteSlice(96, 15),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 16,
ProposerIndex: 17,
ParentRoot: FillByteSlice(32, 18),
StateRoot: FillByteSlice(32, 19),
BodyRoot: FillByteSlice(32, 20),
},
Signature: FillByteSlice(96, 21),
},
},
{
Header_1: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 22,
ProposerIndex: 23,
ParentRoot: FillByteSlice(32, 24),
StateRoot: FillByteSlice(32, 25),
BodyRoot: FillByteSlice(32, 26),
},
Signature: FillByteSlice(96, 27),
},
Header_2: &ethpb.SignedBeaconBlockHeader{
Header: &ethpb.BeaconBlockHeader{
Slot: 28,
ProposerIndex: 29,
ParentRoot: FillByteSlice(32, 30),
StateRoot: FillByteSlice(32, 31),
BodyRoot: FillByteSlice(32, 32),
},
Signature: FillByteSlice(96, 33),
},
},
},
AttesterSlashings: []*ethpb.AttesterSlashing{
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{34, 35},
Data: &ethpb.AttestationData{
Slot: 36,
CommitteeIndex: 37,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 39,
Root: FillByteSlice(32, 40),
},
Target: &ethpb.Checkpoint{
Epoch: 41,
Root: FillByteSlice(32, 42),
},
},
Signature: FillByteSlice(96, 43),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{44, 45},
Data: &ethpb.AttestationData{
Slot: 46,
CommitteeIndex: 47,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 49,
Root: FillByteSlice(32, 50),
},
Target: &ethpb.Checkpoint{
Epoch: 51,
Root: FillByteSlice(32, 52),
},
},
Signature: FillByteSlice(96, 53),
},
},
{
Attestation_1: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{54, 55},
Data: &ethpb.AttestationData{
Slot: 56,
CommitteeIndex: 57,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 59,
Root: FillByteSlice(32, 60),
},
Target: &ethpb.Checkpoint{
Epoch: 61,
Root: FillByteSlice(32, 62),
},
},
Signature: FillByteSlice(96, 63),
},
Attestation_2: &ethpb.IndexedAttestation{
AttestingIndices: []uint64{64, 65},
Data: &ethpb.AttestationData{
Slot: 66,
CommitteeIndex: 67,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 69,
Root: FillByteSlice(32, 70),
},
Target: &ethpb.Checkpoint{
Epoch: 71,
Root: FillByteSlice(32, 72),
},
},
Signature: FillByteSlice(96, 73),
},
},
},
Attestations: []*ethpb.Attestation{
{
AggregationBits: FillByteSlice(4, 74),
Data: &ethpb.AttestationData{
Slot: 75,
CommitteeIndex: 76,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 78,
Root: FillByteSlice(32, 79),
},
Target: &ethpb.Checkpoint{
Epoch: 80,
Root: FillByteSlice(32, 81),
},
},
Signature: FillByteSlice(96, 82),
},
{
AggregationBits: FillByteSlice(4, 83),
Data: &ethpb.AttestationData{
Slot: 84,
CommitteeIndex: 85,
BeaconBlockRoot: FillByteSlice(32, 38),
Source: &ethpb.Checkpoint{
Epoch: 87,
Root: FillByteSlice(32, 88),
},
Target: &ethpb.Checkpoint{
Epoch: 89,
Root: FillByteSlice(32, 90),
},
},
Signature: FillByteSlice(96, 91),
},
},
Deposits: []*ethpb.Deposit{
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 92)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 94),
WithdrawalCredentials: FillByteSlice(32, 95),
Amount: 96,
Signature: FillByteSlice(96, 97),
},
},
{
Proof: FillByteArraySlice(33, FillByteSlice(32, 98)),
Data: &ethpb.Deposit_Data{
PublicKey: FillByteSlice(48, 100),
WithdrawalCredentials: FillByteSlice(32, 101),
Amount: 102,
Signature: FillByteSlice(96, 103),
},
},
},
VoluntaryExits: []*ethpb.SignedVoluntaryExit{
{
Exit: &ethpb.VoluntaryExit{
Epoch: 104,
ValidatorIndex: 105,
},
Signature: FillByteSlice(96, 106),
},
{
Exit: &ethpb.VoluntaryExit{
Epoch: 107,
ValidatorIndex: 108,
},
Signature: FillByteSlice(96, 109),
},
},
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: FillByteSlice(64, 110),
SyncCommitteeSignature: FillByteSlice(96, 111),
},
ExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: FillByteSlice(32, 112),
FeeRecipient: FillByteSlice(20, 113),
StateRoot: FillByteSlice(32, 114),
ReceiptsRoot: FillByteSlice(32, 115),
LogsBloom: FillByteSlice(256, 116),
PrevRandao: FillByteSlice(32, 117),
BlockNumber: 118,
GasLimit: 119,
GasUsed: 120,
Timestamp: 121,
ExtraData: FillByteSlice(32, 122),
BaseFeePerGas: FillByteSlice(32, 123),
BlockHash: FillByteSlice(32, 124),
TransactionsRoot: FillByteSlice(32, 125),
WithdrawalsRoot: FillByteSlice(32, 126),
},
BlsToExecutionChanges: []*ethpb.SignedBLSToExecutionChange{
{
Message: &ethpb.BLSToExecutionChange{
ValidatorIndex: 135,
FromBlsPubkey: FillByteSlice(48, 136),
ToExecutionAddress: FillByteSlice(20, 137),
},
Signature: FillByteSlice(96, 138),
},
{
Message: &ethpb.BLSToExecutionChange{
ValidatorIndex: 139,
FromBlsPubkey: FillByteSlice(48, 140),
ToExecutionAddress: FillByteSlice(20, 141),
},
Signature: FillByteSlice(96, 142),
},
},
},
}
}
func GenerateJsonCapellaBeaconBlock() *apimiddleware.BeaconBlockCapellaJson {
return &apimiddleware.BeaconBlockCapellaJson{
Slot: "1",
@@ -536,3 +786,252 @@ func GenerateJsonCapellaBeaconBlock() *apimiddleware.BeaconBlockCapellaJson {
},
}
}
func GenerateJsonBlindedCapellaBeaconBlock() *shared.BlindedBeaconBlockCapella {
return &shared.BlindedBeaconBlockCapella{
Slot: "1",
ProposerIndex: "2",
ParentRoot: FillEncodedByteSlice(32, 3),
StateRoot: FillEncodedByteSlice(32, 4),
Body: &shared.BlindedBeaconBlockBodyCapella{
RandaoReveal: FillEncodedByteSlice(96, 5),
Eth1Data: &shared.Eth1Data{
DepositRoot: FillEncodedByteSlice(32, 6),
DepositCount: "7",
BlockHash: FillEncodedByteSlice(32, 8),
},
Graffiti: FillEncodedByteSlice(32, 9),
ProposerSlashings: []*shared.ProposerSlashing{
{
SignedHeader1: &shared.SignedBeaconBlockHeader{
Message: &shared.BeaconBlockHeader{
Slot: "10",
ProposerIndex: "11",
ParentRoot: FillEncodedByteSlice(32, 12),
StateRoot: FillEncodedByteSlice(32, 13),
BodyRoot: FillEncodedByteSlice(32, 14),
},
Signature: FillEncodedByteSlice(96, 15),
},
SignedHeader2: &shared.SignedBeaconBlockHeader{
Message: &shared.BeaconBlockHeader{
Slot: "16",
ProposerIndex: "17",
ParentRoot: FillEncodedByteSlice(32, 18),
StateRoot: FillEncodedByteSlice(32, 19),
BodyRoot: FillEncodedByteSlice(32, 20),
},
Signature: FillEncodedByteSlice(96, 21),
},
},
{
SignedHeader1: &shared.SignedBeaconBlockHeader{
Message: &shared.BeaconBlockHeader{
Slot: "22",
ProposerIndex: "23",
ParentRoot: FillEncodedByteSlice(32, 24),
StateRoot: FillEncodedByteSlice(32, 25),
BodyRoot: FillEncodedByteSlice(32, 26),
},
Signature: FillEncodedByteSlice(96, 27),
},
SignedHeader2: &shared.SignedBeaconBlockHeader{
Message: &shared.BeaconBlockHeader{
Slot: "28",
ProposerIndex: "29",
ParentRoot: FillEncodedByteSlice(32, 30),
StateRoot: FillEncodedByteSlice(32, 31),
BodyRoot: FillEncodedByteSlice(32, 32),
},
Signature: FillEncodedByteSlice(96, 33),
},
},
},
AttesterSlashings: []*shared.AttesterSlashing{
{
Attestation1: &shared.IndexedAttestation{
AttestingIndices: []string{"34", "35"},
Data: &shared.AttestationData{
Slot: "36",
CommitteeIndex: "37",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "39",
Root: FillEncodedByteSlice(32, 40),
},
Target: &shared.Checkpoint{
Epoch: "41",
Root: FillEncodedByteSlice(32, 42),
},
},
Signature: FillEncodedByteSlice(96, 43),
},
Attestation2: &shared.IndexedAttestation{
AttestingIndices: []string{"44", "45"},
Data: &shared.AttestationData{
Slot: "46",
CommitteeIndex: "47",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "49",
Root: FillEncodedByteSlice(32, 50),
},
Target: &shared.Checkpoint{
Epoch: "51",
Root: FillEncodedByteSlice(32, 52),
},
},
Signature: FillEncodedByteSlice(96, 53),
},
},
{
Attestation1: &shared.IndexedAttestation{
AttestingIndices: []string{"54", "55"},
Data: &shared.AttestationData{
Slot: "56",
CommitteeIndex: "57",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "59",
Root: FillEncodedByteSlice(32, 60),
},
Target: &shared.Checkpoint{
Epoch: "61",
Root: FillEncodedByteSlice(32, 62),
},
},
Signature: FillEncodedByteSlice(96, 63),
},
Attestation2: &shared.IndexedAttestation{
AttestingIndices: []string{"64", "65"},
Data: &shared.AttestationData{
Slot: "66",
CommitteeIndex: "67",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "69",
Root: FillEncodedByteSlice(32, 70),
},
Target: &shared.Checkpoint{
Epoch: "71",
Root: FillEncodedByteSlice(32, 72),
},
},
Signature: FillEncodedByteSlice(96, 73),
},
},
},
Attestations: []*shared.Attestation{
{
AggregationBits: FillEncodedByteSlice(4, 74),
Data: &shared.AttestationData{
Slot: "75",
CommitteeIndex: "76",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "78",
Root: FillEncodedByteSlice(32, 79),
},
Target: &shared.Checkpoint{
Epoch: "80",
Root: FillEncodedByteSlice(32, 81),
},
},
Signature: FillEncodedByteSlice(96, 82),
},
{
AggregationBits: FillEncodedByteSlice(4, 83),
Data: &shared.AttestationData{
Slot: "84",
CommitteeIndex: "85",
BeaconBlockRoot: FillEncodedByteSlice(32, 38),
Source: &shared.Checkpoint{
Epoch: "87",
Root: FillEncodedByteSlice(32, 88),
},
Target: &shared.Checkpoint{
Epoch: "89",
Root: FillEncodedByteSlice(32, 90),
},
},
Signature: FillEncodedByteSlice(96, 91),
},
},
Deposits: []*shared.Deposit{
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 92)),
Data: &shared.DepositData{
Pubkey: FillEncodedByteSlice(48, 94),
WithdrawalCredentials: FillEncodedByteSlice(32, 95),
Amount: "96",
Signature: FillEncodedByteSlice(96, 97),
},
},
{
Proof: FillEncodedByteArraySlice(33, FillEncodedByteSlice(32, 98)),
Data: &shared.DepositData{
Pubkey: FillEncodedByteSlice(48, 100),
WithdrawalCredentials: FillEncodedByteSlice(32, 101),
Amount: "102",
Signature: FillEncodedByteSlice(96, 103),
},
},
},
VoluntaryExits: []*shared.SignedVoluntaryExit{
{
Message: &shared.VoluntaryExit{
Epoch: "104",
ValidatorIndex: "105",
},
Signature: FillEncodedByteSlice(96, 106),
},
{
Message: &shared.VoluntaryExit{
Epoch: "107",
ValidatorIndex: "108",
},
Signature: FillEncodedByteSlice(96, 109),
},
},
SyncAggregate: &shared.SyncAggregate{
SyncCommitteeBits: FillEncodedByteSlice(64, 110),
SyncCommitteeSignature: FillEncodedByteSlice(96, 111),
},
ExecutionPayloadHeader: &shared.ExecutionPayloadHeaderCapella{
ParentHash: FillEncodedByteSlice(32, 112),
FeeRecipient: FillEncodedByteSlice(20, 113),
StateRoot: FillEncodedByteSlice(32, 114),
ReceiptsRoot: FillEncodedByteSlice(32, 115),
LogsBloom: FillEncodedByteSlice(256, 116),
PrevRandao: FillEncodedByteSlice(32, 117),
BlockNumber: "118",
GasLimit: "119",
GasUsed: "120",
Timestamp: "121",
ExtraData: FillEncodedByteSlice(32, 122),
BaseFeePerGas: bytesutil.LittleEndianBytesToBigInt(FillByteSlice(32, 123)).String(),
BlockHash: FillEncodedByteSlice(32, 124),
TransactionsRoot: FillEncodedByteSlice(32, 125),
WithdrawalsRoot: FillEncodedByteSlice(32, 126),
},
BlsToExecutionChanges: []*shared.SignedBlsToExecutionChange{
{
Message: &shared.BlsToExecutionChange{
ValidatorIndex: "135",
FromBlsPubkey: FillEncodedByteSlice(48, 136),
ToExecutionAddress: FillEncodedByteSlice(20, 137),
},
Signature: FillEncodedByteSlice(96, 138),
},
{
Message: &shared.BlsToExecutionChange{
ValidatorIndex: "139",
FromBlsPubkey: FillEncodedByteSlice(48, 140),
ToExecutionAddress: FillEncodedByteSlice(20, 141),
},
Signature: FillEncodedByteSlice(96, 142),
},
},
},
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -411,7 +411,7 @@ func signVoluntaryExit(
func (v *validator) getGraffiti(ctx context.Context, pubKey [fieldparams.BLSPubkeyLength]byte) ([]byte, error) {
// When specified, default graffiti from the command line takes the first priority.
if len(v.graffiti) != 0 {
return v.graffiti, nil
return bytesutil.PadTo(v.graffiti, 32), nil
}
if v.graffitiStruct == nil {
@@ -421,11 +421,11 @@ func (v *validator) getGraffiti(ctx context.Context, pubKey [fieldparams.BLSPubk
// When specified, individual validator specified graffiti takes the second priority.
idx, err := v.validatorClient.ValidatorIndex(ctx, &ethpb.ValidatorIndexRequest{PublicKey: pubKey[:]})
if err != nil {
return []byte{}, err
return nil, err
}
g, ok := v.graffitiStruct.Specific[idx.Index]
if ok {
return []byte(g), nil
return bytesutil.PadTo([]byte(g), 32), nil
}
// When specified, a graffiti from the ordered list in the file take third priority.
@@ -436,7 +436,7 @@ func (v *validator) getGraffiti(ctx context.Context, pubKey [fieldparams.BLSPubk
if err != nil {
return nil, errors.Wrap(err, "failed to update graffiti ordered index")
}
return []byte(graffiti), nil
return bytesutil.PadTo([]byte(graffiti), 32), nil
}
// When specified, a graffiti from the random list in the file take fourth priority.
@@ -444,12 +444,12 @@ func (v *validator) getGraffiti(ctx context.Context, pubKey [fieldparams.BLSPubk
r := rand.NewGenerator()
r.Seed(time.Now().Unix())
i := r.Uint64() % uint64(len(v.graffitiStruct.Random))
return []byte(v.graffitiStruct.Random[i]), nil
return bytesutil.PadTo([]byte(v.graffitiStruct.Random[i]), 32), nil
}
// Finally, default graffiti if specified in the file will be used.
if v.graffitiStruct.Default != "" {
return []byte(v.graffitiStruct.Default), nil
return bytesutil.PadTo([]byte(v.graffitiStruct.Default), 32), nil
}
return []byte{}, nil

View File

@@ -963,7 +963,7 @@ func TestGetGraffiti_Ok(t *testing.T) {
},
},
},
want: []byte{'b'},
want: bytesutil.PadTo([]byte{'b'}, 32),
},
{name: "use default file graffiti",
v: &validator{
@@ -972,7 +972,7 @@ func TestGetGraffiti_Ok(t *testing.T) {
Default: "c",
},
},
want: []byte{'c'},
want: bytesutil.PadTo([]byte{'c'}, 32),
},
{name: "use random file graffiti",
v: &validator{
@@ -982,7 +982,7 @@ func TestGetGraffiti_Ok(t *testing.T) {
Default: "c",
},
},
want: []byte{'d'},
want: bytesutil.PadTo([]byte{'d'}, 32),
},
{name: "use validator file graffiti, has validator",
v: &validator{
@@ -996,7 +996,7 @@ func TestGetGraffiti_Ok(t *testing.T) {
},
},
},
want: []byte{'g'},
want: bytesutil.PadTo([]byte{'g'}, 32),
},
{name: "use validator file graffiti, none specified",
v: &validator{
@@ -1041,7 +1041,7 @@ func TestGetGraffitiOrdered_Ok(t *testing.T) {
Default: "d",
},
}
for _, want := range [][]byte{{'a'}, {'b'}, {'c'}, {'d'}, {'d'}} {
for _, want := range [][]byte{bytesutil.PadTo([]byte{'a'}, 32), bytesutil.PadTo([]byte{'b'}, 32), bytesutil.PadTo([]byte{'c'}, 32), bytesutil.PadTo([]byte{'d'}, 32), bytesutil.PadTo([]byte{'d'}, 32)} {
got, err := v.getGraffiti(context.Background(), pubKey)
require.NoError(t, err)
require.DeepEqual(t, want, got)