From 898e143f37ba300e7124ac56d93d520146e7c3db Mon Sep 17 00:00:00 2001 From: james-prysm <90280386+james-prysm@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:04:48 -0500 Subject: [PATCH] introducing deneb changes and blobs to builder (#12477) --- api/client/builder/BUILD.bazel | 3 +- api/client/builder/bid.go | 107 +++- api/client/builder/client.go | 87 ++- api/client/builder/client_test.go | 253 ++++++++- api/client/builder/testing/BUILD.bazel | 1 + api/client/builder/testing/mock.go | 5 +- api/client/builder/types.go | 290 ++++++++++ api/client/builder/types_test.go | 301 +++++++++++ beacon-chain/builder/BUILD.bazel | 2 + beacon-chain/builder/service.go | 14 +- beacon-chain/builder/service_test.go | 2 +- beacon-chain/builder/testing/mock.go | 26 +- beacon-chain/execution/BUILD.bazel | 1 - beacon-chain/execution/engine_client.go | 7 +- beacon-chain/execution/testing/BUILD.bazel | 1 + .../execution/testing/mock_engine_client.go | 5 +- .../rpc/prysm/v1alpha1/validator/unblinder.go | 5 +- consensus-types/blocks/BUILD.bazel | 1 + consensus-types/blocks/execution.go | 25 +- math/math_helper.go | 10 +- math/math_helper_test.go | 4 +- proto/engine/v1/BUILD.bazel | 2 + proto/engine/v1/execution_engine.pb.go | 144 ++++- proto/engine/v1/execution_engine.proto | 12 +- proto/engine/v1/generated.ssz.go | 494 +++++++++++++++++- proto/engine/v1/json_marshal_unmarshal.go | 12 +- .../engine/v1/json_marshal_unmarshal_test.go | 8 +- proto/eth/v1/generated.ssz.go | 2 +- proto/eth/v2/generated.ssz.go | 2 +- proto/prysm/v1alpha1/BUILD.bazel | 1 + proto/prysm/v1alpha1/beacon_block.pb.go | 301 ++++++++--- proto/prysm/v1alpha1/beacon_block.proto | 12 + proto/prysm/v1alpha1/generated.ssz.go | 174 +++++- testing/middleware/builder/builder.go | 6 +- testing/util/BUILD.bazel | 1 + testing/util/blob.go | 37 ++ testing/util/merge.go | 5 + 37 files changed, 2195 insertions(+), 168 deletions(-) create mode 100644 testing/util/blob.go diff --git a/api/client/builder/BUILD.bazel b/api/client/builder/BUILD.bazel index ae3f44c9827..ca2b537fb92 100644 --- a/api/client/builder/BUILD.bazel +++ b/api/client/builder/BUILD.bazel @@ -11,12 +11,12 @@ go_library( importpath = "github.com/prysmaticlabs/prysm/v4/api/client/builder", visibility = ["//visibility:public"], deps = [ + "//config/fieldparams:go_default_library", "//consensus-types:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", - "//math:go_default_library", "//monitoring/tracing:go_default_library", "//network:go_default_library", "//network/authorization:go_default_library", @@ -40,6 +40,7 @@ go_test( data = glob(["testdata/**"]), embed = [":go_default_library"], deps = [ + "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/primitives:go_default_library", diff --git a/api/client/builder/bid.go b/api/client/builder/bid.go index 43e4ef434cb..293a599a153 100644 --- a/api/client/builder/bid.go +++ b/api/client/builder/bid.go @@ -1,14 +1,12 @@ package builder import ( - "math/big" - + "github.com/pkg/errors" ssz "github.com/prysmaticlabs/fastssz" consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types" "github.com/prysmaticlabs/prysm/v4/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces" - "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" - "github.com/prysmaticlabs/prysm/v4/math" + enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/runtime/version" ) @@ -24,6 +22,7 @@ type SignedBid interface { // Bid is an interface describing the method set of a builder bid. type Bid interface { Header() (interfaces.ExecutionData, error) + BlindedBlobsBundle() (*enginev1.BlindedBlobsBundle, error) Value() []byte Pubkey() []byte Version() int @@ -116,6 +115,11 @@ func (b builderBid) Header() (interfaces.ExecutionData, error) { return blocks.WrappedExecutionPayloadHeader(b.p.Header) } +// BlindedBlobsBundle -- +func (b builderBid) BlindedBlobsBundle() (*enginev1.BlindedBlobsBundle, error) { + return nil, errors.New("blinded blobs bundle not available before Deneb") +} + // Version -- func (b builderBid) Version() int { return version.Bellatrix @@ -162,8 +166,12 @@ func WrappedBuilderBidCapella(p *ethpb.BuilderBidCapella) (Bid, error) { // Header returns the execution data interface. func (b builderBidCapella) Header() (interfaces.ExecutionData, error) { // We have to convert big endian to little endian because the value is coming from the execution layer. - v := big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(b.p.Value)) - return blocks.WrappedExecutionPayloadHeaderCapella(b.p.Header, math.WeiToGwei(v)) + return blocks.WrappedExecutionPayloadHeaderCapella(b.p.Header, blocks.PayloadValueToGwei(b.p.Value)) +} + +// BlindedBlobsBundle -- +func (b builderBidCapella) BlindedBlobsBundle() (*enginev1.BlindedBlobsBundle, error) { + return nil, errors.New("blinded blobs bundle not available before Deneb") } // Version -- @@ -195,3 +203,90 @@ func (b builderBidCapella) HashTreeRoot() ([32]byte, error) { func (b builderBidCapella) HashTreeRootWith(hh *ssz.Hasher) error { return b.p.HashTreeRootWith(hh) } + +type builderBidDeneb struct { + p *ethpb.BuilderBidDeneb +} + +// WrappedBuilderBidDeneb is a constructor which wraps a protobuf bid into an interface. +func WrappedBuilderBidDeneb(p *ethpb.BuilderBidDeneb) (Bid, error) { + w := builderBidDeneb{p: p} + if w.IsNil() { + return nil, consensus_types.ErrNilObjectWrapped + } + return w, nil +} + +// Version -- +func (b builderBidDeneb) Version() int { + return version.Deneb +} + +// Value -- +func (b builderBidDeneb) Value() []byte { + return b.p.Value +} + +// Pubkey -- +func (b builderBidDeneb) Pubkey() []byte { + return b.p.Pubkey +} + +// IsNil -- +func (b builderBidDeneb) IsNil() bool { + return b.p == nil +} + +// HashTreeRoot -- +func (b builderBidDeneb) HashTreeRoot() ([32]byte, error) { + return b.p.HashTreeRoot() +} + +// HashTreeRootWith -- +func (b builderBidDeneb) HashTreeRootWith(hh *ssz.Hasher) error { + return b.p.HashTreeRootWith(hh) +} + +// Header -- +func (b builderBidDeneb) Header() (interfaces.ExecutionData, error) { + // We have to convert big endian to little endian because the value is coming from the execution layer. + return blocks.WrappedExecutionPayloadHeaderDeneb(b.p.Header, blocks.PayloadValueToGwei(b.p.Value)) +} + +// BlindedBlobsBundle -- +func (b builderBidDeneb) BlindedBlobsBundle() (*enginev1.BlindedBlobsBundle, error) { + return b.p.BlindedBlobsBundle, nil +} + +type signedBuilderBidDeneb struct { + p *ethpb.SignedBuilderBidDeneb +} + +// WrappedSignedBuilderBidDeneb is a constructor which wraps a protobuf signed bit into an interface. +func WrappedSignedBuilderBidDeneb(p *ethpb.SignedBuilderBidDeneb) (SignedBid, error) { + w := signedBuilderBidDeneb{p: p} + if w.IsNil() { + return nil, consensus_types.ErrNilObjectWrapped + } + return w, nil +} + +// Message -- +func (b signedBuilderBidDeneb) Message() (Bid, error) { + return WrappedBuilderBidDeneb(b.p.Message) +} + +// Signature -- +func (b signedBuilderBidDeneb) Signature() []byte { + return b.p.Signature +} + +// Version -- +func (b signedBuilderBidDeneb) Version() int { + return version.Deneb +} + +// IsNil -- +func (b signedBuilderBidDeneb) IsNil() bool { + return b.p == nil +} diff --git a/api/client/builder/client.go b/api/client/builder/client.go index 373f3d01aa9..58a742c441c 100644 --- a/api/client/builder/client.go +++ b/api/client/builder/client.go @@ -19,6 +19,7 @@ import ( "github.com/prysmaticlabs/prysm/v4/monitoring/tracing" "github.com/prysmaticlabs/prysm/v4/network" "github.com/prysmaticlabs/prysm/v4/network/authorization" + v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/runtime/version" log "github.com/sirupsen/logrus" @@ -86,7 +87,7 @@ type BuilderClient interface { NodeURL() string GetHeader(ctx context.Context, slot primitives.Slot, parentHash [32]byte, pubkey [48]byte) (SignedBid, error) RegisterValidator(ctx context.Context, svr []*ethpb.SignedValidatorRegistrationV1) error - SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, error) + SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock, blobs []*ethpb.SignedBlindedBlobSidecar) (interfaces.ExecutionData, *v1.BlobsBundle, error) Status(ctx context.Context) error } @@ -220,6 +221,16 @@ func (c *Client) GetHeader(ctx context.Context, slot primitives.Slot, parentHash return nil, errors.Wrapf(err, "error unmarshaling the builder GetHeader response, using slot=%d, parentHash=%#x, pubkey=%#x", slot, parentHash, pubkey) } switch strings.ToLower(v.Version) { + case strings.ToLower(version.String(version.Deneb)): + hr := &ExecHeaderResponseDeneb{} + if err := json.Unmarshal(hb, hr); err != nil { + return nil, errors.Wrapf(err, "error unmarshaling the builder GetHeader response, using slot=%d, parentHash=%#x, pubkey=%#x", slot, parentHash, pubkey) + } + p, err := hr.ToProto() + if err != nil { + return nil, errors.Wrapf(err, "could not extract proto message from header") + } + return WrappedSignedBuilderBidDeneb(p) case strings.ToLower(version.String(version.Capella)): hr := &ExecHeaderResponseCapella{} if err := json.Unmarshal(hb, hr); err != nil { @@ -274,20 +285,20 @@ func (c *Client) RegisterValidator(ctx context.Context, svr []*ethpb.SignedValid // SubmitBlindedBlock calls the builder API endpoint that binds the validator to the builder and submits the block. // The response is the full execution payload used to create the blinded block. -func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, error) { +func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock, blobs []*ethpb.SignedBlindedBlobSidecar) (interfaces.ExecutionData, *v1.BlobsBundle, error) { if !sb.IsBlinded() { - return nil, errNotBlinded + return nil, nil, errNotBlinded } switch sb.Version() { case version.Bellatrix: psb, err := sb.PbBlindedBellatrixBlock() if err != nil { - return nil, errors.Wrapf(err, "could not get protobuf block") + return nil, nil, errors.Wrapf(err, "could not get protobuf block") } b := &SignedBlindedBeaconBlockBellatrix{SignedBlindedBeaconBlockBellatrix: psb} body, err := json.Marshal(b) if err != nil { - return nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockBellatrix value body in SubmitBlindedBlock") + return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockBellatrix value body in SubmitBlindedBlock") } versionOpt := func(r *http.Request) { @@ -296,29 +307,33 @@ func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlyS rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt) if err != nil { - return nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockBellatrix to the builder api") + return nil, nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockBellatrix to the builder api") } ep := &ExecPayloadResponse{} if err := json.Unmarshal(rb, ep); err != nil { - return nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlock response") + return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlock response") } if strings.ToLower(ep.Version) != version.String(version.Bellatrix) { - return nil, errors.New("not a bellatrix payload") + return nil, nil, errors.New("not a bellatrix payload") } p, err := ep.ToProto() if err != nil { - return nil, errors.Wrapf(err, "could not extract proto message from payload") + return nil, nil, errors.Wrapf(err, "could not extract proto message from payload") } - return blocks.WrappedExecutionPayload(p) + payload, err := blocks.WrappedExecutionPayload(p) + if err != nil { + return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface") + } + return payload, nil, nil case version.Capella: psb, err := sb.PbBlindedCapellaBlock() if err != nil { - return nil, errors.Wrapf(err, "could not get protobuf block") + return nil, nil, errors.Wrapf(err, "could not get protobuf block") } b := &SignedBlindedBeaconBlockCapella{SignedBlindedBeaconBlockCapella: psb} body, err := json.Marshal(b) if err != nil { - return nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockCapella value body in SubmitBlindedBlockCapella") + return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockCapella value body in SubmitBlindedBlockCapella") } versionOpt := func(r *http.Request) { @@ -327,22 +342,58 @@ func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlyS rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt) if err != nil { - return nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockCapella to the builder api") + return nil, nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockCapella to the builder api") } ep := &ExecPayloadResponseCapella{} if err := json.Unmarshal(rb, ep); err != nil { - return nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlockCapella response") + return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlockCapella response") } if strings.ToLower(ep.Version) != version.String(version.Capella) { - return nil, errors.New("not a capella payload") + return nil, nil, errors.New("not a capella payload") } p, err := ep.ToProto() if err != nil { - return nil, errors.Wrapf(err, "could not extract proto message from payload") + return nil, nil, errors.Wrapf(err, "could not extract proto message from payload") + } + payload, err := blocks.WrappedExecutionPayloadCapella(p, 0) + if err != nil { + return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface") + } + return payload, nil, nil + case version.Deneb: + psb, err := sb.PbBlindedDenebBlock() + if err != nil { + return nil, nil, errors.Wrapf(err, "could not get protobuf block") + } + + b := ðpb.SignedBlindedBeaconBlockAndBlobsDeneb{Block: psb, Blobs: blobs} + body, err := json.Marshal(b) + if err != nil { + return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockDeneb value body in SubmitBlindedBlockDeneb") + } + + versionOpt := func(r *http.Request) { + r.Header.Add("Eth-Consensus-Version", version.String(version.Deneb)) + } + rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt) + ep := &ExecPayloadResponseDeneb{} + if err := json.Unmarshal(rb, ep); err != nil { + return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlockDeneb response") + } + if strings.ToLower(ep.Version) != version.String(version.Deneb) { + return nil, nil, errors.New("not a deneb payload") + } + p, blobBundle, err := ep.ToProto() + if err != nil { + return nil, nil, errors.Wrapf(err, "could not extract proto message from payload") + } + payload, err := blocks.WrappedExecutionPayloadDeneb(p, 0) + if err != nil { + return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface") } - return blocks.WrappedExecutionPayloadCapella(p, 0) + return payload, blobBundle, nil default: - return nil, fmt.Errorf("unsupported block version %s", version.String(sb.Version())) + return nil, nil, fmt.Errorf("unsupported block version %s", version.String(sb.Version())) } } diff --git a/api/client/builder/client_test.go b/api/client/builder/client_test.go index 0a4fb62ad49..80ac1262c8d 100644 --- a/api/client/builder/client_test.go +++ b/api/client/builder/client_test.go @@ -12,7 +12,9 @@ import ( "strconv" "testing" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/prysmaticlabs/go-bitfield" + fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" "github.com/prysmaticlabs/prysm/v4/config/params" "github.com/prysmaticlabs/prysm/v4/consensus-types/blocks" types "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" @@ -125,7 +127,6 @@ func TestClient_GetHeader(t *testing.T) { var slot types.Slot = 23 parentHash := ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") pubkey := ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a") - t.Run("server error", func(t *testing.T) { hc := &http.Client{ Transport: roundtrip(func(r *http.Request) (*http.Response, error) { @@ -236,6 +237,52 @@ func TestClient_GetHeader(t *testing.T) { require.DeepEqual(t, bidValue, value.Bytes()) require.DeepEqual(t, big.NewInt(0).SetBytes(bidValue), value.Int) }) + t.Run("deneb", func(t *testing.T) { + hc := &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + require.Equal(t, expectedPath, r.URL.Path) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBufferString(testExampleHeaderResponseDeneb)), + Request: r.Clone(ctx), + }, nil + }), + } + c := &Client{ + hc: hc, + baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"}, + } + h, err := c.GetHeader(ctx, slot, bytesutil.ToBytes32(parentHash), bytesutil.ToBytes48(pubkey)) + require.NoError(t, err) + expectedWithdrawalsRoot := ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + bid, err := h.Message() + require.NoError(t, err) + bidHeader, err := bid.Header() + require.NoError(t, err) + withdrawalsRoot, err := bidHeader.WithdrawalsRoot() + require.NoError(t, err) + require.Equal(t, true, bytes.Equal(expectedWithdrawalsRoot, withdrawalsRoot)) + value, err := stringToUint256("652312848583266388373324160190187140051835877600158453279131187530910662656") + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("%#x", value.SSZBytes()), fmt.Sprintf("%#x", bid.Value())) + bidValue := bytesutil.ReverseByteOrder(bid.Value()) + require.DeepEqual(t, bidValue, value.Bytes()) + require.DeepEqual(t, big.NewInt(0).SetBytes(bidValue), value.Int) + bundle, err := bid.BlindedBlobsBundle() + require.NoError(t, err) + require.Equal(t, len(bundle.BlobRoots) <= fieldparams.MaxBlobsPerBlock && len(bundle.BlobRoots) > 0, true) + for i := range bundle.BlobRoots { + require.Equal(t, len(bundle.BlobRoots[i]) == fieldparams.RootLength, true) + } + require.Equal(t, len(bundle.KzgCommitments) > 0, true) + for i := range bundle.KzgCommitments { + require.Equal(t, len(bundle.KzgCommitments[i]) == 48, true) + } + require.Equal(t, len(bundle.Proofs) > 0, true) + for i := range bundle.Proofs { + require.Equal(t, len(bundle.Proofs[i]) == 48, true) + } + }) t.Run("unsupported version", func(t *testing.T) { hc := &http.Client{ Transport: roundtrip(func(r *http.Request) (*http.Response, error) { @@ -277,7 +324,7 @@ func TestSubmitBlindedBlock(t *testing.T) { } sbbb, err := blocks.NewSignedBeaconBlock(testSignedBlindedBeaconBlockBellatrix(t)) require.NoError(t, err) - ep, err := c.SubmitBlindedBlock(ctx, sbbb) + ep, _, err := c.SubmitBlindedBlock(ctx, sbbb, nil) require.NoError(t, err) require.Equal(t, true, bytes.Equal(ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), ep.ParentHash())) bfpg, err := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") @@ -303,7 +350,37 @@ func TestSubmitBlindedBlock(t *testing.T) { } sbb, err := blocks.NewSignedBeaconBlock(testSignedBlindedBeaconBlockCapella(t)) require.NoError(t, err) - ep, err := c.SubmitBlindedBlock(ctx, sbb) + ep, _, err := c.SubmitBlindedBlock(ctx, sbb, nil) + require.NoError(t, err) + withdrawals, err := ep.Withdrawals() + require.NoError(t, err) + require.Equal(t, 1, len(withdrawals)) + assert.Equal(t, uint64(1), withdrawals[0].Index) + assert.Equal(t, types.ValidatorIndex(1), withdrawals[0].ValidatorIndex) + assert.DeepEqual(t, ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943"), withdrawals[0].Address) + assert.Equal(t, uint64(1), withdrawals[0].Amount) + }) + t.Run("deneb", func(t *testing.T) { + hc := &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path) + require.Equal(t, "deneb", r.Header.Get("Eth-Consensus-Version")) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBufferString(testExampleExecutionPayloadDeneb)), + Request: r.Clone(ctx), + }, nil + }), + } + c := &Client{ + hc: hc, + baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"}, + } + test := testSignedBlindedBeaconBlockAndBlobsDeneb(t) + sbb, err := blocks.NewSignedBeaconBlock(test.Block) + require.NoError(t, err) + + ep, blobBundle, err := c.SubmitBlindedBlock(ctx, sbb, test.Blobs) require.NoError(t, err) withdrawals, err := ep.Withdrawals() require.NoError(t, err) @@ -312,6 +389,10 @@ func TestSubmitBlindedBlock(t *testing.T) { assert.Equal(t, types.ValidatorIndex(1), withdrawals[0].ValidatorIndex) assert.DeepEqual(t, ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943"), withdrawals[0].Address) assert.Equal(t, uint64(1), withdrawals[0].Amount) + require.NotNil(t, blobBundle) + require.Equal(t, hexutil.Encode(blobBundle.Blobs[0]), hexutil.Encode(make([]byte, fieldparams.BlobLength))) + require.Equal(t, hexutil.Encode(blobBundle.KzgCommitments[0]), "0x8dab030c51e16e84be9caab84ee3d0b8bbec1db4a0e4de76439da8424d9b957370a10a78851f97e4b54d2ce1ab0d686f") + require.Equal(t, hexutil.Encode(blobBundle.Proofs[0]), "0xb4021b0de10f743893d4f71e1bf830c019e832958efd6795baf2f83b8699a9eccc5dc99015d8d4d8ec370d0cc333c06a") }) t.Run("mismatched versions, expected bellatrix got capella", func(t *testing.T) { hc := &http.Client{ @@ -330,13 +411,13 @@ func TestSubmitBlindedBlock(t *testing.T) { } sbbb, err := blocks.NewSignedBeaconBlock(testSignedBlindedBeaconBlockBellatrix(t)) require.NoError(t, err) - _, err = c.SubmitBlindedBlock(ctx, sbbb) + _, _, err = c.SubmitBlindedBlock(ctx, sbbb, nil) require.ErrorContains(t, "not a bellatrix payload", err) }) t.Run("not blinded", func(t *testing.T) { sbb, err := blocks.NewSignedBeaconBlock(ð.SignedBeaconBlockBellatrix{Block: ð.BeaconBlockBellatrix{Body: ð.BeaconBlockBodyBellatrix{}}}) require.NoError(t, err) - _, err = (&Client{}).SubmitBlindedBlock(ctx, sbb) + _, _, err = (&Client{}).SubmitBlindedBlock(ctx, sbb, nil) require.ErrorIs(t, err, errNotBlinded) }) } @@ -626,6 +707,168 @@ func testSignedBlindedBeaconBlockCapella(t *testing.T) *eth.SignedBlindedBeaconB } } +func testSignedBlindedBeaconBlockAndBlobsDeneb(t *testing.T) *eth.SignedBlindedBeaconBlockAndBlobsDeneb { + return ð.SignedBlindedBeaconBlockAndBlobsDeneb{ + Block: ð.SignedBlindedBeaconBlockDeneb{ + Block: ð.BlindedBeaconBlockDeneb{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Body: ð.BlindedBeaconBlockBodyDeneb{ + RandaoReveal: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + Eth1Data: ð.Eth1Data{ + DepositRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + DepositCount: 1, + BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Graffiti: ezDecode(t, "0xdeadbeefc0ffee"), + ProposerSlashings: []*eth.ProposerSlashing{ + { + Header_1: ð.SignedBeaconBlockHeader{ + Header: ð.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BodyRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + Header_2: ð.SignedBeaconBlockHeader{ + Header: ð.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BodyRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + }, + AttesterSlashings: []*eth.AttesterSlashing{ + { + Attestation_1: ð.IndexedAttestation{ + AttestingIndices: []uint64{1}, + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + Attestation_2: ð.IndexedAttestation{ + AttestingIndices: []uint64{1}, + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + }, + Attestations: []*eth.Attestation{ + { + AggregationBits: bitfield.Bitlist{0x01}, + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + Deposits: []*eth.Deposit{ + { + Proof: [][]byte{ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2")}, + Data: ð.Deposit_Data{ + PublicKey: ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"), + WithdrawalCredentials: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Amount: 1, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + }, + VoluntaryExits: []*eth.SignedVoluntaryExit{ + { + Exit: ð.VoluntaryExit{ + Epoch: 1, + ValidatorIndex: 1, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + SyncAggregate: ð.SyncAggregate{ + SyncCommitteeSignature: make([]byte, 48), + SyncCommitteeBits: bitfield.Bitvector512{0x01}, + }, + ExecutionPayloadHeader: &v1.ExecutionPayloadHeaderDeneb{ + ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + FeeRecipient: ezDecode(t, "0xabcf8e0d4e9587369b2301d0790347320302cc09"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + ReceiptsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + LogsBloom: ezDecode(t, "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + PrevRandao: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BaseFeePerGas: []byte(strconv.FormatUint(1, 10)), + BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + WithdrawalsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + DataGasUsed: 1, + ExcessDataGas: 1, + }, + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + Blobs: []*eth.SignedBlindedBlobSidecar{ + { + Message: ð.BlindedBlobSidecar{ + BlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Index: 0, + Slot: 1, + BlockParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + ProposerIndex: 1, + BlobRoot: ezDecode(t, "0x24564723180fcb3d994104538d351c8dcbde12d541676bb736cf678018ca4739"), + KzgCommitment: ezDecode(t, "0x8dab030c51e16e84be9caab84ee3d0b8bbec1db4a0e4de76439da8424d9b957370a10a78851f97e4b54d2ce1ab0d686f"), + KzgProof: ezDecode(t, "0xb4021b0de10f743893d4f71e1bf830c019e832958efd6795baf2f83b8699a9eccc5dc99015d8d4d8ec370d0cc333c06a"), + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + } +} + func TestRequestLogger(t *testing.T) { wo := WithObserver(&requestLogger{}) c, err := NewClient("localhost:3500", wo) diff --git a/api/client/builder/testing/BUILD.bazel b/api/client/builder/testing/BUILD.bazel index 81aa66919cd..f6bf7cb5189 100644 --- a/api/client/builder/testing/BUILD.bazel +++ b/api/client/builder/testing/BUILD.bazel @@ -10,6 +10,7 @@ go_library( "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", + "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", ], ) diff --git a/api/client/builder/testing/mock.go b/api/client/builder/testing/mock.go index fad2611a7c1..698a9dd51fb 100644 --- a/api/client/builder/testing/mock.go +++ b/api/client/builder/testing/mock.go @@ -7,6 +7,7 @@ import ( "github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" + v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" ) @@ -40,8 +41,8 @@ func (m MockClient) RegisterValidator(_ context.Context, svr []*ethpb.SignedVali } // SubmitBlindedBlock -- -func (MockClient) SubmitBlindedBlock(_ context.Context, _ interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, error) { - return nil, nil +func (MockClient) SubmitBlindedBlock(_ context.Context, _ interfaces.ReadOnlySignedBeaconBlock, _ []*ethpb.SignedBlindedBlobSidecar) (interfaces.ExecutionData, *v1.BlobsBundle, error) { + return nil, nil, nil } // Status -- diff --git a/api/client/builder/types.go b/api/client/builder/types.go index 4b2a3932958..c2d48a8edd7 100644 --- a/api/client/builder/types.go +++ b/api/client/builder/types.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" + fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" types "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" @@ -1107,6 +1108,295 @@ func (b *BlindedBeaconBlockBodyCapella) MarshalJSON() ([]byte, error) { }) } +// ExecHeaderResponseDeneb is the header response for builder API /eth/v1/builder/header/{slot}/{parent_hash}/{pubkey}. +type ExecHeaderResponseDeneb struct { + Data struct { + Signature hexutil.Bytes `json:"signature"` + Message *BuilderBidDeneb `json:"message"` + } `json:"data"` +} + +// ToProto creates a SignedBuilderBidDeneb Proto from ExecHeaderResponseDeneb. +func (ehr *ExecHeaderResponseDeneb) ToProto() (*eth.SignedBuilderBidDeneb, error) { + bb, err := ehr.Data.Message.ToProto() + if err != nil { + return nil, err + } + return ð.SignedBuilderBidDeneb{ + Message: bb, + Signature: bytesutil.SafeCopyBytes(ehr.Data.Signature), + }, nil +} + +// ToProto creates a BuilderBidDeneb Proto from BuilderBidDeneb. +func (bb *BuilderBidDeneb) ToProto() (*eth.BuilderBidDeneb, error) { + header, err := bb.Header.ToProto() + if err != nil { + return nil, err + } + bundle, err := bb.BlindedBlobsBundle.ToProto() + if err != nil { + return nil, err + } + return ð.BuilderBidDeneb{ + Header: header, + BlindedBlobsBundle: bundle, + Value: bytesutil.SafeCopyBytes(bb.Value.SSZBytes()), + Pubkey: bytesutil.SafeCopyBytes(bb.Pubkey), + }, nil +} + +// BuilderBidDeneb is a field of ExecHeaderResponseDeneb. +type BuilderBidDeneb struct { + Header *ExecutionPayloadHeaderDeneb `json:"header"` + BlindedBlobsBundle *BlindedBlobsBundle `json:"blinded_blobs_bundle"` + Value Uint256 `json:"value"` + Pubkey hexutil.Bytes `json:"pubkey"` +} + +// BlindedBlobsBundle is a field of BuilderBidDeneb and represents the blinded blobs of the associated header. +type BlindedBlobsBundle struct { + KzgCommitments []hexutil.Bytes `json:"commitments"` + Proofs []hexutil.Bytes `json:"proofs"` + BlobRoots []hexutil.Bytes `json:"blob_roots"` +} + +// ToProto creates a BlindedBlobsBundle Proto from BlindedBlobsBundle. +func (r *BlindedBlobsBundle) ToProto() (*v1.BlindedBlobsBundle, error) { + kzg := make([][]byte, len(r.KzgCommitments)) + for i := range kzg { + kzg[i] = bytesutil.SafeCopyBytes(r.KzgCommitments[i]) + } + + proofs := make([][]byte, len(r.Proofs)) + for i := range proofs { + proofs[i] = bytesutil.SafeCopyBytes(r.Proofs[i]) + } + + blobRoots := make([][]byte, len(r.BlobRoots)) + for i := range blobRoots { + blobRoots[i] = bytesutil.SafeCopyBytes(r.BlobRoots[i]) + } + + return &v1.BlindedBlobsBundle{ + KzgCommitments: kzg, + Proofs: proofs, + BlobRoots: blobRoots, + }, nil +} + +// ExecutionPayloadHeaderDeneb a field part of the BuilderBidDeneb. +type ExecutionPayloadHeaderDeneb struct { + ParentHash hexutil.Bytes `json:"parent_hash"` + FeeRecipient hexutil.Bytes `json:"fee_recipient"` + StateRoot hexutil.Bytes `json:"state_root"` + ReceiptsRoot hexutil.Bytes `json:"receipts_root"` + LogsBloom hexutil.Bytes `json:"logs_bloom"` + PrevRandao hexutil.Bytes `json:"prev_randao"` + BlockNumber Uint64String `json:"block_number"` + GasLimit Uint64String `json:"gas_limit"` + GasUsed Uint64String `json:"gas_used"` + Timestamp Uint64String `json:"timestamp"` + ExtraData hexutil.Bytes `json:"extra_data"` + BaseFeePerGas Uint256 `json:"base_fee_per_gas"` + BlockHash hexutil.Bytes `json:"block_hash"` + TransactionsRoot hexutil.Bytes `json:"transactions_root"` + WithdrawalsRoot hexutil.Bytes `json:"withdrawals_root"` + DataGasUsed Uint64String `json:"data_gas_used"` // new in deneb + ExcessDataGas Uint64String `json:"excess_data_gas"` // new in deneb + *v1.ExecutionPayloadHeaderDeneb +} + +// MarshalJSON returns a JSON byte array representing the ExecutionPayloadHeaderDeneb struct. +func (h *ExecutionPayloadHeaderDeneb) MarshalJSON() ([]byte, error) { + type MarshalCaller ExecutionPayloadHeaderDeneb + baseFeePerGas, err := sszBytesToUint256(h.ExecutionPayloadHeaderDeneb.BaseFeePerGas) + if err != nil { + return []byte{}, errors.Wrapf(err, "invalid BaseFeePerGas") + } + return json.Marshal(&MarshalCaller{ + ParentHash: h.ExecutionPayloadHeaderDeneb.ParentHash, + FeeRecipient: h.ExecutionPayloadHeaderDeneb.FeeRecipient, + StateRoot: h.ExecutionPayloadHeaderDeneb.StateRoot, + ReceiptsRoot: h.ExecutionPayloadHeaderDeneb.ReceiptsRoot, + LogsBloom: h.ExecutionPayloadHeaderDeneb.LogsBloom, + PrevRandao: h.ExecutionPayloadHeaderDeneb.PrevRandao, + BlockNumber: Uint64String(h.ExecutionPayloadHeaderDeneb.BlockNumber), + GasLimit: Uint64String(h.ExecutionPayloadHeaderDeneb.GasLimit), + GasUsed: Uint64String(h.ExecutionPayloadHeaderDeneb.GasUsed), + Timestamp: Uint64String(h.ExecutionPayloadHeaderDeneb.Timestamp), + ExtraData: h.ExecutionPayloadHeaderDeneb.ExtraData, + BaseFeePerGas: baseFeePerGas, + BlockHash: h.ExecutionPayloadHeaderDeneb.BlockHash, + TransactionsRoot: h.ExecutionPayloadHeaderDeneb.TransactionsRoot, + WithdrawalsRoot: h.ExecutionPayloadHeaderDeneb.WithdrawalsRoot, + DataGasUsed: Uint64String(h.ExecutionPayloadHeaderDeneb.DataGasUsed), + ExcessDataGas: Uint64String(h.ExecutionPayloadHeaderDeneb.ExcessDataGas), + }) +} + +// UnmarshalJSON takes in a byte array and unmarshals the value into ExecutionPayloadHeaderDeneb. +func (h *ExecutionPayloadHeaderDeneb) UnmarshalJSON(b []byte) error { + type UnmarshalCaller ExecutionPayloadHeaderDeneb + uc := &UnmarshalCaller{} + if err := json.Unmarshal(b, uc); err != nil { + return err + } + ep := ExecutionPayloadHeaderDeneb(*uc) + *h = ep + var err error + h.ExecutionPayloadHeaderDeneb, err = h.ToProto() + return err +} + +// ToProto returns a ExecutionPayloadHeaderDeneb Proto object. +func (h *ExecutionPayloadHeaderDeneb) ToProto() (*v1.ExecutionPayloadHeaderDeneb, error) { + return &v1.ExecutionPayloadHeaderDeneb{ + ParentHash: bytesutil.SafeCopyBytes(h.ParentHash), + FeeRecipient: bytesutil.SafeCopyBytes(h.FeeRecipient), + StateRoot: bytesutil.SafeCopyBytes(h.StateRoot), + ReceiptsRoot: bytesutil.SafeCopyBytes(h.ReceiptsRoot), + LogsBloom: bytesutil.SafeCopyBytes(h.LogsBloom), + PrevRandao: bytesutil.SafeCopyBytes(h.PrevRandao), + BlockNumber: uint64(h.BlockNumber), + GasLimit: uint64(h.GasLimit), + GasUsed: uint64(h.GasUsed), + Timestamp: uint64(h.Timestamp), + ExtraData: bytesutil.SafeCopyBytes(h.ExtraData), + BaseFeePerGas: bytesutil.SafeCopyBytes(h.BaseFeePerGas.SSZBytes()), + BlockHash: bytesutil.SafeCopyBytes(h.BlockHash), + TransactionsRoot: bytesutil.SafeCopyBytes(h.TransactionsRoot), + WithdrawalsRoot: bytesutil.SafeCopyBytes(h.WithdrawalsRoot), + DataGasUsed: uint64(h.DataGasUsed), + ExcessDataGas: uint64(h.ExcessDataGas), + }, nil +} + +// ExecPayloadResponseDeneb the response to the build API /eth/v1/builder/blinded_blocks that includes the version, execution payload object , and blobs bundle object. +type ExecPayloadResponseDeneb struct { + Version string `json:"version"` + Data *ExecutionPayloadDenebAndBlobsBundle `json:"data"` +} + +// ExecutionPayloadDenebAndBlobsBundle the main field used in ExecPayloadResponseDeneb. +type ExecutionPayloadDenebAndBlobsBundle struct { + ExecutionPayload *ExecutionPayloadDeneb `json:"execution_payload"` + BlobsBundle *BlobsBundle `json:"blobs_bundle"` +} + +// ExecutionPayloadDeneb is a field used in ExecutionPayloadDenebAndBlobsBundle. +type ExecutionPayloadDeneb struct { + ParentHash hexutil.Bytes `json:"parent_hash"` + FeeRecipient hexutil.Bytes `json:"fee_recipient"` + StateRoot hexutil.Bytes `json:"state_root"` + ReceiptsRoot hexutil.Bytes `json:"receipts_root"` + LogsBloom hexutil.Bytes `json:"logs_bloom"` + PrevRandao hexutil.Bytes `json:"prev_randao"` + BlockNumber Uint64String `json:"block_number"` + GasLimit Uint64String `json:"gas_limit"` + GasUsed Uint64String `json:"gas_used"` + Timestamp Uint64String `json:"timestamp"` + ExtraData hexutil.Bytes `json:"extra_data"` + BaseFeePerGas Uint256 `json:"base_fee_per_gas"` + BlockHash hexutil.Bytes `json:"block_hash"` + Transactions []hexutil.Bytes `json:"transactions"` + Withdrawals []Withdrawal `json:"withdrawals"` + DataGasUsed Uint64String `json:"data_gas_used"` // new in deneb + ExcessDataGas Uint64String `json:"excess_data_gas"` // new in deneb +} + +// BlobsBundle is a field in ExecutionPayloadDenebAndBlobsBundle. +type BlobsBundle struct { + Commitments []hexutil.Bytes `json:"commitments"` + Proofs []hexutil.Bytes `json:"proofs"` + Blobs []hexutil.Bytes `json:"blobs"` +} + +// ToProto returns a BlobsBundle Proto. +func (b BlobsBundle) ToProto() (*v1.BlobsBundle, error) { + commitments := make([][]byte, len(b.Commitments)) + for i := range b.Commitments { + if len(b.Commitments[i]) != fieldparams.BLSPubkeyLength { + return nil, fmt.Errorf("commitment length %d is not %d", len(b.Commitments[i]), fieldparams.BLSPubkeyLength) + } + commitments[i] = bytesutil.SafeCopyBytes(b.Commitments[i]) + } + proofs := make([][]byte, len(b.Proofs)) + for i := range b.Proofs { + if len(b.Proofs[i]) != fieldparams.BLSPubkeyLength { + return nil, fmt.Errorf("proof length %d is not %d", len(b.Proofs[i]), fieldparams.BLSPubkeyLength) + } + proofs[i] = bytesutil.SafeCopyBytes(b.Proofs[i]) + } + if len(b.Blobs) > fieldparams.MaxBlobsPerBlock { + return nil, fmt.Errorf("blobs length %d is more than max %d", len(b.Blobs), fieldparams.MaxBlobsPerBlock) + } + blobs := make([][]byte, len(b.Blobs)) + for i := range b.Blobs { + if len(b.Blobs[i]) != fieldparams.BlobLength { + return nil, fmt.Errorf("blob length %d is not %d", len(b.Blobs[i]), fieldparams.BlobLength) + } + blobs[i] = bytesutil.SafeCopyBytes(b.Blobs[i]) + } + return &v1.BlobsBundle{ + KzgCommitments: commitments, + Proofs: proofs, + Blobs: blobs, + }, nil +} + +// ToProto returns ExecutionPayloadDeneb Proto and BlobsBundle Proto separately. +func (r *ExecPayloadResponseDeneb) ToProto() (*v1.ExecutionPayloadDeneb, *v1.BlobsBundle, error) { + if r.Data == nil { + return nil, nil, errors.New("data field in response is empty") + } + payload, err := r.Data.ExecutionPayload.ToProto() + if err != nil { + return nil, nil, err + } + bundle, err := r.Data.BlobsBundle.ToProto() + if err != nil { + return nil, nil, err + } + return payload, bundle, nil +} + +// ToProto returns the ExecutionPayloadDeneb Proto. +func (p *ExecutionPayloadDeneb) ToProto() (*v1.ExecutionPayloadDeneb, error) { + txs := make([][]byte, len(p.Transactions)) + for i := range p.Transactions { + txs[i] = bytesutil.SafeCopyBytes(p.Transactions[i]) + } + withdrawals := make([]*v1.Withdrawal, len(p.Withdrawals)) + for i, w := range p.Withdrawals { + withdrawals[i] = &v1.Withdrawal{ + Index: w.Index.Uint64(), + ValidatorIndex: types.ValidatorIndex(w.ValidatorIndex.Uint64()), + Address: bytesutil.SafeCopyBytes(w.Address), + Amount: w.Amount.Uint64(), + } + } + return &v1.ExecutionPayloadDeneb{ + ParentHash: bytesutil.SafeCopyBytes(p.ParentHash), + FeeRecipient: bytesutil.SafeCopyBytes(p.FeeRecipient), + StateRoot: bytesutil.SafeCopyBytes(p.StateRoot), + ReceiptsRoot: bytesutil.SafeCopyBytes(p.ReceiptsRoot), + LogsBloom: bytesutil.SafeCopyBytes(p.LogsBloom), + PrevRandao: bytesutil.SafeCopyBytes(p.PrevRandao), + BlockNumber: uint64(p.BlockNumber), + GasLimit: uint64(p.GasLimit), + GasUsed: uint64(p.GasUsed), + Timestamp: uint64(p.Timestamp), + ExtraData: bytesutil.SafeCopyBytes(p.ExtraData), + BaseFeePerGas: bytesutil.SafeCopyBytes(p.BaseFeePerGas.SSZBytes()), + BlockHash: bytesutil.SafeCopyBytes(p.BlockHash), + Transactions: txs, + Withdrawals: withdrawals, + DataGasUsed: uint64(p.DataGasUsed), + ExcessDataGas: uint64(p.ExcessDataGas), + }, nil +} + // ErrorMessage is a JSON representation of the builder API's returned error message. type ErrorMessage struct { Code int `json:"code"` diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 0d72cf1ee79..4dac14862a1 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/golang/protobuf/proto" "github.com/prysmaticlabs/go-bitfield" + fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" eth "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v4/testing/assert" @@ -116,6 +117,47 @@ var testExampleHeaderResponseCapella = `{ } }` +var testExampleHeaderResponseDeneb = `{ + "version": "deneb", + "data": { + "message": { + "header": { + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "452312848583266388373324160190187140051835877600158453279131187530910662656", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "withdrawals_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "data_gas_used": "1", + "excess_data_gas": "1" + }, + "blinded_blobs_bundle": { + "commitments": [ + "0x8dab030c51e16e84be9caab84ee3d0b8bbec1db4a0e4de76439da8424d9b957370a10a78851f97e4b54d2ce1ab0d686f" + ], + "proofs": [ + "0xb4021b0de10f743893d4f71e1bf830c019e832958efd6795baf2f83b8699a9eccc5dc99015d8d4d8ec370d0cc333c06a" + ], + "blob_roots": [ + "0x24564723180fcb3d994104538d351c8dcbde12d541676bb736cf678018ca4739" + ] + }, + "value": "652312848583266388373324160190187140051835877600158453279131187530910662656", + "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } +}` + var testExampleHeaderResponseUnknownVersion = `{ "version": "bad", "data": { @@ -518,6 +560,51 @@ var testExampleExecutionPayloadCapella = `{ } }` +var testExampleExecutionPayloadDeneb = fmt.Sprintf(`{ + "version": "deneb", + "data": { + "execution_payload":{ + "parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09", + "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "block_number": "1", + "gas_limit": "1", + "gas_used": "1", + "timestamp": "1", + "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "base_fee_per_gas": "452312848583266388373324160190187140051835877600158453279131187530910662656", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions": [ + "0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86" + ], + "withdrawals": [ + { + "index": "1", + "validator_index": "1", + "address": "0xcf8e0d4e9587369b2301d0790347320302cc0943", + "amount": "1" + } + ], + "data_gas_used": "2", + "excess_data_gas": "3" + }, + "blobs_bundle": { + "commitments": [ + "0x8dab030c51e16e84be9caab84ee3d0b8bbec1db4a0e4de76439da8424d9b957370a10a78851f97e4b54d2ce1ab0d686f" + ], + "proofs": [ + "0xb4021b0de10f743893d4f71e1bf830c019e832958efd6795baf2f83b8699a9eccc5dc99015d8d4d8ec370d0cc333c06a" + ], + "blobs": [ + "%s" + ] + } + } +}`, hexutil.Encode(make([]byte, fieldparams.BlobLength))) + func TestExecutionPayloadResponseUnmarshal(t *testing.T) { epr := &ExecPayloadResponse{} require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayload), epr)) @@ -689,6 +776,107 @@ func TestExecutionPayloadResponseCapellaUnmarshal(t *testing.T) { assert.Equal(t, uint64(1), w.Amount.Uint64()) } +func TestExecutionPayloadResponseDenebUnmarshal(t *testing.T) { + epr := &ExecPayloadResponseDeneb{} + require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayloadDeneb), epr)) + cases := []struct { + expected string + actual string + name string + }{ + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: hexutil.Encode(epr.Data.ExecutionPayload.ParentHash), + name: "ExecPayloadResponse.ExecutionPayload.ParentHash", + }, + { + expected: "0xabcf8e0d4e9587369b2301d0790347320302cc09", + actual: hexutil.Encode(epr.Data.ExecutionPayload.FeeRecipient), + name: "ExecPayloadResponse.ExecutionPayload.FeeRecipient", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: hexutil.Encode(epr.Data.ExecutionPayload.StateRoot), + name: "ExecPayloadResponse.ExecutionPayload.StateRoot", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: hexutil.Encode(epr.Data.ExecutionPayload.ReceiptsRoot), + name: "ExecPayloadResponse.ExecutionPayload.ReceiptsRoot", + }, + { + expected: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + actual: hexutil.Encode(epr.Data.ExecutionPayload.LogsBloom), + name: "ExecPayloadResponse.ExecutionPayload.LogsBloom", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: hexutil.Encode(epr.Data.ExecutionPayload.PrevRandao), + name: "ExecPayloadResponse.ExecutionPayload.PrevRandao", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.ExecutionPayload.BlockNumber), + name: "ExecPayloadResponse.ExecutionPayload.BlockNumber", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.ExecutionPayload.GasLimit), + name: "ExecPayloadResponse.ExecutionPayload.GasLimit", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.ExecutionPayload.GasUsed), + name: "ExecPayloadResponse.ExecutionPayload.GasUsed", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.ExecutionPayload.Timestamp), + name: "ExecPayloadResponse.ExecutionPayload.Timestamp", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: hexutil.Encode(epr.Data.ExecutionPayload.ExtraData), + name: "ExecPayloadResponse.ExecutionPayload.ExtraData", + }, + { + expected: "452312848583266388373324160190187140051835877600158453279131187530910662656", + actual: fmt.Sprintf("%d", epr.Data.ExecutionPayload.BaseFeePerGas), + name: "ExecPayloadResponse.ExecutionPayload.BaseFeePerGas", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: hexutil.Encode(epr.Data.ExecutionPayload.BlockHash), + name: "ExecPayloadResponse.ExecutionPayload.BlockHash", + }, + { + expected: "2", + actual: fmt.Sprintf("%d", epr.Data.ExecutionPayload.DataGasUsed), + name: "ExecPayloadResponse.ExecutionPayload.DataGasUsed", + }, + { + expected: "3", + actual: fmt.Sprintf("%d", epr.Data.ExecutionPayload.ExcessDataGas), + name: "ExecPayloadResponse.ExecutionPayload.ExcessDataGas", + }, + } + for _, c := range cases { + require.Equal(t, c.expected, c.actual, fmt.Sprintf("unexpected value for field %s", c.name)) + } + require.Equal(t, 1, len(epr.Data.ExecutionPayload.Transactions)) + txHash := "0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86" + require.Equal(t, txHash, hexutil.Encode(epr.Data.ExecutionPayload.Transactions[0])) + + require.Equal(t, 1, len(epr.Data.ExecutionPayload.Withdrawals)) + w := epr.Data.ExecutionPayload.Withdrawals[0] + assert.Equal(t, uint64(1), w.Index.Uint64()) + assert.Equal(t, uint64(1), w.ValidatorIndex.Uint64()) + assert.DeepEqual(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943", w.Address.String()) + assert.Equal(t, uint64(1), w.Amount.Uint64()) + assert.Equal(t, uint64(2), uint64(epr.Data.ExecutionPayload.DataGasUsed)) + assert.Equal(t, uint64(3), uint64(epr.Data.ExecutionPayload.ExcessDataGas)) +} + func TestExecutionPayloadResponseToProto(t *testing.T) { hr := &ExecPayloadResponse{} require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayload), hr)) @@ -796,6 +984,85 @@ func TestExecutionPayloadResponseCapellaToProto(t *testing.T) { } +func TestExecutionPayloadResponseDenebToProto(t *testing.T) { + hr := &ExecPayloadResponseDeneb{} + require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayloadDeneb), hr)) + p, blobsBundle, err := hr.ToProto() + require.NoError(t, err) + + parentHash, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + feeRecipient, err := hexutil.Decode("0xabcf8e0d4e9587369b2301d0790347320302cc09") + require.NoError(t, err) + stateRoot, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + receiptsRoot, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + logsBloom, err := hexutil.Decode("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + require.NoError(t, err) + prevRandao, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + extraData, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + blockHash, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + + tx, err := hexutil.Decode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86") + require.NoError(t, err) + txList := [][]byte{tx} + address, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943") + require.NoError(t, err) + + bfpg, err := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") + require.NoError(t, err) + expected := &v1.ExecutionPayloadDeneb{ + ParentHash: parentHash, + FeeRecipient: feeRecipient, + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: prevRandao, + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: extraData, + BaseFeePerGas: bfpg.SSZBytes(), + BlockHash: blockHash, + Transactions: txList, + Withdrawals: []*v1.Withdrawal{ + { + Index: 1, + ValidatorIndex: 1, + Address: address, + Amount: 1, + }, + }, + DataGasUsed: 2, + ExcessDataGas: 3, + } + require.DeepEqual(t, expected, p) + commitment, err := hexutil.Decode("0x8dab030c51e16e84be9caab84ee3d0b8bbec1db4a0e4de76439da8424d9b957370a10a78851f97e4b54d2ce1ab0d686f") + require.NoError(t, err) + proof, err := hexutil.Decode("0xb4021b0de10f743893d4f71e1bf830c019e832958efd6795baf2f83b8699a9eccc5dc99015d8d4d8ec370d0cc333c06a") + require.NoError(t, err) + + expectedBlobs := &v1.BlobsBundle{ + KzgCommitments: [][]byte{ + commitment, + }, + Proofs: [][]byte{ + proof, + }, + Blobs: [][]byte{ + make([]byte, fieldparams.BlobLength), + }, + } + + require.DeepEqual(t, blobsBundle, expectedBlobs) + +} + func pbEth1Data() *eth.Eth1Data { return ð.Eth1Data{ DepositRoot: make([]byte, 32), @@ -1026,6 +1293,30 @@ func pbExecutionPayloadHeaderCapella(t *testing.T) *v1.ExecutionPayloadHeaderCap } } +func pbExecutionPayloadHeaderDeneb(t *testing.T) *v1.ExecutionPayloadHeaderDeneb { + bfpg, err := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") + require.NoError(t, err) + return &v1.ExecutionPayloadHeaderDeneb{ + ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + FeeRecipient: ezDecode(t, "0xabcf8e0d4e9587369b2301d0790347320302cc09"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + ReceiptsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + LogsBloom: ezDecode(t, "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + PrevRandao: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BaseFeePerGas: bfpg.SSZBytes(), + BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + WithdrawalsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + DataGasUsed: 1, + ExcessDataGas: 1, + } +} + func TestExecutionPayloadHeader_MarshalJSON(t *testing.T) { h := &ExecutionPayloadHeader{ ExecutionPayloadHeader: pbExecutionPayloadHeader(t), @@ -1046,6 +1337,16 @@ func TestExecutionPayloadHeaderCapella_MarshalJSON(t *testing.T) { require.Equal(t, expected, string(b)) } +func TestExecutionPayloadHeaderDeneb_MarshalJSON(t *testing.T) { + h := &ExecutionPayloadHeaderDeneb{ + ExecutionPayloadHeaderDeneb: pbExecutionPayloadHeaderDeneb(t), + } + b, err := json.Marshal(h) + require.NoError(t, err) + expected := `{"parent_hash":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","fee_recipient":"0xabcf8e0d4e9587369b2301d0790347320302cc09","state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","receipts_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","logs_bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prev_randao":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","block_number":"1","gas_limit":"1","gas_used":"1","timestamp":"1","extra_data":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","base_fee_per_gas":"452312848583266388373324160190187140051835877600158453279131187530910662656","block_hash":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","transactions_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","withdrawals_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","data_gas_used":"1","excess_data_gas":"1"}` + require.Equal(t, expected, string(b)) +} + var testBuilderBid = `{ "version":"bellatrix", "data":{ diff --git a/beacon-chain/builder/BUILD.bazel b/beacon-chain/builder/BUILD.bazel index 3cbffb8300f..0d03f2c5cec 100644 --- a/beacon-chain/builder/BUILD.bazel +++ b/beacon-chain/builder/BUILD.bazel @@ -15,10 +15,12 @@ go_library( "//beacon-chain/cache:go_default_library", "//beacon-chain/db:go_default_library", "//cmd/beacon-chain/flags:go_default_library", + "//config/fieldparams:go_default_library", "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", "//monitoring/tracing:go_default_library", + "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "@com_github_pkg_errors//:go_default_library", "@com_github_prometheus_client_golang//prometheus:go_default_library", diff --git a/beacon-chain/builder/service.go b/beacon-chain/builder/service.go index ce301043b4a..5a2fb7f6192 100644 --- a/beacon-chain/builder/service.go +++ b/beacon-chain/builder/service.go @@ -2,6 +2,7 @@ package builder import ( "context" + "fmt" "reflect" "time" @@ -10,10 +11,12 @@ import ( "github.com/prysmaticlabs/prysm/v4/beacon-chain/blockchain" "github.com/prysmaticlabs/prysm/v4/beacon-chain/cache" "github.com/prysmaticlabs/prysm/v4/beacon-chain/db" + fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" "github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v4/monitoring/tracing" + v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" log "github.com/sirupsen/logrus" "go.opencensus.io/trace" @@ -24,7 +27,7 @@ var ErrNoBuilder = errors.New("builder endpoint not configured") // BlockBuilder defines the interface for interacting with the block builder type BlockBuilder interface { - SubmitBlindedBlock(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, error) + SubmitBlindedBlock(ctx context.Context, block interfaces.ReadOnlySignedBeaconBlock, blobs []*ethpb.SignedBlindedBlobSidecar) (interfaces.ExecutionData, *v1.BlobsBundle, error) GetHeader(ctx context.Context, slot primitives.Slot, parentHash [32]byte, pubKey [48]byte) (builder.SignedBid, error) RegisterValidator(ctx context.Context, reg []*ethpb.SignedValidatorRegistrationV1) error RegistrationByValidatorID(ctx context.Context, id primitives.ValidatorIndex) (*ethpb.ValidatorRegistrationV1, error) @@ -87,7 +90,7 @@ func (s *Service) Stop() error { } // SubmitBlindedBlock submits a blinded block to the builder relay network. -func (s *Service) SubmitBlindedBlock(ctx context.Context, b interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, error) { +func (s *Service) SubmitBlindedBlock(ctx context.Context, b interfaces.ReadOnlySignedBeaconBlock, blobs []*ethpb.SignedBlindedBlobSidecar) (interfaces.ExecutionData, *v1.BlobsBundle, error) { ctx, span := trace.StartSpan(ctx, "builder.SubmitBlindedBlock") defer span.End() start := time.Now() @@ -95,10 +98,13 @@ func (s *Service) SubmitBlindedBlock(ctx context.Context, b interfaces.ReadOnlyS submitBlindedBlockLatency.Observe(float64(time.Since(start).Milliseconds())) }() if s.c == nil { - return nil, ErrNoBuilder + return nil, nil, ErrNoBuilder + } + if uint64(len(blobs)) > fieldparams.MaxBlobsPerBlock { + return nil, nil, fmt.Errorf("blob count %d beyond max limit of %d", len(blobs), fieldparams.MaxBlobsPerBlock) } - return s.c.SubmitBlindedBlock(ctx, b) + return s.c.SubmitBlindedBlock(ctx, b, blobs) } // GetHeader retrieves the header for a given slot and parent hash from the builder relay network. diff --git a/beacon-chain/builder/service_test.go b/beacon-chain/builder/service_test.go index 0c35590550d..b9afc36a6d0 100644 --- a/beacon-chain/builder/service_test.go +++ b/beacon-chain/builder/service_test.go @@ -62,7 +62,7 @@ func Test_BuilderMethodsWithouClient(t *testing.T) { _, err = s.GetHeader(context.Background(), 0, [32]byte{}, [48]byte{}) assert.ErrorContains(t, ErrNoBuilder.Error(), err) - _, err = s.SubmitBlindedBlock(context.Background(), nil) + _, _, err = s.SubmitBlindedBlock(context.Background(), nil, nil) assert.ErrorContains(t, ErrNoBuilder.Error(), err) err = s.RegisterValidator(context.Background(), nil) diff --git a/beacon-chain/builder/testing/mock.go b/beacon-chain/builder/testing/mock.go index f162d7af6d8..61303a6b640 100644 --- a/beacon-chain/builder/testing/mock.go +++ b/beacon-chain/builder/testing/mock.go @@ -26,9 +26,12 @@ type MockBuilderService struct { HasConfigured bool Payload *v1.ExecutionPayload PayloadCapella *v1.ExecutionPayloadCapella + PayloadDeneb *v1.ExecutionPayloadDeneb + BlobBundle *v1.BlobsBundle ErrSubmitBlindedBlock error Bid *ethpb.SignedBuilderBid BidCapella *ethpb.SignedBuilderBidCapella + BidDeneb *ethpb.SignedBuilderBidDeneb RegistrationCache *cache.RegistrationCache ErrGetHeader error ErrRegisterValidator error @@ -41,23 +44,34 @@ func (s *MockBuilderService) Configured() bool { } // SubmitBlindedBlock for mocking. -func (s *MockBuilderService) SubmitBlindedBlock(_ context.Context, _ interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, error) { +func (s *MockBuilderService) SubmitBlindedBlock(_ context.Context, _ interfaces.ReadOnlySignedBeaconBlock, _ []*ethpb.SignedBlindedBlobSidecar) (interfaces.ExecutionData, *v1.BlobsBundle, error) { if s.Payload != nil { w, err := blocks.WrappedExecutionPayload(s.Payload) if err != nil { - return nil, errors.Wrap(err, "could not wrap payload") + return nil, nil, errors.Wrap(err, "could not wrap payload") } - return w, s.ErrSubmitBlindedBlock + return w, nil, s.ErrSubmitBlindedBlock } - w, err := blocks.WrappedExecutionPayloadCapella(s.PayloadCapella, 0) + if s.PayloadCapella != nil { + w, err := blocks.WrappedExecutionPayloadCapella(s.PayloadCapella, 0) + if err != nil { + return nil, nil, errors.Wrap(err, "could not wrap capella payload") + } + return w, nil, s.ErrSubmitBlindedBlock + } + + w, err := blocks.WrappedExecutionPayloadDeneb(s.PayloadDeneb, 0) if err != nil { - return nil, errors.Wrap(err, "could not wrap capella payload") + return nil, nil, errors.Wrap(err, "could not wrap deneb payload") } - return w, s.ErrSubmitBlindedBlock + return w, s.BlobBundle, s.ErrSubmitBlindedBlock } // GetHeader for mocking. func (s *MockBuilderService) GetHeader(_ context.Context, slot primitives.Slot, _ [32]byte, _ [48]byte) (builder.SignedBid, error) { + if slots.ToEpoch(slot) >= params.BeaconConfig().DenebForkEpoch || s.BidDeneb != nil { + return builder.WrappedSignedBuilderBidDeneb(s.BidDeneb) + } if slots.ToEpoch(slot) >= params.BeaconConfig().CapellaForkEpoch || s.BidCapella != nil { return builder.WrappedSignedBuilderBidCapella(s.BidCapella) } diff --git a/beacon-chain/execution/BUILD.bazel b/beacon-chain/execution/BUILD.bazel index 7e81c9753b8..e91895898d0 100644 --- a/beacon-chain/execution/BUILD.bazel +++ b/beacon-chain/execution/BUILD.bazel @@ -48,7 +48,6 @@ go_library( "//crypto/hash:go_default_library", "//encoding/bytesutil:go_default_library", "//io/logs:go_default_library", - "//math:go_default_library", "//monitoring/clientstats:go_default_library", "//monitoring/tracing:go_default_library", "//network:go_default_library", diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 98bbf9619d1..adb986a8169 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -23,7 +23,6 @@ import ( payloadattribute "github.com/prysmaticlabs/prysm/v4/consensus-types/payload-attribute" "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" - "github.com/prysmaticlabs/prysm/v4/math" pb "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" "github.com/prysmaticlabs/prysm/v4/runtime/version" "github.com/prysmaticlabs/prysm/v4/time/slots" @@ -250,8 +249,7 @@ func (s *Service) GetPayload(ctx context.Context, payloadId [8]byte, slot primit if err != nil { return nil, nil, handleRPCError(err) } - v := big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(result.Value)) - ed, err := blocks.WrappedExecutionPayloadDeneb(result.Payload, math.WeiToGwei(v)) + ed, err := blocks.WrappedExecutionPayloadDeneb(result.Payload, blocks.PayloadValueToGwei(result.Value)) if err != nil { return nil, nil, err } @@ -264,8 +262,7 @@ func (s *Service) GetPayload(ctx context.Context, payloadId [8]byte, slot primit if err != nil { return nil, nil, handleRPCError(err) } - v := big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(result.Value)) - ed, err := blocks.WrappedExecutionPayloadCapella(result.Payload, math.WeiToGwei(v)) + ed, err := blocks.WrappedExecutionPayloadCapella(result.Payload, blocks.PayloadValueToGwei(result.Value)) if err != nil { return nil, nil, err } diff --git a/beacon-chain/execution/testing/BUILD.bazel b/beacon-chain/execution/testing/BUILD.bazel index ca7c21152cf..44a9cc8fb20 100644 --- a/beacon-chain/execution/testing/BUILD.bazel +++ b/beacon-chain/execution/testing/BUILD.bazel @@ -23,6 +23,7 @@ go_library( "//consensus-types/payload-attribute:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", + "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//time/slots:go_default_library", diff --git a/beacon-chain/execution/testing/mock_engine_client.go b/beacon-chain/execution/testing/mock_engine_client.go index 9eef2566536..7b7d0fcd4b2 100644 --- a/beacon-chain/execution/testing/mock_engine_client.go +++ b/beacon-chain/execution/testing/mock_engine_client.go @@ -14,6 +14,7 @@ import ( payloadattribute "github.com/prysmaticlabs/prysm/v4/consensus-types/payload-attribute" "github.com/prysmaticlabs/prysm/v4/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" + "github.com/prysmaticlabs/prysm/v4/math" pb "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" "github.com/prysmaticlabs/prysm/v4/time/slots" ) @@ -61,14 +62,14 @@ func (e *EngineClient) ForkchoiceUpdated( // GetPayload -- func (e *EngineClient) GetPayload(_ context.Context, _ [8]byte, s primitives.Slot) (interfaces.ExecutionData, *pb.BlobsBundle, error) { if slots.ToEpoch(s) >= params.BeaconConfig().DenebForkEpoch { - ed, err := blocks.WrappedExecutionPayloadDeneb(e.ExecutionPayloadDeneb, e.BlockValue) + ed, err := blocks.WrappedExecutionPayloadDeneb(e.ExecutionPayloadDeneb, math.Gwei(e.BlockValue)) if err != nil { return nil, nil, err } return ed, e.BlobsBundle, nil } if slots.ToEpoch(s) >= params.BeaconConfig().CapellaForkEpoch { - ed, err := blocks.WrappedExecutionPayloadCapella(e.ExecutionPayloadCapella, e.BlockValue) + ed, err := blocks.WrappedExecutionPayloadCapella(e.ExecutionPayloadCapella, math.Gwei(e.BlockValue)) if err != nil { return nil, nil, err } diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/unblinder.go b/beacon-chain/rpc/prysm/v1alpha1/validator/unblinder.go index fa1a356d025..38c5f40a2f2 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/unblinder.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/unblinder.go @@ -59,8 +59,9 @@ func (u *unblinder) unblindBuilderBlock(ctx context.Context) (interfaces.SignedB if err = sb.SetExecution(h); err != nil { return nil, errors.Wrap(err, "could not set execution") } - - payload, err := u.builder.SubmitBlindedBlock(ctx, sb) + // TODO: replace nil with proper variable for signed blinded blob sidecars + // replace _ with blob bundle and use it in the response. + payload, _, err := u.builder.SubmitBlindedBlock(ctx, sb, nil) if err != nil { return nil, errors.Wrap(err, "could not submit blinded block") } diff --git a/consensus-types/blocks/BUILD.bazel b/consensus-types/blocks/BUILD.bazel index f89aa311150..18e83dda108 100644 --- a/consensus-types/blocks/BUILD.bazel +++ b/consensus-types/blocks/BUILD.bazel @@ -20,6 +20,7 @@ go_library( "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", "//encoding/ssz:go_default_library", + "//math:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1/validator-client:go_default_library", diff --git a/consensus-types/blocks/execution.go b/consensus-types/blocks/execution.go index 44d0c308d90..517fae4deea 100644 --- a/consensus-types/blocks/execution.go +++ b/consensus-types/blocks/execution.go @@ -3,6 +3,7 @@ package blocks import ( "bytes" "errors" + "math/big" fastssz "github.com/prysmaticlabs/fastssz" fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" @@ -10,6 +11,7 @@ import ( "github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v4/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v4/encoding/ssz" + "github.com/prysmaticlabs/prysm/v4/math" enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1" "google.golang.org/protobuf/proto" ) @@ -393,8 +395,8 @@ type executionPayloadCapella struct { } // WrappedExecutionPayloadCapella is a constructor which wraps a protobuf execution payload into an interface. -func WrappedExecutionPayloadCapella(p *enginev1.ExecutionPayloadCapella, value uint64) (interfaces.ExecutionData, error) { - w := executionPayloadCapella{p: p, value: value} +func WrappedExecutionPayloadCapella(p *enginev1.ExecutionPayloadCapella, value math.Gwei) (interfaces.ExecutionData, error) { + w := executionPayloadCapella{p: p, value: uint64(value)} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -565,8 +567,8 @@ type executionPayloadHeaderCapella struct { } // WrappedExecutionPayloadHeaderCapella is a constructor which wraps a protobuf execution header into an interface. -func WrappedExecutionPayloadHeaderCapella(p *enginev1.ExecutionPayloadHeaderCapella, value uint64) (interfaces.ExecutionData, error) { - w := executionPayloadHeaderCapella{p: p, value: value} +func WrappedExecutionPayloadHeaderCapella(p *enginev1.ExecutionPayloadHeaderCapella, value math.Gwei) (interfaces.ExecutionData, error) { + w := executionPayloadHeaderCapella{p: p, value: uint64(value)} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -880,8 +882,8 @@ type executionPayloadHeaderDeneb struct { } // WrappedExecutionPayloadHeaderDeneb is a constructor which wraps a protobuf execution header into an interface. -func WrappedExecutionPayloadHeaderDeneb(p *enginev1.ExecutionPayloadHeaderDeneb, value uint64) (interfaces.ExecutionData, error) { - w := executionPayloadHeaderDeneb{p: p, value: value} +func WrappedExecutionPayloadHeaderDeneb(p *enginev1.ExecutionPayloadHeaderDeneb, value math.Gwei) (interfaces.ExecutionData, error) { + w := executionPayloadHeaderDeneb{p: p, value: uint64(value)} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -1049,8 +1051,8 @@ type executionPayloadDeneb struct { } // WrappedExecutionPayloadDeneb is a constructor which wraps a protobuf execution payload into an interface. -func WrappedExecutionPayloadDeneb(p *enginev1.ExecutionPayloadDeneb, value uint64) (interfaces.ExecutionData, error) { - w := executionPayloadDeneb{p: p, value: value} +func WrappedExecutionPayloadDeneb(p *enginev1.ExecutionPayloadDeneb, value math.Gwei) (interfaces.ExecutionData, error) { + w := executionPayloadDeneb{p: p, value: uint64(value)} if w.IsNil() { return nil, consensus_types.ErrNilObjectWrapped } @@ -1208,3 +1210,10 @@ func (e executionPayloadDeneb) ValueInGwei() (uint64, error) { func (e executionPayloadDeneb) IsBlinded() bool { return false } + +// PayloadValueToGwei returns a Gwei value given the payload's value +func PayloadValueToGwei(value []byte) math.Gwei { + // We have to convert big endian to little endian because the value is coming from the execution layer. + v := big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(value)) + return math.WeiToGwei(v) +} diff --git a/math/math_helper.go b/math/math_helper.go index b4442f56db9..c23d42f6a33 100644 --- a/math/math_helper.go +++ b/math/math_helper.go @@ -213,14 +213,20 @@ func AddInt(i ...int) (int, error) { return sum, nil } +// Wei is the smallest unit of Ether, represented as a pointer to a bigInt. +type Wei *big.Int + +// Gwei is a denomination of 1e9 Wei represented as an uint64. +type Gwei uint64 + // WeiToGwei converts big int wei to uint64 gwei. // The input `v` is copied before being modified. -func WeiToGwei(v *big.Int) uint64 { +func WeiToGwei(v Wei) Gwei { if v == nil { return 0 } gweiPerEth := big.NewInt(1e9) copied := big.NewInt(0).Set(v) copied.Div(copied, gweiPerEth) - return copied.Uint64() + return Gwei(copied.Uint64()) } diff --git a/math/math_helper_test.go b/math/math_helper_test.go index d3b5231fb3e..3da36d0dc15 100644 --- a/math/math_helper_test.go +++ b/math/math_helper_test.go @@ -554,7 +554,7 @@ func TestAddInt(t *testing.T) { func TestWeiToGwei(t *testing.T) { tests := []struct { v *big.Int - want uint64 + want math.Gwei }{ {big.NewInt(1e9 - 1), 0}, {big.NewInt(1e9), 1}, @@ -572,6 +572,6 @@ func TestWeiToGwei_CopyOk(t *testing.T) { v := big.NewInt(1e9) got := math.WeiToGwei(v) - require.Equal(t, uint64(1), got) + require.Equal(t, math.Gwei(1), got) require.Equal(t, big.NewInt(1e9).Uint64(), v.Uint64()) } diff --git a/proto/engine/v1/BUILD.bazel b/proto/engine/v1/BUILD.bazel index dd422442b9f..f5e42a198c2 100644 --- a/proto/engine/v1/BUILD.bazel +++ b/proto/engine/v1/BUILD.bazel @@ -41,6 +41,8 @@ ssz_gen_marshal( "ExecutionPayloadHeaderCapella", "ExecutionPayloadHeaderDeneb", "ExecutionPayloadDeneb", + "BlindedBlobsBundle", + "BlobsBundle", "Withdrawal", ], ) diff --git a/proto/engine/v1/execution_engine.pb.go b/proto/engine/v1/execution_engine.pb.go index 061f564a5a7..26266d0b5f3 100755 --- a/proto/engine/v1/execution_engine.pb.go +++ b/proto/engine/v1/execution_engine.pb.go @@ -1681,6 +1681,69 @@ func (x *BlobsBundle) GetBlobs() [][]byte { return nil } +type BlindedBlobsBundle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KzgCommitments [][]byte `protobuf:"bytes,1,rep,name=kzg_commitments,json=kzgCommitments,proto3" json:"kzg_commitments,omitempty" ssz-max:"4" ssz-size:"?,48"` + Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"4" ssz-size:"?,48"` + BlobRoots [][]byte `protobuf:"bytes,3,rep,name=blob_roots,json=blobRoots,proto3" json:"blob_roots,omitempty" ssz-max:"4" ssz-size:"?,32"` +} + +func (x *BlindedBlobsBundle) Reset() { + *x = BlindedBlobsBundle{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlindedBlobsBundle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlindedBlobsBundle) ProtoMessage() {} + +func (x *BlindedBlobsBundle) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlindedBlobsBundle.ProtoReflect.Descriptor instead. +func (*BlindedBlobsBundle) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16} +} + +func (x *BlindedBlobsBundle) GetKzgCommitments() [][]byte { + if x != nil { + return x.KzgCommitments + } + return nil +} + +func (x *BlindedBlobsBundle) GetProofs() [][]byte { + if x != nil { + return x.Proofs + } + return nil +} + +func (x *BlindedBlobsBundle) GetBlobRoots() [][]byte { + if x != nil { + return x.BlobRoots + } + return nil +} + type Blob struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1692,7 +1755,7 @@ type Blob struct { func (x *Blob) Reset() { *x = Blob{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1705,7 +1768,7 @@ func (x *Blob) String() string { func (*Blob) ProtoMessage() {} func (x *Blob) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1718,7 +1781,7 @@ func (x *Blob) ProtoReflect() protoreflect.Message { // Deprecated: Use Blob.ProtoReflect.Descriptor instead. func (*Blob) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{17} } func (x *Blob) GetData() []byte { @@ -1739,7 +1802,7 @@ type ExchangeCapabilities struct { func (x *ExchangeCapabilities) Reset() { *x = ExchangeCapabilities{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1752,7 +1815,7 @@ func (x *ExchangeCapabilities) String() string { func (*ExchangeCapabilities) ProtoMessage() {} func (x *ExchangeCapabilities) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[17] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1765,7 +1828,7 @@ func (x *ExchangeCapabilities) ProtoReflect() protoreflect.Message { // Deprecated: Use ExchangeCapabilities.ProtoReflect.Descriptor instead. func (*ExchangeCapabilities) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{17} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{18} } func (x *ExchangeCapabilities) GetSupportedMethods() []string { @@ -2145,24 +2208,34 @@ var file_proto_engine_v1_execution_engine_proto_rawDesc = []byte{ 0x18, 0x01, 0x34, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x27, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x11, 0x8a, 0xb5, 0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x01, 0x34, 0x52, 0x05, 0x62, - 0x6c, 0x6f, 0x62, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x1e, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a, 0x8a, 0xb5, 0x18, 0x06, - 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x43, 0x0a, 0x14, - 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, - 0x74, 0x69, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x73, 0x42, 0x96, 0x01, 0x0a, 0x16, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, - 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x14, 0x45, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, - 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x76, 0x31, - 0xaa, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, - 0x5c, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5c, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x6c, 0x6f, 0x62, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x12, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, + 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x36, 0x0a, 0x0f, 0x6b, + 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0d, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, + 0x18, 0x01, 0x34, 0x52, 0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0c, 0x42, 0x0d, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, + 0x01, 0x34, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2c, 0x0a, 0x0a, 0x62, 0x6c, + 0x6f, 0x62, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x0d, + 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x33, 0x32, 0x92, 0xb5, 0x18, 0x01, 0x34, 0x52, 0x09, 0x62, + 0x6c, 0x6f, 0x62, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x42, 0x6c, 0x6f, 0x62, + 0x12, 0x1e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a, + 0x8a, 0xb5, 0x18, 0x06, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x43, 0x0a, 0x14, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x61, 0x70, 0x61, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x10, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x73, 0x42, 0x96, 0x01, 0x0a, 0x16, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x42, 0x14, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, + 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x76, 0x31, 0xaa, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, + 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5c, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2178,7 +2251,7 @@ func file_proto_engine_v1_execution_engine_proto_rawDescGZIP() []byte { } var file_proto_engine_v1_execution_engine_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_proto_engine_v1_execution_engine_proto_goTypes = []interface{}{ (PayloadStatus_Status)(0), // 0: ethereum.engine.v1.PayloadStatus.Status (*ExecutionPayload)(nil), // 1: ethereum.engine.v1.ExecutionPayload @@ -2197,8 +2270,9 @@ var file_proto_engine_v1_execution_engine_proto_goTypes = []interface{}{ (*ForkchoiceState)(nil), // 14: ethereum.engine.v1.ForkchoiceState (*Withdrawal)(nil), // 15: ethereum.engine.v1.Withdrawal (*BlobsBundle)(nil), // 16: ethereum.engine.v1.BlobsBundle - (*Blob)(nil), // 17: ethereum.engine.v1.Blob - (*ExchangeCapabilities)(nil), // 18: ethereum.engine.v1.ExchangeCapabilities + (*BlindedBlobsBundle)(nil), // 17: ethereum.engine.v1.BlindedBlobsBundle + (*Blob)(nil), // 18: ethereum.engine.v1.Blob + (*ExchangeCapabilities)(nil), // 19: ethereum.engine.v1.ExchangeCapabilities } var file_proto_engine_v1_execution_engine_proto_depIdxs = []int32{ 15, // 0: ethereum.engine.v1.ExecutionPayloadBodyV1.withdrawals:type_name -> ethereum.engine.v1.Withdrawal @@ -2415,7 +2489,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { } } file_proto_engine_v1_execution_engine_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Blob); i { + switch v := v.(*BlindedBlobsBundle); i { case 0: return &v.state case 1: @@ -2427,6 +2501,18 @@ func file_proto_engine_v1_execution_engine_proto_init() { } } file_proto_engine_v1_execution_engine_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Blob); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_engine_v1_execution_engine_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ExchangeCapabilities); i { case 0: return &v.state @@ -2445,7 +2531,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_engine_v1_execution_engine_proto_rawDesc, NumEnums: 1, - NumMessages: 18, + NumMessages: 19, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/engine/v1/execution_engine.proto b/proto/engine/v1/execution_engine.proto index 011cc8801a4..59003b31337 100644 --- a/proto/engine/v1/execution_engine.proto +++ b/proto/engine/v1/execution_engine.proto @@ -207,7 +207,7 @@ message Withdrawal { uint64 amount = 4; } -// Blobs bundle is retrieved through engine-api from the execution layer client. +// BlobsBundle is retrieved through engine-api from the execution layer client. // It consists of the necessary components for constructing a blobs sidecar object to gossip through p2p. message BlobsBundle { // The KZG commitments of the blobs. @@ -218,6 +218,16 @@ message BlobsBundle { repeated bytes blobs = 3 [(ethereum.eth.ext.ssz_size) = "?,131072", (ethereum.eth.ext.ssz_max) = "4"]; } +// BlindedBlobsBundle is retrieved through the builder-api from /eth/v1/builder/header/{slot}/{parent_hash}/{pubkey} after the Deneb hardfork. +message BlindedBlobsBundle { + // The KZG commitments of the blobs. + repeated bytes kzg_commitments = 1 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "4"]; + // The proofs of the blobs. + repeated bytes proofs = 2 [(ethereum.eth.ext.ssz_size) = "?,48", (ethereum.eth.ext.ssz_max) = "4"]; + // The blob roots. + repeated bytes blob_roots = 3 [(ethereum.eth.ext.ssz_size) = "?,32", (ethereum.eth.ext.ssz_max) = "4"]; +} + // Blob contains the data that is to be committed on chain. message Blob { // Each blob consists of `BLS_FIELD_ELEMENT`(32) multiplies `FIELD_ELEMENTS_PER_BLOB`(4096) diff --git a/proto/engine/v1/generated.ssz.go b/proto/engine/v1/generated.ssz.go index 9cee99c4996..cabab53c93f 100644 --- a/proto/engine/v1/generated.ssz.go +++ b/proto/engine/v1/generated.ssz.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: b6dd872046b3b8deb04e7771b1c2436ff08459f58cddcdeb46920124a0d639e0 +// Hash: e55708aac3d3cb6d7fa68dafd784f6fa014917a3888e8e46fc9e056dbf0f2672 package enginev1 import ( @@ -2415,3 +2415,495 @@ func (w *Withdrawal) HashTreeRootWith(hh *ssz.Hasher) (err error) { } return } + +// MarshalSSZ ssz marshals the BlobsBundle object +func (b *BlobsBundle) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(b) +} + +// MarshalSSZTo ssz marshals the BlobsBundle object to a target array +func (b *BlobsBundle) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(12) + + // Offset (0) 'KzgCommitments' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.KzgCommitments) * 48 + + // Offset (1) 'Proofs' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.Proofs) * 48 + + // Offset (2) 'Blobs' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.Blobs) * 131072 + + // Field (0) 'KzgCommitments' + if size := len(b.KzgCommitments); size > 4 { + err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4) + return + } + for ii := 0; ii < len(b.KzgCommitments); ii++ { + if size := len(b.KzgCommitments[ii]); size != 48 { + err = ssz.ErrBytesLengthFn("--.KzgCommitments[ii]", size, 48) + return + } + dst = append(dst, b.KzgCommitments[ii]...) + } + + // Field (1) 'Proofs' + if size := len(b.Proofs); size > 4 { + err = ssz.ErrListTooBigFn("--.Proofs", size, 4) + return + } + for ii := 0; ii < len(b.Proofs); ii++ { + if size := len(b.Proofs[ii]); size != 48 { + err = ssz.ErrBytesLengthFn("--.Proofs[ii]", size, 48) + return + } + dst = append(dst, b.Proofs[ii]...) + } + + // Field (2) 'Blobs' + if size := len(b.Blobs); size > 4 { + err = ssz.ErrListTooBigFn("--.Blobs", size, 4) + return + } + for ii := 0; ii < len(b.Blobs); ii++ { + if size := len(b.Blobs[ii]); size != 131072 { + err = ssz.ErrBytesLengthFn("--.Blobs[ii]", size, 131072) + return + } + dst = append(dst, b.Blobs[ii]...) + } + + return +} + +// UnmarshalSSZ ssz unmarshals the BlobsBundle object +func (b *BlobsBundle) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 12 { + return ssz.ErrSize + } + + tail := buf + var o0, o1, o2 uint64 + + // Offset (0) 'KzgCommitments' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 12 { + return ssz.ErrInvalidVariableOffset + } + + // Offset (1) 'Proofs' + if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 { + return ssz.ErrOffset + } + + // Offset (2) 'Blobs' + if o2 = ssz.ReadOffset(buf[8:12]); o2 > size || o1 > o2 { + return ssz.ErrOffset + } + + // Field (0) 'KzgCommitments' + { + buf = tail[o0:o1] + num, err := ssz.DivideInt2(len(buf), 48, 4) + if err != nil { + return err + } + b.KzgCommitments = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(b.KzgCommitments[ii]) == 0 { + b.KzgCommitments[ii] = make([]byte, 0, len(buf[ii*48:(ii+1)*48])) + } + b.KzgCommitments[ii] = append(b.KzgCommitments[ii], buf[ii*48:(ii+1)*48]...) + } + } + + // Field (1) 'Proofs' + { + buf = tail[o1:o2] + num, err := ssz.DivideInt2(len(buf), 48, 4) + if err != nil { + return err + } + b.Proofs = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(b.Proofs[ii]) == 0 { + b.Proofs[ii] = make([]byte, 0, len(buf[ii*48:(ii+1)*48])) + } + b.Proofs[ii] = append(b.Proofs[ii], buf[ii*48:(ii+1)*48]...) + } + } + + // Field (2) 'Blobs' + { + buf = tail[o2:] + num, err := ssz.DivideInt2(len(buf), 131072, 4) + if err != nil { + return err + } + b.Blobs = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(b.Blobs[ii]) == 0 { + b.Blobs[ii] = make([]byte, 0, len(buf[ii*131072:(ii+1)*131072])) + } + b.Blobs[ii] = append(b.Blobs[ii], buf[ii*131072:(ii+1)*131072]...) + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the BlobsBundle object +func (b *BlobsBundle) SizeSSZ() (size int) { + size = 12 + + // Field (0) 'KzgCommitments' + size += len(b.KzgCommitments) * 48 + + // Field (1) 'Proofs' + size += len(b.Proofs) * 48 + + // Field (2) 'Blobs' + size += len(b.Blobs) * 131072 + + return +} + +// HashTreeRoot ssz hashes the BlobsBundle object +func (b *BlobsBundle) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(b) +} + +// HashTreeRootWith ssz hashes the BlobsBundle object with a hasher +func (b *BlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) { + indx := hh.Index() + + // Field (0) 'KzgCommitments' + { + if size := len(b.KzgCommitments); size > 4 { + err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4) + return + } + subIndx := hh.Index() + for _, i := range b.KzgCommitments { + if len(i) != 48 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(i) + } + + numItems := uint64(len(b.KzgCommitments)) + if ssz.EnableVectorizedHTR { + hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4) + } else { + hh.MerkleizeWithMixin(subIndx, numItems, 4) + } + } + + // Field (1) 'Proofs' + { + if size := len(b.Proofs); size > 4 { + err = ssz.ErrListTooBigFn("--.Proofs", size, 4) + return + } + subIndx := hh.Index() + for _, i := range b.Proofs { + if len(i) != 48 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(i) + } + + numItems := uint64(len(b.Proofs)) + if ssz.EnableVectorizedHTR { + hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4) + } else { + hh.MerkleizeWithMixin(subIndx, numItems, 4) + } + } + + // Field (2) 'Blobs' + { + if size := len(b.Blobs); size > 4 { + err = ssz.ErrListTooBigFn("--.Blobs", size, 4) + return + } + subIndx := hh.Index() + for _, i := range b.Blobs { + if len(i) != 131072 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(i) + } + + numItems := uint64(len(b.Blobs)) + if ssz.EnableVectorizedHTR { + hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4) + } else { + hh.MerkleizeWithMixin(subIndx, numItems, 4) + } + } + + if ssz.EnableVectorizedHTR { + hh.MerkleizeVectorizedHTR(indx) + } else { + hh.Merkleize(indx) + } + return +} + +// MarshalSSZ ssz marshals the BlindedBlobsBundle object +func (b *BlindedBlobsBundle) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(b) +} + +// MarshalSSZTo ssz marshals the BlindedBlobsBundle object to a target array +func (b *BlindedBlobsBundle) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(12) + + // Offset (0) 'KzgCommitments' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.KzgCommitments) * 48 + + // Offset (1) 'Proofs' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.Proofs) * 48 + + // Offset (2) 'BlobRoots' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.BlobRoots) * 32 + + // Field (0) 'KzgCommitments' + if size := len(b.KzgCommitments); size > 4 { + err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4) + return + } + for ii := 0; ii < len(b.KzgCommitments); ii++ { + if size := len(b.KzgCommitments[ii]); size != 48 { + err = ssz.ErrBytesLengthFn("--.KzgCommitments[ii]", size, 48) + return + } + dst = append(dst, b.KzgCommitments[ii]...) + } + + // Field (1) 'Proofs' + if size := len(b.Proofs); size > 4 { + err = ssz.ErrListTooBigFn("--.Proofs", size, 4) + return + } + for ii := 0; ii < len(b.Proofs); ii++ { + if size := len(b.Proofs[ii]); size != 48 { + err = ssz.ErrBytesLengthFn("--.Proofs[ii]", size, 48) + return + } + dst = append(dst, b.Proofs[ii]...) + } + + // Field (2) 'BlobRoots' + if size := len(b.BlobRoots); size > 4 { + err = ssz.ErrListTooBigFn("--.BlobRoots", size, 4) + return + } + for ii := 0; ii < len(b.BlobRoots); ii++ { + if size := len(b.BlobRoots[ii]); size != 32 { + err = ssz.ErrBytesLengthFn("--.BlobRoots[ii]", size, 32) + return + } + dst = append(dst, b.BlobRoots[ii]...) + } + + return +} + +// UnmarshalSSZ ssz unmarshals the BlindedBlobsBundle object +func (b *BlindedBlobsBundle) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 12 { + return ssz.ErrSize + } + + tail := buf + var o0, o1, o2 uint64 + + // Offset (0) 'KzgCommitments' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 12 { + return ssz.ErrInvalidVariableOffset + } + + // Offset (1) 'Proofs' + if o1 = ssz.ReadOffset(buf[4:8]); o1 > size || o0 > o1 { + return ssz.ErrOffset + } + + // Offset (2) 'BlobRoots' + if o2 = ssz.ReadOffset(buf[8:12]); o2 > size || o1 > o2 { + return ssz.ErrOffset + } + + // Field (0) 'KzgCommitments' + { + buf = tail[o0:o1] + num, err := ssz.DivideInt2(len(buf), 48, 4) + if err != nil { + return err + } + b.KzgCommitments = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(b.KzgCommitments[ii]) == 0 { + b.KzgCommitments[ii] = make([]byte, 0, len(buf[ii*48:(ii+1)*48])) + } + b.KzgCommitments[ii] = append(b.KzgCommitments[ii], buf[ii*48:(ii+1)*48]...) + } + } + + // Field (1) 'Proofs' + { + buf = tail[o1:o2] + num, err := ssz.DivideInt2(len(buf), 48, 4) + if err != nil { + return err + } + b.Proofs = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(b.Proofs[ii]) == 0 { + b.Proofs[ii] = make([]byte, 0, len(buf[ii*48:(ii+1)*48])) + } + b.Proofs[ii] = append(b.Proofs[ii], buf[ii*48:(ii+1)*48]...) + } + } + + // Field (2) 'BlobRoots' + { + buf = tail[o2:] + num, err := ssz.DivideInt2(len(buf), 32, 4) + if err != nil { + return err + } + b.BlobRoots = make([][]byte, num) + for ii := 0; ii < num; ii++ { + if cap(b.BlobRoots[ii]) == 0 { + b.BlobRoots[ii] = make([]byte, 0, len(buf[ii*32:(ii+1)*32])) + } + b.BlobRoots[ii] = append(b.BlobRoots[ii], buf[ii*32:(ii+1)*32]...) + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the BlindedBlobsBundle object +func (b *BlindedBlobsBundle) SizeSSZ() (size int) { + size = 12 + + // Field (0) 'KzgCommitments' + size += len(b.KzgCommitments) * 48 + + // Field (1) 'Proofs' + size += len(b.Proofs) * 48 + + // Field (2) 'BlobRoots' + size += len(b.BlobRoots) * 32 + + return +} + +// HashTreeRoot ssz hashes the BlindedBlobsBundle object +func (b *BlindedBlobsBundle) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(b) +} + +// HashTreeRootWith ssz hashes the BlindedBlobsBundle object with a hasher +func (b *BlindedBlobsBundle) HashTreeRootWith(hh *ssz.Hasher) (err error) { + indx := hh.Index() + + // Field (0) 'KzgCommitments' + { + if size := len(b.KzgCommitments); size > 4 { + err = ssz.ErrListTooBigFn("--.KzgCommitments", size, 4) + return + } + subIndx := hh.Index() + for _, i := range b.KzgCommitments { + if len(i) != 48 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(i) + } + + numItems := uint64(len(b.KzgCommitments)) + if ssz.EnableVectorizedHTR { + hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4) + } else { + hh.MerkleizeWithMixin(subIndx, numItems, 4) + } + } + + // Field (1) 'Proofs' + { + if size := len(b.Proofs); size > 4 { + err = ssz.ErrListTooBigFn("--.Proofs", size, 4) + return + } + subIndx := hh.Index() + for _, i := range b.Proofs { + if len(i) != 48 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(i) + } + + numItems := uint64(len(b.Proofs)) + if ssz.EnableVectorizedHTR { + hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4) + } else { + hh.MerkleizeWithMixin(subIndx, numItems, 4) + } + } + + // Field (2) 'BlobRoots' + { + if size := len(b.BlobRoots); size > 4 { + err = ssz.ErrListTooBigFn("--.BlobRoots", size, 4) + return + } + subIndx := hh.Index() + for _, i := range b.BlobRoots { + if len(i) != 32 { + err = ssz.ErrBytesLength + return + } + hh.Append(i) + } + + numItems := uint64(len(b.BlobRoots)) + if ssz.EnableVectorizedHTR { + hh.MerkleizeWithMixinVectorizedHTR(subIndx, numItems, 4) + } else { + hh.MerkleizeWithMixin(subIndx, numItems, 4) + } + } + + if ssz.EnableVectorizedHTR { + hh.MerkleizeVectorizedHTR(indx) + } else { + hh.Merkleize(indx) + } + return +} diff --git a/proto/engine/v1/json_marshal_unmarshal.go b/proto/engine/v1/json_marshal_unmarshal.go index 89b23ba304c..d6aa9368710 100644 --- a/proto/engine/v1/json_marshal_unmarshal.go +++ b/proto/engine/v1/json_marshal_unmarshal.go @@ -693,6 +693,14 @@ type BlobBundleJSON struct { Blobs [][]byte `json:"blobs"` } +func (b BlobBundleJSON) ToProto() *BlobsBundle { + return &BlobsBundle{ + KzgCommitments: bytesutil.SafeCopy2dBytes(bytesutil.FromBytes48Array(b.Commitments)), + Proofs: bytesutil.SafeCopy2dBytes(bytesutil.FromBytes48Array(b.Proofs)), + Blobs: bytesutil.SafeCopy2dBytes(b.Blobs), + } +} + // MarshalJSON -- func (e *ExecutionPayloadDeneb) MarshalJSON() ([]byte, error) { transactions := make([]hexutil.Bytes, len(e.Transactions)) @@ -731,11 +739,11 @@ func (e *ExecutionPayloadDeneb) MarshalJSON() ([]byte, error) { Timestamp: &timeStamp, ExtraData: e.ExtraData, BaseFeePerGas: baseFeeHex, - ExcessDataGas: &excessDataGas, - DataGasUsed: &dataGasUsed, BlockHash: &bHash, Transactions: transactions, Withdrawals: e.Withdrawals, + DataGasUsed: &dataGasUsed, + ExcessDataGas: &excessDataGas, }) } diff --git a/proto/engine/v1/json_marshal_unmarshal_test.go b/proto/engine/v1/json_marshal_unmarshal_test.go index f638cfafa58..ea9249c334a 100644 --- a/proto/engine/v1/json_marshal_unmarshal_test.go +++ b/proto/engine/v1/json_marshal_unmarshal_test.go @@ -243,14 +243,14 @@ func TestJsonMarshalUnmarshal(t *testing.T) { BaseFeePerGas: "0x123", BlockHash: &hash, Transactions: []hexutil.Bytes{{}}, - DataGasUsed: &dgu, - ExcessDataGas: &edg, Withdrawals: []*enginev1.Withdrawal{{ Index: 1, ValidatorIndex: 1, Address: bytesutil.PadTo([]byte("address"), 20), Amount: 1, }}, + DataGasUsed: &dgu, + ExcessDataGas: &edg, }, } enc, err := json.Marshal(resp) @@ -267,11 +267,11 @@ func TestJsonMarshalUnmarshal(t *testing.T) { require.DeepEqual(t, uint64(2), pb.Payload.GasLimit) require.DeepEqual(t, uint64(3), pb.Payload.GasUsed) require.DeepEqual(t, uint64(4), pb.Payload.Timestamp) + require.DeepEqual(t, uint64(5), pb.Payload.DataGasUsed) + require.DeepEqual(t, uint64(6), pb.Payload.ExcessDataGas) require.DeepEqual(t, extra.Bytes(), pb.Payload.ExtraData) feePerGas := new(big.Int).SetBytes(pb.Payload.BaseFeePerGas) require.Equal(t, "15832716547479101977395928904157292820330083199902421483727713169783165812736", feePerGas.String()) - require.DeepEqual(t, uint64(5), pb.Payload.DataGasUsed) - require.DeepEqual(t, uint64(6), pb.Payload.ExcessDataGas) require.DeepEqual(t, hash.Bytes(), pb.Payload.BlockHash) require.DeepEqual(t, [][]byte{{}}, pb.Payload.Transactions) require.Equal(t, 1, len(pb.Payload.Withdrawals)) diff --git a/proto/eth/v1/generated.ssz.go b/proto/eth/v1/generated.ssz.go index 8eda8487066..2a2c05d80df 100644 --- a/proto/eth/v1/generated.ssz.go +++ b/proto/eth/v1/generated.ssz.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: 1b85415b8554b026eb2df13a10fe94efa922bae61c9c666935ebe1c75e8d419f +// Hash: 401cdb3ad7380c513dbcec6cecea7854113a0c2d862d35445b2b319aaf3cbecd package v1 import ( diff --git a/proto/eth/v2/generated.ssz.go b/proto/eth/v2/generated.ssz.go index 38679954a9c..df9be56c32b 100644 --- a/proto/eth/v2/generated.ssz.go +++ b/proto/eth/v2/generated.ssz.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: 32f6d66a95401ce0292033b47fd1417101fc5e73b4d4e89610bb8060e0e43bae +// Hash: 53d31a180e6d53a5d13f2c323d24dd544c0a684a457631fe0dcae4428696a70b package eth import ( diff --git a/proto/prysm/v1alpha1/BUILD.bazel b/proto/prysm/v1alpha1/BUILD.bazel index 374dd348f7a..65cb0f14140 100644 --- a/proto/prysm/v1alpha1/BUILD.bazel +++ b/proto/prysm/v1alpha1/BUILD.bazel @@ -129,6 +129,7 @@ ssz_gen_marshal( "SignedBLSToExecutionChange", "BuilderBid", "BuilderBidCapella", + "BuilderBidDeneb", "BlobSidecar", "SignedBlobSidecar", "BlobIdentifier", diff --git a/proto/prysm/v1alpha1/beacon_block.pb.go b/proto/prysm/v1alpha1/beacon_block.pb.go index e3f39f410e0..e2b0a387d58 100755 --- a/proto/prysm/v1alpha1/beacon_block.pb.go +++ b/proto/prysm/v1alpha1/beacon_block.pb.go @@ -3622,6 +3622,132 @@ func (x *SignedBuilderBidCapella) GetSignature() []byte { return nil } +type BuilderBidDeneb struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Header *v1.ExecutionPayloadHeaderDeneb `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty" ssz-size:"32"` + Pubkey []byte `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" ssz-size:"48"` + BlindedBlobsBundle *v1.BlindedBlobsBundle `protobuf:"bytes,4,opt,name=blinded_blobs_bundle,json=blindedBlobsBundle,proto3" json:"blinded_blobs_bundle,omitempty"` +} + +func (x *BuilderBidDeneb) Reset() { + *x = BuilderBidDeneb{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BuilderBidDeneb) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BuilderBidDeneb) ProtoMessage() {} + +func (x *BuilderBidDeneb) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[47] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BuilderBidDeneb.ProtoReflect.Descriptor instead. +func (*BuilderBidDeneb) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_beacon_block_proto_rawDescGZIP(), []int{47} +} + +func (x *BuilderBidDeneb) GetHeader() *v1.ExecutionPayloadHeaderDeneb { + if x != nil { + return x.Header + } + return nil +} + +func (x *BuilderBidDeneb) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *BuilderBidDeneb) GetPubkey() []byte { + if x != nil { + return x.Pubkey + } + return nil +} + +func (x *BuilderBidDeneb) GetBlindedBlobsBundle() *v1.BlindedBlobsBundle { + if x != nil { + return x.BlindedBlobsBundle + } + return nil +} + +type SignedBuilderBidDeneb struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *BuilderBidDeneb `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty" ssz-size:"96"` +} + +func (x *SignedBuilderBidDeneb) Reset() { + *x = SignedBuilderBidDeneb{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignedBuilderBidDeneb) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignedBuilderBidDeneb) ProtoMessage() {} + +func (x *SignedBuilderBidDeneb) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignedBuilderBidDeneb.ProtoReflect.Descriptor instead. +func (*SignedBuilderBidDeneb) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_beacon_block_proto_rawDescGZIP(), []int{48} +} + +func (x *SignedBuilderBidDeneb) GetMessage() *BuilderBidDeneb { + if x != nil { + return x.Message + } + return nil +} + +func (x *SignedBuilderBidDeneb) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + type Deposit_Data struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3636,7 +3762,7 @@ type Deposit_Data struct { func (x *Deposit_Data) Reset() { *x = Deposit_Data{} if protoimpl.UnsafeEnabled { - mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[47] + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3649,7 +3775,7 @@ func (x *Deposit_Data) String() string { func (*Deposit_Data) ProtoMessage() {} func (x *Deposit_Data) ProtoReflect() protoreflect.Message { - mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[47] + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4696,18 +4822,41 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_rawDesc = []byte{ 0x65, 0x72, 0x42, 0x69, 0x64, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, - 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x9b, 0x01, 0x0a, 0x19, - 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, - 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, - 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, - 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, - 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xf2, 0x01, 0x0a, 0x0f, + 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x42, 0x69, 0x64, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x12, + 0x47, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x65, 0x6e, 0x65, 0x62, + 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1e, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x06, + 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x58, 0x0a, 0x14, 0x62, 0x6c, 0x69, 0x6e, 0x64, 0x65, + 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, + 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, + 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x12, 0x62, 0x6c, + 0x69, 0x6e, 0x64, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x22, 0x7f, 0x0a, 0x15, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, + 0x72, 0x42, 0x69, 0x64, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x12, 0x40, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x42, 0x69, 0x64, 0x44, 0x65, 0x6e, + 0x65, 0x62, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, + 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x42, 0x9b, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, + 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, + 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, + 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, + 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4722,7 +4871,7 @@ func file_proto_prysm_v1alpha1_beacon_block_proto_rawDescGZIP() []byte { return file_proto_prysm_v1alpha1_beacon_block_proto_rawDescData } -var file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes = make([]protoimpl.MessageInfo, 48) +var file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes = make([]protoimpl.MessageInfo, 50) var file_proto_prysm_v1alpha1_beacon_block_proto_goTypes = []interface{}{ (*GenericSignedBeaconBlock)(nil), // 0: ethereum.eth.v1alpha1.GenericSignedBeaconBlock (*GenericBeaconBlock)(nil), // 1: ethereum.eth.v1alpha1.GenericBeaconBlock @@ -4771,20 +4920,23 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_goTypes = []interface{}{ (*SignedBuilderBid)(nil), // 44: ethereum.eth.v1alpha1.SignedBuilderBid (*BuilderBidCapella)(nil), // 45: ethereum.eth.v1alpha1.BuilderBidCapella (*SignedBuilderBidCapella)(nil), // 46: ethereum.eth.v1alpha1.SignedBuilderBidCapella - (*Deposit_Data)(nil), // 47: ethereum.eth.v1alpha1.Deposit.Data - (*Attestation)(nil), // 48: ethereum.eth.v1alpha1.Attestation - (*AttestationData)(nil), // 49: ethereum.eth.v1alpha1.AttestationData - (*v1.ExecutionPayload)(nil), // 50: ethereum.engine.v1.ExecutionPayload - (*v1.ExecutionPayloadHeader)(nil), // 51: ethereum.engine.v1.ExecutionPayloadHeader - (*SignedBlobSidecar)(nil), // 52: ethereum.eth.v1alpha1.SignedBlobSidecar - (*BlobSidecar)(nil), // 53: ethereum.eth.v1alpha1.BlobSidecar - (*v1.ExecutionPayloadDeneb)(nil), // 54: ethereum.engine.v1.ExecutionPayloadDeneb - (*SignedBLSToExecutionChange)(nil), // 55: ethereum.eth.v1alpha1.SignedBLSToExecutionChange - (*v1.ExecutionPayloadCapella)(nil), // 56: ethereum.engine.v1.ExecutionPayloadCapella - (*v1.ExecutionPayloadHeaderCapella)(nil), // 57: ethereum.engine.v1.ExecutionPayloadHeaderCapella - (*SignedBlindedBlobSidecar)(nil), // 58: ethereum.eth.v1alpha1.SignedBlindedBlobSidecar - (*BlindedBlobSidecar)(nil), // 59: ethereum.eth.v1alpha1.BlindedBlobSidecar - (*v1.ExecutionPayloadHeaderDeneb)(nil), // 60: ethereum.engine.v1.ExecutionPayloadHeaderDeneb + (*BuilderBidDeneb)(nil), // 47: ethereum.eth.v1alpha1.BuilderBidDeneb + (*SignedBuilderBidDeneb)(nil), // 48: ethereum.eth.v1alpha1.SignedBuilderBidDeneb + (*Deposit_Data)(nil), // 49: ethereum.eth.v1alpha1.Deposit.Data + (*Attestation)(nil), // 50: ethereum.eth.v1alpha1.Attestation + (*AttestationData)(nil), // 51: ethereum.eth.v1alpha1.AttestationData + (*v1.ExecutionPayload)(nil), // 52: ethereum.engine.v1.ExecutionPayload + (*v1.ExecutionPayloadHeader)(nil), // 53: ethereum.engine.v1.ExecutionPayloadHeader + (*SignedBlobSidecar)(nil), // 54: ethereum.eth.v1alpha1.SignedBlobSidecar + (*BlobSidecar)(nil), // 55: ethereum.eth.v1alpha1.BlobSidecar + (*v1.ExecutionPayloadDeneb)(nil), // 56: ethereum.engine.v1.ExecutionPayloadDeneb + (*SignedBLSToExecutionChange)(nil), // 57: ethereum.eth.v1alpha1.SignedBLSToExecutionChange + (*v1.ExecutionPayloadCapella)(nil), // 58: ethereum.engine.v1.ExecutionPayloadCapella + (*v1.ExecutionPayloadHeaderCapella)(nil), // 59: ethereum.engine.v1.ExecutionPayloadHeaderCapella + (*SignedBlindedBlobSidecar)(nil), // 60: ethereum.eth.v1alpha1.SignedBlindedBlobSidecar + (*BlindedBlobSidecar)(nil), // 61: ethereum.eth.v1alpha1.BlindedBlobSidecar + (*v1.ExecutionPayloadHeaderDeneb)(nil), // 62: ethereum.engine.v1.ExecutionPayloadHeaderDeneb + (*v1.BlindedBlobsBundle)(nil), // 63: ethereum.engine.v1.BlindedBlobsBundle } var file_proto_prysm_v1alpha1_beacon_block_proto_depIdxs = []int32{ 3, // 0: ethereum.eth.v1alpha1.GenericSignedBeaconBlock.phase0:type_name -> ethereum.eth.v1alpha1.SignedBeaconBlock @@ -4810,13 +4962,13 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_depIdxs = []int32{ 13, // 20: ethereum.eth.v1alpha1.BeaconBlockBody.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 21: ethereum.eth.v1alpha1.BeaconBlockBody.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 22: ethereum.eth.v1alpha1.BeaconBlockBody.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 48, // 23: ethereum.eth.v1alpha1.BeaconBlockBody.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 50, // 23: ethereum.eth.v1alpha1.BeaconBlockBody.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 24: ethereum.eth.v1alpha1.BeaconBlockBody.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 25: ethereum.eth.v1alpha1.BeaconBlockBody.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 13, // 26: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 27: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 28: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 48, // 29: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 50, // 29: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 30: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 31: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 32: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate @@ -4824,93 +4976,96 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_depIdxs = []int32{ 15, // 34: ethereum.eth.v1alpha1.ProposerSlashing.header_2:type_name -> ethereum.eth.v1alpha1.SignedBeaconBlockHeader 16, // 35: ethereum.eth.v1alpha1.AttesterSlashing.attestation_1:type_name -> ethereum.eth.v1alpha1.IndexedAttestation 16, // 36: ethereum.eth.v1alpha1.AttesterSlashing.attestation_2:type_name -> ethereum.eth.v1alpha1.IndexedAttestation - 47, // 37: ethereum.eth.v1alpha1.Deposit.data:type_name -> ethereum.eth.v1alpha1.Deposit.Data + 49, // 37: ethereum.eth.v1alpha1.Deposit.data:type_name -> ethereum.eth.v1alpha1.Deposit.Data 11, // 38: ethereum.eth.v1alpha1.SignedVoluntaryExit.exit:type_name -> ethereum.eth.v1alpha1.VoluntaryExit 14, // 39: ethereum.eth.v1alpha1.SignedBeaconBlockHeader.header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader - 49, // 40: ethereum.eth.v1alpha1.IndexedAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData + 51, // 40: ethereum.eth.v1alpha1.IndexedAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData 19, // 41: ethereum.eth.v1alpha1.SignedBeaconBlockBellatrix.block:type_name -> ethereum.eth.v1alpha1.BeaconBlockBellatrix 20, // 42: ethereum.eth.v1alpha1.BeaconBlockBellatrix.body:type_name -> ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix 13, // 43: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 44: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 45: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 48, // 46: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 50, // 46: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 47: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 48: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 49: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate - 50, // 50: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.execution_payload:type_name -> ethereum.engine.v1.ExecutionPayload + 52, // 50: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.execution_payload:type_name -> ethereum.engine.v1.ExecutionPayload 22, // 51: ethereum.eth.v1alpha1.SignedBlindedBeaconBlockBellatrix.block:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix 23, // 52: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix.body:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix 13, // 53: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 54: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 55: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 48, // 56: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 50, // 56: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 57: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 58: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 59: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate - 51, // 60: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.execution_payload_header:type_name -> ethereum.engine.v1.ExecutionPayloadHeader + 53, // 60: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.execution_payload_header:type_name -> ethereum.engine.v1.ExecutionPayloadHeader 25, // 61: ethereum.eth.v1alpha1.SignedBeaconBlockAndBlobsDeneb.block:type_name -> ethereum.eth.v1alpha1.SignedBeaconBlockDeneb - 52, // 62: ethereum.eth.v1alpha1.SignedBeaconBlockAndBlobsDeneb.blobs:type_name -> ethereum.eth.v1alpha1.SignedBlobSidecar + 54, // 62: ethereum.eth.v1alpha1.SignedBeaconBlockAndBlobsDeneb.blobs:type_name -> ethereum.eth.v1alpha1.SignedBlobSidecar 27, // 63: ethereum.eth.v1alpha1.SignedBeaconBlockDeneb.block:type_name -> ethereum.eth.v1alpha1.BeaconBlockDeneb 27, // 64: ethereum.eth.v1alpha1.BeaconBlockAndBlobsDeneb.block:type_name -> ethereum.eth.v1alpha1.BeaconBlockDeneb - 53, // 65: ethereum.eth.v1alpha1.BeaconBlockAndBlobsDeneb.blobs:type_name -> ethereum.eth.v1alpha1.BlobSidecar + 55, // 65: ethereum.eth.v1alpha1.BeaconBlockAndBlobsDeneb.blobs:type_name -> ethereum.eth.v1alpha1.BlobSidecar 28, // 66: ethereum.eth.v1alpha1.BeaconBlockDeneb.body:type_name -> ethereum.eth.v1alpha1.BeaconBlockBodyDeneb 13, // 67: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 68: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 69: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 48, // 70: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 50, // 70: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 71: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 72: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 73: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate - 54, // 74: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.execution_payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb - 55, // 75: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange + 56, // 74: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.execution_payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb + 57, // 75: ethereum.eth.v1alpha1.BeaconBlockBodyDeneb.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange 30, // 76: ethereum.eth.v1alpha1.SignedBeaconBlockCapella.block:type_name -> ethereum.eth.v1alpha1.BeaconBlockCapella 31, // 77: ethereum.eth.v1alpha1.BeaconBlockCapella.body:type_name -> ethereum.eth.v1alpha1.BeaconBlockBodyCapella 13, // 78: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 79: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 80: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 48, // 81: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 50, // 81: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 82: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 83: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 84: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate - 56, // 85: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.execution_payload:type_name -> ethereum.engine.v1.ExecutionPayloadCapella - 55, // 86: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange + 58, // 85: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.execution_payload:type_name -> ethereum.engine.v1.ExecutionPayloadCapella + 57, // 86: ethereum.eth.v1alpha1.BeaconBlockBodyCapella.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange 33, // 87: ethereum.eth.v1alpha1.SignedBlindedBeaconBlockCapella.block:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockCapella 34, // 88: ethereum.eth.v1alpha1.BlindedBeaconBlockCapella.body:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella 13, // 89: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 90: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 91: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 48, // 92: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 50, // 92: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 93: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 94: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 95: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate - 57, // 96: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.execution_payload_header:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderCapella - 55, // 97: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange + 59, // 96: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.execution_payload_header:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderCapella + 57, // 97: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyCapella.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange 37, // 98: ethereum.eth.v1alpha1.SignedBlindedBeaconBlockAndBlobsDeneb.block:type_name -> ethereum.eth.v1alpha1.SignedBlindedBeaconBlockDeneb - 58, // 99: ethereum.eth.v1alpha1.SignedBlindedBeaconBlockAndBlobsDeneb.blobs:type_name -> ethereum.eth.v1alpha1.SignedBlindedBlobSidecar + 60, // 99: ethereum.eth.v1alpha1.SignedBlindedBeaconBlockAndBlobsDeneb.blobs:type_name -> ethereum.eth.v1alpha1.SignedBlindedBlobSidecar 38, // 100: ethereum.eth.v1alpha1.BlindedBeaconBlockAndBlobsDeneb.block:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb - 59, // 101: ethereum.eth.v1alpha1.BlindedBeaconBlockAndBlobsDeneb.blobs:type_name -> ethereum.eth.v1alpha1.BlindedBlobSidecar + 61, // 101: ethereum.eth.v1alpha1.BlindedBeaconBlockAndBlobsDeneb.blobs:type_name -> ethereum.eth.v1alpha1.BlindedBlobSidecar 38, // 102: ethereum.eth.v1alpha1.SignedBlindedBeaconBlockDeneb.block:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb 39, // 103: ethereum.eth.v1alpha1.BlindedBeaconBlockDeneb.body:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb 13, // 104: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 105: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 106: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 48, // 107: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 50, // 107: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 108: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 109: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 110: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate - 60, // 111: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.execution_payload_header:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderDeneb - 55, // 112: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange + 62, // 111: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.execution_payload_header:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderDeneb + 57, // 112: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyDeneb.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange 42, // 113: ethereum.eth.v1alpha1.SignedValidatorRegistrationsV1.messages:type_name -> ethereum.eth.v1alpha1.SignedValidatorRegistrationV1 40, // 114: ethereum.eth.v1alpha1.SignedValidatorRegistrationV1.message:type_name -> ethereum.eth.v1alpha1.ValidatorRegistrationV1 - 51, // 115: ethereum.eth.v1alpha1.BuilderBid.header:type_name -> ethereum.engine.v1.ExecutionPayloadHeader + 53, // 115: ethereum.eth.v1alpha1.BuilderBid.header:type_name -> ethereum.engine.v1.ExecutionPayloadHeader 43, // 116: ethereum.eth.v1alpha1.SignedBuilderBid.message:type_name -> ethereum.eth.v1alpha1.BuilderBid - 57, // 117: ethereum.eth.v1alpha1.BuilderBidCapella.header:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderCapella + 59, // 117: ethereum.eth.v1alpha1.BuilderBidCapella.header:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderCapella 45, // 118: ethereum.eth.v1alpha1.SignedBuilderBidCapella.message:type_name -> ethereum.eth.v1alpha1.BuilderBidCapella - 119, // [119:119] is the sub-list for method output_type - 119, // [119:119] is the sub-list for method input_type - 119, // [119:119] is the sub-list for extension type_name - 119, // [119:119] is the sub-list for extension extendee - 0, // [0:119] is the sub-list for field type_name + 62, // 119: ethereum.eth.v1alpha1.BuilderBidDeneb.header:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderDeneb + 63, // 120: ethereum.eth.v1alpha1.BuilderBidDeneb.blinded_blobs_bundle:type_name -> ethereum.engine.v1.BlindedBlobsBundle + 47, // 121: ethereum.eth.v1alpha1.SignedBuilderBidDeneb.message:type_name -> ethereum.eth.v1alpha1.BuilderBidDeneb + 122, // [122:122] is the sub-list for method output_type + 122, // [122:122] is the sub-list for method input_type + 122, // [122:122] is the sub-list for extension type_name + 122, // [122:122] is the sub-list for extension extendee + 0, // [0:122] is the sub-list for field type_name } func init() { file_proto_prysm_v1alpha1_beacon_block_proto_init() } @@ -5487,6 +5642,30 @@ func file_proto_prysm_v1alpha1_beacon_block_proto_init() { } } file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BuilderBidDeneb); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignedBuilderBidDeneb); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Deposit_Data); i { case 0: return &v.state @@ -5525,7 +5704,7 @@ func file_proto_prysm_v1alpha1_beacon_block_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_prysm_v1alpha1_beacon_block_proto_rawDesc, NumEnums: 0, - NumMessages: 48, + NumMessages: 50, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/prysm/v1alpha1/beacon_block.proto b/proto/prysm/v1alpha1/beacon_block.proto index 264b16edde8..df5057d7d67 100644 --- a/proto/prysm/v1alpha1/beacon_block.proto +++ b/proto/prysm/v1alpha1/beacon_block.proto @@ -761,3 +761,15 @@ message SignedBuilderBidCapella { bytes signature = 2 [(ethereum.eth.ext.ssz_size) = "96"]; } +message BuilderBidDeneb { + ethereum.engine.v1.ExecutionPayloadHeaderDeneb header = 1; + bytes value = 2 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes pubkey = 3 [(ethereum.eth.ext.ssz_size) = "48"]; + ethereum.engine.v1.BlindedBlobsBundle blinded_blobs_bundle = 4; // new in deneb +} + +message SignedBuilderBidDeneb { + BuilderBidDeneb message = 1 ; + bytes signature = 2 [(ethereum.eth.ext.ssz_size) = "96"]; +} + diff --git a/proto/prysm/v1alpha1/generated.ssz.go b/proto/prysm/v1alpha1/generated.ssz.go index 491a1e8cfe7..d2061366474 100644 --- a/proto/prysm/v1alpha1/generated.ssz.go +++ b/proto/prysm/v1alpha1/generated.ssz.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: 2ae3aad86b787c66c08ffd704552e17c80b2527f332ad0bef791a7e0d81cf9a7 +// Hash: 8b5590d4a7e7101774ac858fb074719953db492e41b163d46e3793ab22ef2020 package eth import ( @@ -8554,6 +8554,178 @@ func (b *BuilderBidCapella) HashTreeRootWith(hh *ssz.Hasher) (err error) { return } +// MarshalSSZ ssz marshals the BuilderBidDeneb object +func (b *BuilderBidDeneb) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(b) +} + +// MarshalSSZTo ssz marshals the BuilderBidDeneb object to a target array +func (b *BuilderBidDeneb) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(88) + + // Offset (0) 'Header' + dst = ssz.WriteOffset(dst, offset) + if b.Header == nil { + b.Header = new(v1.ExecutionPayloadHeaderDeneb) + } + offset += b.Header.SizeSSZ() + + // Field (1) 'Value' + if size := len(b.Value); size != 32 { + err = ssz.ErrBytesLengthFn("--.Value", size, 32) + return + } + dst = append(dst, b.Value...) + + // Field (2) 'Pubkey' + if size := len(b.Pubkey); size != 48 { + err = ssz.ErrBytesLengthFn("--.Pubkey", size, 48) + return + } + dst = append(dst, b.Pubkey...) + + // Offset (3) 'BlindedBlobsBundle' + dst = ssz.WriteOffset(dst, offset) + if b.BlindedBlobsBundle == nil { + b.BlindedBlobsBundle = new(v1.BlindedBlobsBundle) + } + offset += b.BlindedBlobsBundle.SizeSSZ() + + // Field (0) 'Header' + if dst, err = b.Header.MarshalSSZTo(dst); err != nil { + return + } + + // Field (3) 'BlindedBlobsBundle' + if dst, err = b.BlindedBlobsBundle.MarshalSSZTo(dst); err != nil { + return + } + + return +} + +// UnmarshalSSZ ssz unmarshals the BuilderBidDeneb object +func (b *BuilderBidDeneb) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 88 { + return ssz.ErrSize + } + + tail := buf + var o0, o3 uint64 + + // Offset (0) 'Header' + if o0 = ssz.ReadOffset(buf[0:4]); o0 > size { + return ssz.ErrOffset + } + + if o0 < 88 { + return ssz.ErrInvalidVariableOffset + } + + // Field (1) 'Value' + if cap(b.Value) == 0 { + b.Value = make([]byte, 0, len(buf[4:36])) + } + b.Value = append(b.Value, buf[4:36]...) + + // Field (2) 'Pubkey' + if cap(b.Pubkey) == 0 { + b.Pubkey = make([]byte, 0, len(buf[36:84])) + } + b.Pubkey = append(b.Pubkey, buf[36:84]...) + + // Offset (3) 'BlindedBlobsBundle' + if o3 = ssz.ReadOffset(buf[84:88]); o3 > size || o0 > o3 { + return ssz.ErrOffset + } + + // Field (0) 'Header' + { + buf = tail[o0:o3] + if b.Header == nil { + b.Header = new(v1.ExecutionPayloadHeaderDeneb) + } + if err = b.Header.UnmarshalSSZ(buf); err != nil { + return err + } + } + + // Field (3) 'BlindedBlobsBundle' + { + buf = tail[o3:] + if b.BlindedBlobsBundle == nil { + b.BlindedBlobsBundle = new(v1.BlindedBlobsBundle) + } + if err = b.BlindedBlobsBundle.UnmarshalSSZ(buf); err != nil { + return err + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the BuilderBidDeneb object +func (b *BuilderBidDeneb) SizeSSZ() (size int) { + size = 88 + + // Field (0) 'Header' + if b.Header == nil { + b.Header = new(v1.ExecutionPayloadHeaderDeneb) + } + size += b.Header.SizeSSZ() + + // Field (3) 'BlindedBlobsBundle' + if b.BlindedBlobsBundle == nil { + b.BlindedBlobsBundle = new(v1.BlindedBlobsBundle) + } + size += b.BlindedBlobsBundle.SizeSSZ() + + return +} + +// HashTreeRoot ssz hashes the BuilderBidDeneb object +func (b *BuilderBidDeneb) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(b) +} + +// HashTreeRootWith ssz hashes the BuilderBidDeneb object with a hasher +func (b *BuilderBidDeneb) HashTreeRootWith(hh *ssz.Hasher) (err error) { + indx := hh.Index() + + // Field (0) 'Header' + if err = b.Header.HashTreeRootWith(hh); err != nil { + return + } + + // Field (1) 'Value' + if size := len(b.Value); size != 32 { + err = ssz.ErrBytesLengthFn("--.Value", size, 32) + return + } + hh.PutBytes(b.Value) + + // Field (2) 'Pubkey' + if size := len(b.Pubkey); size != 48 { + err = ssz.ErrBytesLengthFn("--.Pubkey", size, 48) + return + } + hh.PutBytes(b.Pubkey) + + // Field (3) 'BlindedBlobsBundle' + if err = b.BlindedBlobsBundle.HashTreeRootWith(hh); err != nil { + return + } + + if ssz.EnableVectorizedHTR { + hh.MerkleizeVectorizedHTR(indx) + } else { + hh.Merkleize(indx) + } + return +} + // MarshalSSZ ssz marshals the Deposit_Data object func (d *Deposit_Data) MarshalSSZ() ([]byte, error) { return ssz.MarshalSSZ(d) diff --git a/testing/middleware/builder/builder.go b/testing/middleware/builder/builder.go index fe1ad19466a..21b5d8e09f7 100644 --- a/testing/middleware/builder/builder.go +++ b/testing/middleware/builder/builder.go @@ -276,7 +276,7 @@ func (p *Builder) handleHeaderRequest(w http.ResponseWriter, req *http.Request) ax := types.Slot(slot) currEpoch := types.Epoch(ax / params.BeaconConfig().SlotsPerEpoch) if currEpoch >= params.BeaconConfig().CapellaForkEpoch { - p.handleHeadeRequestCapella(w) + p.handleHeaderRequestCapella(w) return } @@ -354,7 +354,7 @@ func (p *Builder) handleHeaderRequest(w http.ResponseWriter, req *http.Request) w.WriteHeader(http.StatusOK) } -func (p *Builder) handleHeadeRequestCapella(w http.ResponseWriter) { +func (p *Builder) handleHeaderRequestCapella(w http.ResponseWriter) { b, err := p.retrievePendingBlockCapella() if err != nil { p.cfg.logger.WithError(err).Error("Could not retrieve pending block") @@ -369,9 +369,11 @@ func (p *Builder) handleHeadeRequestCapella(w http.ResponseWriter) { return } v := big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(b.Value)) + // we set the payload value as twice its actual one so that it always chooses builder payloads vs local payloads v = v.Mul(v, big.NewInt(2)) // Is used as the helper modifies the big.Int weiVal := big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(b.Value)) + // we set the payload value as twice its actual one so that it always chooses builder payloads vs local payloads weiVal = weiVal.Mul(weiVal, big.NewInt(2)) wObj, err := blocks.WrappedExecutionPayloadCapella(b.Payload, math.WeiToGwei(weiVal)) if err != nil { diff --git a/testing/util/BUILD.bazel b/testing/util/BUILD.bazel index 7fa3617924e..553926ffc76 100644 --- a/testing/util/BUILD.bazel +++ b/testing/util/BUILD.bazel @@ -9,6 +9,7 @@ go_library( "bazel.go", "bellatrix.go", "bellatrix_state.go", + "blob.go", "block.go", "capella_block.go", "capella_state.go", diff --git a/testing/util/blob.go b/testing/util/blob.go new file mode 100644 index 00000000000..291aa25403d --- /dev/null +++ b/testing/util/blob.go @@ -0,0 +1,37 @@ +package util + +import ( + fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" + ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1" +) + +// HydrateSignedBlindedBlobSidecar hydrates a signed blinded blob sidecar with correct field length sizes +// to comply with SSZ marshalling and unmarshalling rules. +func HydrateSignedBlindedBlobSidecar(b *ethpb.SignedBlindedBlobSidecar) *ethpb.SignedBlindedBlobSidecar { + if b.Signature == nil { + b.Signature = make([]byte, fieldparams.BLSSignatureLength) + } + b.Message = HydrateBlindedBlobSidecar(b.Message) + return b +} + +// HydrateBlindedBlobSidecar hydrates a blinded blob sidecar with correct field length sizes +// to comply with SSZ marshalling and unmarshalling rules. +func HydrateBlindedBlobSidecar(b *ethpb.BlindedBlobSidecar) *ethpb.BlindedBlobSidecar { + if b.BlockRoot == nil { + b.BlockRoot = make([]byte, fieldparams.RootLength) + } + if b.BlockParentRoot == nil { + b.BlockParentRoot = make([]byte, fieldparams.RootLength) + } + if b.KzgCommitment == nil { + b.KzgCommitment = make([]byte, fieldparams.BLSPubkeyLength) + } + if b.KzgProof == nil { + b.KzgProof = make([]byte, fieldparams.BLSPubkeyLength) + } + if b.BlobRoot == nil { + b.BlobRoot = make([]byte, fieldparams.RootLength) + } + return b +} diff --git a/testing/util/merge.go b/testing/util/merge.go index 491ea5f6f84..2e83a44df3a 100644 --- a/testing/util/merge.go +++ b/testing/util/merge.go @@ -43,6 +43,11 @@ func NewBlindedBeaconBlockDeneb() *ethpb.SignedBlindedBeaconBlockDeneb { return HydrateSignedBlindedBeaconBlockDeneb(ðpb.SignedBlindedBeaconBlockDeneb{}) } +// NewBlindedBlobSidecar creates a signed blinded blob sidecar with minimum marshalable fields. +func NewBlindedBlobSidecar() *ethpb.SignedBlindedBlobSidecar { + return HydrateSignedBlindedBlobSidecar(ðpb.SignedBlindedBlobSidecar{}) +} + // NewBlindedBeaconBlockCapellaV2 creates a blinded beacon block with minimum marshalable fields. func NewBlindedBeaconBlockCapellaV2() *v2.SignedBlindedBeaconBlockCapella { return HydrateV2SignedBlindedBeaconBlockCapella(&v2.SignedBlindedBeaconBlockCapella{})