From 4cd1f9d446c72ff526389e397c47ca83fbf47ca5 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Fri, 11 Apr 2025 20:02:16 -0700 Subject: [PATCH 1/3] Execution api: add and use blobs_bundle_v2 --- beacon-chain/execution/BUILD.bazel | 1 + beacon-chain/execution/engine_client.go | 2 +- beacon-chain/execution/engine_client_test.go | 68 +++++++- .../validator/construct_generic_block.go | 30 +++- .../validator/construct_generic_block_test.go | 9 +- .../rpc/prysm/v1alpha1/validator/proposer.go | 4 +- .../v1alpha1/validator/proposer_bellatrix.go | 4 +- consensus-types/blocks/execution.go | 2 + consensus-types/blocks/get_payload.go | 10 +- proto/engine/v1/BUILD.bazel | 1 + proto/engine/v1/blobs_bundle.go | 7 + proto/engine/v1/electra.pb.go | 135 +++++++++++++-- proto/engine/v1/electra.proto | 8 + proto/engine/v1/execution_engine.pb.go | 162 ++++++++++++++---- proto/engine/v1/execution_engine.proto | 20 ++- 15 files changed, 388 insertions(+), 75 deletions(-) create mode 100644 proto/engine/v1/blobs_bundle.go diff --git a/beacon-chain/execution/BUILD.bazel b/beacon-chain/execution/BUILD.bazel index 59cf1505d503..b4381a0f75bb 100644 --- a/beacon-chain/execution/BUILD.bazel +++ b/beacon-chain/execution/BUILD.bazel @@ -146,5 +146,6 @@ go_test( "@com_github_prometheus_client_golang//prometheus:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", "@com_github_sirupsen_logrus//hooks/test:go_default_library", + "@org_golang_google_protobuf//encoding/protojson:go_default_library", ], ) diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 1dd410a4726d..6d4984e273a6 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -275,7 +275,7 @@ func (s *Service) ForkchoiceUpdated( func getPayloadMethodAndMessage(slot primitives.Slot) (string, proto.Message) { pe := slots.ToEpoch(slot) if pe >= params.BeaconConfig().FuluForkEpoch { - return GetPayloadMethodV5, &pb.ExecutionBundleElectra{} + return GetPayloadMethodV5, &pb.ExecutionBundleFulu{} } if pe >= params.BeaconConfig().ElectraForkEpoch { return GetPayloadMethodV4, &pb.ExecutionBundleElectra{} diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index 2818cfa9e1a8..d78ef151e167 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -38,6 +38,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/testing/util" "github.com/prysmaticlabs/prysm/v5/time/slots" logTest "github.com/sirupsen/logrus/hooks/test" + "google.golang.org/protobuf/encoding/protojson" ) var ( @@ -168,6 +169,7 @@ func TestClient_HTTP(t *testing.T) { cfg.CapellaForkEpoch = 1 cfg.DenebForkEpoch = 2 cfg.ElectraForkEpoch = 3 + cfg.FuluForkEpoch = 4 params.OverrideBeaconConfig(cfg) t.Run(GetPayloadMethod, func(t *testing.T) { @@ -406,7 +408,48 @@ func TestClient_HTTP(t *testing.T) { require.DeepEqual(t, requests, resp.ExecutionRequests) }) + t.Run(GetPayloadMethodV5, func(t *testing.T) { + payloadId := [8]byte{1} + want, ok := fix["ExecutionBundleFulu"].(*pb.ExecutionBundleFulu) + require.Equal(t, true, ok) + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + defer func() { + require.NoError(t, r.Body.Close()) + }() + // Read and verify request + enc, err := io.ReadAll(r.Body) + require.NoError(t, err) + jsonRequestString := string(enc) + reqArg, err := json.Marshal(pb.PayloadIDBytes(payloadId)) + require.NoError(t, err) + require.Equal(t, strings.Contains(jsonRequestString, string(reqArg)), true) + + // Use protojson to marshal the result correctly + marshaled, err := protojson.Marshal(want) + require.NoError(t, err) + + response := `{"jsonrpc":"2.0","id":1,"result":` + string(marshaled) + `}` + _, err = w.Write([]byte(response)) + require.NoError(t, err) + })) + defer srv.Close() + rpcClient, err := rpc.DialHTTP(srv.URL) + require.NoError(t, err) + defer rpcClient.Close() + + client := &Service{rpcClient: rpcClient} + resp, err := client.GetPayload(ctx, payloadId, 4*params.BeaconConfig().SlotsPerEpoch) + require.NoError(t, err) + + _, ok = resp.BlobsBundle.(*pb.BlobsBundleV2) + if !ok { + t.Logf("resp.BlobsBundle has unexpected type: %T", resp.BlobsBundle) + } + require.Equal(t, true, ok) + }) t.Run(ForkchoiceUpdatedMethod+" VALID status", func(t *testing.T) { forkChoiceState := &pb.ForkchoiceState{ HeadBlockHash: []byte("head"), @@ -1540,6 +1583,7 @@ func fixtures() map[string]interface{} { "ExecutionPayloadCapellaWithValue": s.ExecutionPayloadWithValueCapella, "ExecutionPayloadDenebWithValue": s.ExecutionPayloadWithValueDeneb, "ExecutionBundleElectra": s.ExecutionBundleElectra, + "ExecutionBundleFulu": s.ExecutionBundleFulu, "ValidPayloadStatus": s.ValidPayloadStatus, "InvalidBlockHashStatus": s.InvalidBlockHashStatus, "AcceptedStatus": s.AcceptedStatus, @@ -1860,15 +1904,20 @@ func fixturesStruct() *payloadFixtures { LatestValidHash: foo[:], } return &payloadFixtures{ - ExecutionBlock: executionBlock, - ExecutionPayloadBody: executionPayloadBodyFixture, - ExecutionPayload: executionPayloadFixture, - ExecutionPayloadCapella: executionPayloadFixtureCapella, - ExecutionPayloadDeneb: executionPayloadFixtureDeneb, - EmptyExecutionPayloadDeneb: emptyExecutionPayloadDeneb, - ExecutionPayloadWithValueCapella: executionPayloadWithValueFixtureCapella, - ExecutionPayloadWithValueDeneb: executionPayloadWithValueFixtureDeneb, - ExecutionBundleElectra: executionBundleFixtureElectra, + ExecutionBlock: executionBlock, + ExecutionPayloadBody: executionPayloadBodyFixture, + ExecutionPayload: executionPayloadFixture, + ExecutionPayloadCapella: executionPayloadFixtureCapella, + ExecutionPayloadDeneb: executionPayloadFixtureDeneb, + EmptyExecutionPayloadDeneb: emptyExecutionPayloadDeneb, + ExecutionPayloadWithValueCapella: executionPayloadWithValueFixtureCapella, + ExecutionPayloadWithValueDeneb: executionPayloadWithValueFixtureDeneb, + ExecutionBundleElectra: executionBundleFixtureElectra, + ExecutionBundleFulu: &pb.ExecutionBundleFulu{ + Payload: &pb.ExecutionPayloadDeneb{}, + BlobsBundle: &pb.BlobsBundleV2{}, + ExecutionRequests: [][]byte{}, + }, ValidPayloadStatus: validStatus, InvalidBlockHashStatus: inValidBlockHashStatus, AcceptedStatus: acceptedStatus, @@ -1893,6 +1942,7 @@ type payloadFixtures struct { ExecutionPayloadWithValueCapella *pb.GetPayloadV2ResponseJson ExecutionPayloadWithValueDeneb *pb.GetPayloadV3ResponseJson ExecutionBundleElectra *pb.GetPayloadV4ResponseJson + ExecutionBundleFulu *pb.ExecutionBundleFulu ValidPayloadStatus *pb.PayloadStatus InvalidBlockHashStatus *pb.PayloadStatus AcceptedStatus *pb.PayloadStatus diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go b/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go index e9745103daeb..947c891c5a81 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go @@ -3,6 +3,7 @@ package validator import ( "fmt" + "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" @@ -12,9 +13,13 @@ import ( ) // constructGenericBeaconBlock constructs a `GenericBeaconBlock` based on the block version and other parameters. -func (vs *Server) constructGenericBeaconBlock(sBlk interfaces.SignedBeaconBlock, blobsBundle *enginev1.BlobsBundle, winningBid primitives.Wei) (*ethpb.GenericBeaconBlock, error) { +func (vs *Server) constructGenericBeaconBlock( + sBlk interfaces.SignedBeaconBlock, + blobsBundle enginev1.BlobsBundler, + winningBid primitives.Wei, +) (*ethpb.GenericBeaconBlock, error) { if sBlk == nil || sBlk.Block() == nil { - return nil, fmt.Errorf("block cannot be nil") + return nil, errors.New("block cannot be nil") } blockProto, err := sBlk.Block().Proto() @@ -34,12 +39,21 @@ func (vs *Server) constructGenericBeaconBlock(sBlk interfaces.SignedBeaconBlock, return vs.constructBellatrixBlock(blockProto, isBlinded, bidStr), nil case version.Capella: return vs.constructCapellaBlock(blockProto, isBlinded, bidStr), nil - case version.Deneb: - return vs.constructDenebBlock(blockProto, isBlinded, bidStr, blobsBundle), nil - case version.Electra: - return vs.constructElectraBlock(blockProto, isBlinded, bidStr, blobsBundle), nil + case version.Deneb, version.Electra: + bundle, ok := blobsBundle.(*enginev1.BlobsBundle) + if blobsBundle != nil && !ok { + return nil, fmt.Errorf("expected *BlobsBundle, got %T", blobsBundle) + } + if sBlk.Version() == version.Deneb { + return vs.constructDenebBlock(blockProto, isBlinded, bidStr, bundle), nil + } + return vs.constructElectraBlock(blockProto, isBlinded, bidStr, bundle), nil case version.Fulu: - return vs.constructFuluBlock(blockProto, isBlinded, bidStr, blobsBundle), nil + bundle, ok := blobsBundle.(*enginev1.BlobsBundleV2) + if blobsBundle != nil && !ok { + return nil, fmt.Errorf("expected *BlobsBundleV2, got %T", blobsBundle) + } + return vs.constructFuluBlock(blockProto, isBlinded, bidStr, bundle), nil default: return nil, fmt.Errorf("unknown block version: %d", sBlk.Version()) } @@ -92,7 +106,7 @@ func (vs *Server) constructElectraBlock(blockProto proto.Message, isBlinded bool return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_Electra{Electra: electraContents}, IsBlinded: false, PayloadValue: payloadValue} } -func (vs *Server) constructFuluBlock(blockProto proto.Message, isBlinded bool, payloadValue string, bundle *enginev1.BlobsBundle) *ethpb.GenericBeaconBlock { +func (vs *Server) constructFuluBlock(blockProto proto.Message, isBlinded bool, payloadValue string, bundle *enginev1.BlobsBundleV2) *ethpb.GenericBeaconBlock { if isBlinded { return ðpb.GenericBeaconBlock{Block: ðpb.GenericBeaconBlock_BlindedFulu{BlindedFulu: blockProto.(*ethpb.BlindedBeaconBlockFulu)}, IsBlinded: true, PayloadValue: payloadValue} } diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block_test.go index 7a037da0c7f8..764084da9ffa 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block_test.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block_test.go @@ -29,12 +29,19 @@ func TestConstructGenericBeaconBlock(t *testing.T) { require.NoError(t, err) r1, err := eb.Block.HashTreeRoot() require.NoError(t, err) - result, err := vs.constructGenericBeaconBlock(b, nil, primitives.ZeroWei()) + bundle := &enginev1.BlobsBundleV2{ + KzgCommitments: [][]byte{{1, 2, 3}}, + Proofs: [][]byte{{4, 5, 6}}, + Blobs: [][]byte{{7, 8, 9}}, + } + result, err := vs.constructGenericBeaconBlock(b, bundle, primitives.ZeroWei()) require.NoError(t, err) r2, err := result.GetFulu().Block.HashTreeRoot() require.NoError(t, err) require.Equal(t, r1, r2) require.Equal(t, result.IsBlinded, false) + require.DeepEqual(t, bundle.Blobs, result.GetFulu().GetBlobs()) + require.DeepEqual(t, bundle.Proofs, result.GetFulu().GetKzgProofs()) }) // Test for Electra version diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go index 1d55f774db2d..ef146797d1da 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go @@ -238,7 +238,7 @@ func (vs *Server) BuildBlockParallel(ctx context.Context, sBlk interfaces.Signed }() winningBid := primitives.ZeroWei() - var bundle *enginev1.BlobsBundle + var bundle enginev1.BlobsBundler if sBlk.Version() >= version.Bellatrix { local, err := vs.getLocalPayload(ctx, sBlk.Block(), head) if err != nil { @@ -369,7 +369,7 @@ func (vs *Server) handleBlindedBlock(ctx context.Context, block interfaces.Signe } if isPeerDASEnabled { - dataColumnSideCars, err := peerdas.ConstructDataColumnSidecars(block, bundle.Blobs, bundle.Proofs) + dataColumnSideCars, err := peerdas.ConstructDataColumnSidecars(block, bundle.GetBlobs(), bundle.GetProofs()) if err != nil { return nil, nil, nil, errors.Wrap(err, "construct data column sidecars") } diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go index ffb3777f48fd..87eb0a6bc85a 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go @@ -54,7 +54,7 @@ const blockBuilderTimeout = 1 * time.Second const gasLimitAdjustmentFactor = 1024 // Sets the execution data for the block. Execution data can come from local EL client or remote builder depends on validator registration and circuit breaker conditions. -func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, local *blocks.GetPayloadResponse, bid builder.Bid, builderBoostFactor primitives.Gwei) (primitives.Wei, *enginev1.BlobsBundle, error) { +func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, local *blocks.GetPayloadResponse, bid builder.Bid, builderBoostFactor primitives.Gwei) (primitives.Wei, enginev1.BlobsBundler, error) { _, span := trace.StartSpan(ctx, "ProposerServer.setExecutionData") defer span.End() @@ -376,7 +376,7 @@ func matchingWithdrawalsRoot(local, builder interfaces.ExecutionData) (bool, err func setLocalExecution(blk interfaces.SignedBeaconBlock, local *blocks.GetPayloadResponse) error { var kzgCommitments [][]byte if local.BlobsBundle != nil { - kzgCommitments = local.BlobsBundle.KzgCommitments + kzgCommitments = local.BlobsBundle.GetKzgCommitments() } if local.ExecutionRequests != nil { if err := blk.SetExecutionRequests(local.ExecutionRequests); err != nil { diff --git a/consensus-types/blocks/execution.go b/consensus-types/blocks/execution.go index 1ef77ce875be..e33d846d1cf5 100644 --- a/consensus-types/blocks/execution.go +++ b/consensus-types/blocks/execution.go @@ -41,6 +41,8 @@ func NewWrappedExecutionData(v proto.Message) (interfaces.ExecutionData, error) case *enginev1.ExecutionBundleElectra: // note: no payload changes in electra so using deneb return WrappedExecutionPayloadDeneb(pbStruct.Payload) + case *enginev1.ExecutionBundleFulu: + return WrappedExecutionPayloadDeneb(pbStruct.Payload) default: // return nil, errors.Wrapf(ErrUnsupportedVersion, "type %T", pbStruct) return nil, errs.Wrapf(ErrUnsupportedVersion, "type %T", pbStruct) diff --git a/consensus-types/blocks/get_payload.go b/consensus-types/blocks/get_payload.go index 8aa086b2f61f..4bac9074d30e 100644 --- a/consensus-types/blocks/get_payload.go +++ b/consensus-types/blocks/get_payload.go @@ -12,7 +12,7 @@ import ( // GetPayloadResponseV(1|2|3|4) value. type GetPayloadResponse struct { ExecutionData interfaces.ExecutionData - BlobsBundle *pb.BlobsBundle + BlobsBundle pb.BlobsBundler OverrideBuilder bool // todo: should we convert this to Gwei up front? Bid primitives.Wei @@ -24,6 +24,10 @@ type bundleGetter interface { GetBlobsBundle() *pb.BlobsBundle } +type bundleV2Getter interface { + GetBlobsBundle() *pb.BlobsBundleV2 +} + // bidValueGetter is an interface satisfied by get payload responses that have a bid value. type bidValueGetter interface { GetValue() []byte @@ -43,6 +47,10 @@ func NewGetPayloadResponse(msg proto.Message) (*GetPayloadResponse, error) { if hasBundle { r.BlobsBundle = bundleGetter.GetBlobsBundle() } + bundleV2Getter, hasBundle := msg.(bundleV2Getter) + if hasBundle { + r.BlobsBundle = bundleV2Getter.GetBlobsBundle() + } bidValueGetter, hasBid := msg.(bidValueGetter) executionRequestsGetter, hasExecutionRequests := msg.(executionRequestsGetter) wei := primitives.ZeroWei() diff --git a/proto/engine/v1/BUILD.bazel b/proto/engine/v1/BUILD.bazel index c59a17fdb3af..49bfc9c5a0aa 100644 --- a/proto/engine/v1/BUILD.bazel +++ b/proto/engine/v1/BUILD.bazel @@ -74,6 +74,7 @@ go_proto_library( go_library( name = "go_default_library", srcs = [ + "blobs_bundle.go", "electra.go", "execution_engine.go", "json_marshal_unmarshal.go", diff --git a/proto/engine/v1/blobs_bundle.go b/proto/engine/v1/blobs_bundle.go new file mode 100644 index 000000000000..37e7c3d7157b --- /dev/null +++ b/proto/engine/v1/blobs_bundle.go @@ -0,0 +1,7 @@ +package enginev1 + +type BlobsBundler interface { + GetKzgCommitments() [][]byte + GetProofs() [][]byte + GetBlobs() [][]byte +} diff --git a/proto/engine/v1/electra.pb.go b/proto/engine/v1/electra.pb.go index d3a6c8295868..47f76995c2e1 100755 --- a/proto/engine/v1/electra.pb.go +++ b/proto/engine/v1/electra.pb.go @@ -369,6 +369,85 @@ func (x *ExecutionBundleElectra) GetExecutionRequests() [][]byte { return nil } +type ExecutionBundleFulu struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Payload *ExecutionPayloadDeneb `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + BlobsBundle *BlobsBundleV2 `protobuf:"bytes,3,opt,name=blobs_bundle,json=blobsBundle,proto3" json:"blobs_bundle,omitempty"` + ShouldOverrideBuilder bool `protobuf:"varint,4,opt,name=should_override_builder,json=shouldOverrideBuilder,proto3" json:"should_override_builder,omitempty"` + ExecutionRequests [][]byte `protobuf:"bytes,5,rep,name=execution_requests,json=executionRequests,proto3" json:"execution_requests,omitempty"` +} + +func (x *ExecutionBundleFulu) Reset() { + *x = ExecutionBundleFulu{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_electra_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutionBundleFulu) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionBundleFulu) ProtoMessage() {} + +func (x *ExecutionBundleFulu) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_electra_proto_msgTypes[5] + 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 ExecutionBundleFulu.ProtoReflect.Descriptor instead. +func (*ExecutionBundleFulu) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_electra_proto_rawDescGZIP(), []int{5} +} + +func (x *ExecutionBundleFulu) GetPayload() *ExecutionPayloadDeneb { + if x != nil { + return x.Payload + } + return nil +} + +func (x *ExecutionBundleFulu) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *ExecutionBundleFulu) GetBlobsBundle() *BlobsBundleV2 { + if x != nil { + return x.BlobsBundle + } + return nil +} + +func (x *ExecutionBundleFulu) GetShouldOverrideBuilder() bool { + if x != nil { + return x.ShouldOverrideBuilder + } + return false +} + +func (x *ExecutionBundleFulu) GetExecutionRequests() [][]byte { + if x != nil { + return x.ExecutionRequests + } + return nil +} + var File_proto_engine_v1_electra_proto protoreflect.FileDescriptor var file_proto_engine_v1_electra_proto_rawDesc = []byte{ @@ -445,6 +524,24 @@ var file_proto_engine_v1_electra_proto_rawDesc = []byte{ 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x9d, 0x02, 0x0a, 0x13, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x46, + 0x75, 0x6c, 0x75, 0x12, 0x43, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 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, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x52, + 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x44, + 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, + 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, + 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x56, 0x32, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, + 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x6f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x4f, 0x76, 0x65, + 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x42, 0x8e, 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, 0x0c, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x50, @@ -470,27 +567,31 @@ func file_proto_engine_v1_electra_proto_rawDescGZIP() []byte { return file_proto_engine_v1_electra_proto_rawDescData } -var file_proto_engine_v1_electra_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_proto_engine_v1_electra_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_proto_engine_v1_electra_proto_goTypes = []interface{}{ (*WithdrawalRequest)(nil), // 0: ethereum.engine.v1.WithdrawalRequest (*DepositRequest)(nil), // 1: ethereum.engine.v1.DepositRequest (*ConsolidationRequest)(nil), // 2: ethereum.engine.v1.ConsolidationRequest (*ExecutionRequests)(nil), // 3: ethereum.engine.v1.ExecutionRequests (*ExecutionBundleElectra)(nil), // 4: ethereum.engine.v1.ExecutionBundleElectra - (*ExecutionPayloadDeneb)(nil), // 5: ethereum.engine.v1.ExecutionPayloadDeneb - (*BlobsBundle)(nil), // 6: ethereum.engine.v1.BlobsBundle + (*ExecutionBundleFulu)(nil), // 5: ethereum.engine.v1.ExecutionBundleFulu + (*ExecutionPayloadDeneb)(nil), // 6: ethereum.engine.v1.ExecutionPayloadDeneb + (*BlobsBundle)(nil), // 7: ethereum.engine.v1.BlobsBundle + (*BlobsBundleV2)(nil), // 8: ethereum.engine.v1.BlobsBundleV2 } var file_proto_engine_v1_electra_proto_depIdxs = []int32{ 1, // 0: ethereum.engine.v1.ExecutionRequests.deposits:type_name -> ethereum.engine.v1.DepositRequest 0, // 1: ethereum.engine.v1.ExecutionRequests.withdrawals:type_name -> ethereum.engine.v1.WithdrawalRequest 2, // 2: ethereum.engine.v1.ExecutionRequests.consolidations:type_name -> ethereum.engine.v1.ConsolidationRequest - 5, // 3: ethereum.engine.v1.ExecutionBundleElectra.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb - 6, // 4: ethereum.engine.v1.ExecutionBundleElectra.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 6, // 3: ethereum.engine.v1.ExecutionBundleElectra.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb + 7, // 4: ethereum.engine.v1.ExecutionBundleElectra.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle + 6, // 5: ethereum.engine.v1.ExecutionBundleFulu.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb + 8, // 6: ethereum.engine.v1.ExecutionBundleFulu.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundleV2 + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_proto_engine_v1_electra_proto_init() } @@ -560,6 +661,18 @@ func file_proto_engine_v1_electra_proto_init() { return nil } } + file_proto_engine_v1_electra_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutionBundleFulu); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -567,7 +680,7 @@ func file_proto_engine_v1_electra_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_engine_v1_electra_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/engine/v1/electra.proto b/proto/engine/v1/electra.proto index d52f3b58e34f..b295a3e7b587 100644 --- a/proto/engine/v1/electra.proto +++ b/proto/engine/v1/electra.proto @@ -81,3 +81,11 @@ message ExecutionBundleElectra { bool should_override_builder = 4; repeated bytes execution_requests = 5; } + +message ExecutionBundleFulu { + ExecutionPayloadDeneb payload = 1; + bytes value = 2; + BlobsBundleV2 blobs_bundle = 3; + bool should_override_builder = 4; + repeated bytes execution_requests = 5; +} diff --git a/proto/engine/v1/execution_engine.pb.go b/proto/engine/v1/execution_engine.pb.go index 33d1ae538a8f..2d12fd32b17b 100755 --- a/proto/engine/v1/execution_engine.pb.go +++ b/proto/engine/v1/execution_engine.pb.go @@ -1593,7 +1593,7 @@ type BlobsBundle struct { unknownFields protoimpl.UnknownFields KzgCommitments [][]byte `protobuf:"bytes,1,rep,name=kzg_commitments,json=kzgCommitments,proto3" json:"kzg_commitments,omitempty" ssz-max:"4096" ssz-size:"?,48"` - Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"33554432" ssz-size:"?,48"` + Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"4096" ssz-size:"?,48"` Blobs [][]byte `protobuf:"bytes,3,rep,name=blobs,proto3" json:"blobs,omitempty" ssz-max:"4096" ssz-size:"?,131072"` } @@ -1650,6 +1650,69 @@ func (x *BlobsBundle) GetBlobs() [][]byte { return nil } +type BlobsBundleV2 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:"4096" ssz-size:"?,48"` + Proofs [][]byte `protobuf:"bytes,2,rep,name=proofs,proto3" json:"proofs,omitempty" ssz-max:"33554432" ssz-size:"?,48"` + Blobs [][]byte `protobuf:"bytes,3,rep,name=blobs,proto3" json:"blobs,omitempty" ssz-max:"4096" ssz-size:"?,131072"` +} + +func (x *BlobsBundleV2) Reset() { + *x = BlobsBundleV2{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlobsBundleV2) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlobsBundleV2) ProtoMessage() {} + +func (x *BlobsBundleV2) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15] + 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 BlobsBundleV2.ProtoReflect.Descriptor instead. +func (*BlobsBundleV2) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{15} +} + +func (x *BlobsBundleV2) GetKzgCommitments() [][]byte { + if x != nil { + return x.KzgCommitments + } + return nil +} + +func (x *BlobsBundleV2) GetProofs() [][]byte { + if x != nil { + return x.Proofs + } + return nil +} + +func (x *BlobsBundleV2) GetBlobs() [][]byte { + if x != nil { + return x.Blobs + } + return nil +} + type Blob struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1661,7 +1724,7 @@ type Blob struct { func (x *Blob) Reset() { *x = Blob{} if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15] + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1674,7 +1737,7 @@ func (x *Blob) String() string { func (*Blob) ProtoMessage() {} func (x *Blob) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[15] + 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 { @@ -1687,7 +1750,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{15} + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{16} } func (x *Blob) GetData() []byte { @@ -1709,7 +1772,7 @@ type BlobAndProof struct { func (x *BlobAndProof) Reset() { *x = BlobAndProof{} 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) } @@ -1722,7 +1785,7 @@ func (x *BlobAndProof) String() string { func (*BlobAndProof) ProtoMessage() {} func (x *BlobAndProof) 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 { @@ -1735,7 +1798,7 @@ func (x *BlobAndProof) ProtoReflect() protoreflect.Message { // Deprecated: Use BlobAndProof.ProtoReflect.Descriptor instead. func (*BlobAndProof) 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 *BlobAndProof) GetBlob() []byte { @@ -2115,35 +2178,45 @@ var file_proto_engine_v1_execution_engine_proto_rawDesc = []byte{ 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0xa2, 0x01, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, + 0x6e, 0x74, 0x22, 0x9e, 0x01, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x0f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x0e, 0x6b, - 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2c, 0x0a, - 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a, - 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x08, 0x33, 0x33, 0x35, 0x35, 0x34, - 0x34, 0x33, 0x32, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2a, 0x0a, 0x05, 0x62, - 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a, 0xb5, 0x18, 0x08, - 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, - 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, - 0x53, 0x0a, 0x0c, 0x42, 0x6c, 0x6f, 0x62, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, - 0x1e, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x0a, 0x8a, - 0xb5, 0x18, 0x06, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x12, - 0x23, 0x0a, 0x09, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x08, 0x6b, 0x7a, 0x67, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 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, 0x35, 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, + 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x28, 0x0a, + 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, + 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, + 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2a, 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a, 0xb5, 0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33, + 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x05, 0x62, 0x6c, + 0x6f, 0x62, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x0d, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, + 0x64, 0x6c, 0x65, 0x56, 0x32, 0x12, 0x39, 0x0a, 0x0f, 0x6b, 0x7a, 0x67, 0x5f, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, + 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, + 0x52, 0x0e, 0x6b, 0x7a, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, + 0x42, 0x14, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x08, 0x33, 0x33, + 0x35, 0x35, 0x34, 0x34, 0x33, 0x32, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x2a, + 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x14, 0x8a, + 0xb5, 0x18, 0x08, 0x3f, 0x2c, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x92, 0xb5, 0x18, 0x04, 0x34, + 0x30, 0x39, 0x36, 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, 0x53, 0x0a, 0x0c, 0x42, 0x6c, 0x6f, 0x62, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x12, 0x1e, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x42, 0x0a, 0x8a, 0xb5, 0x18, 0x06, 0x31, 0x33, 0x31, 0x30, 0x37, 0x32, 0x52, 0x04, 0x62, 0x6c, + 0x6f, 0x62, 0x12, 0x23, 0x0a, 0x09, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x08, 0x6b, + 0x7a, 0x67, 0x50, 0x72, 0x6f, 0x6f, 0x66, 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, 0x35, 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 ( @@ -2159,7 +2232,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, 17) +var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 18) 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 @@ -2177,8 +2250,9 @@ var file_proto_engine_v1_execution_engine_proto_goTypes = []interface{}{ (*ForkchoiceState)(nil), // 13: ethereum.engine.v1.ForkchoiceState (*Withdrawal)(nil), // 14: ethereum.engine.v1.Withdrawal (*BlobsBundle)(nil), // 15: ethereum.engine.v1.BlobsBundle - (*Blob)(nil), // 16: ethereum.engine.v1.Blob - (*BlobAndProof)(nil), // 17: ethereum.engine.v1.BlobAndProof + (*BlobsBundleV2)(nil), // 16: ethereum.engine.v1.BlobsBundleV2 + (*Blob)(nil), // 17: ethereum.engine.v1.Blob + (*BlobAndProof)(nil), // 18: ethereum.engine.v1.BlobAndProof } var file_proto_engine_v1_execution_engine_proto_depIdxs = []int32{ 14, // 0: ethereum.engine.v1.ExecutionPayloadCapella.withdrawals:type_name -> ethereum.engine.v1.Withdrawal @@ -2383,7 +2457,7 @@ func file_proto_engine_v1_execution_engine_proto_init() { } } file_proto_engine_v1_execution_engine_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Blob); i { + switch v := v.(*BlobsBundleV2); i { case 0: return &v.state case 1: @@ -2395,6 +2469,18 @@ 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 { + 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[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlobAndProof); i { case 0: return &v.state @@ -2413,7 +2499,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: 17, + NumMessages: 18, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/engine/v1/execution_engine.proto b/proto/engine/v1/execution_engine.proto index 6b1242ba20b4..67652a1a6fe5 100644 --- a/proto/engine/v1/execution_engine.proto +++ b/proto/engine/v1/execution_engine.proto @@ -234,8 +234,7 @@ message BlobsBundle { // The proofs of the blobs. repeated bytes proofs = 2 [ (ethereum.eth.ext.ssz_size) = "?,48", - // TODO: That a trick: Use BlobsBundleV2 if accepted in the spec. - (ethereum.eth.ext.ssz_max) = "max_cell_proofs_length.size" + (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size" ]; // The blobs itself. @@ -245,6 +244,23 @@ message BlobsBundle { ]; } +message BlobsBundleV2 { + repeated bytes kzg_commitments = 1 [ + (ethereum.eth.ext.ssz_size) = "?,48", + (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size" + ]; + + repeated bytes proofs = 2 [ + (ethereum.eth.ext.ssz_size) = "?,48", + (ethereum.eth.ext.ssz_max) = "max_cell_proofs_length.size" // Changed in EIP-7594 + ]; + + repeated bytes blobs = 3 [ + (ethereum.eth.ext.ssz_size) = "?,blob.size", + (ethereum.eth.ext.ssz_max) = "max_blob_commitments.size" + ]; +} + // Blob contains the data that is to be committed on chain. message Blob { // The blob bytes. From f69e54a362dd0acca4fb4bb5220a2279afee56cf Mon Sep 17 00:00:00 2001 From: terence tsao Date: Tue, 15 Apr 2025 08:58:03 -0700 Subject: [PATCH 2/3] Execution bundle fulu can unmarshal --- beacon-chain/execution/BUILD.bazel | 1 - beacon-chain/execution/engine_client_test.go | 87 +++++++---- proto/engine/v1/json_marshal_unmarshal.go | 153 +++++++++++++++++++ 3 files changed, 211 insertions(+), 30 deletions(-) diff --git a/beacon-chain/execution/BUILD.bazel b/beacon-chain/execution/BUILD.bazel index b4381a0f75bb..59cf1505d503 100644 --- a/beacon-chain/execution/BUILD.bazel +++ b/beacon-chain/execution/BUILD.bazel @@ -146,6 +146,5 @@ go_test( "@com_github_prometheus_client_golang//prometheus:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", "@com_github_sirupsen_logrus//hooks/test:go_default_library", - "@org_golang_google_protobuf//encoding/protojson:go_default_library", ], ) diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index d78ef151e167..a809e760f930 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -38,7 +38,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/testing/util" "github.com/prysmaticlabs/prysm/v5/time/slots" logTest "github.com/sirupsen/logrus/hooks/test" - "google.golang.org/protobuf/encoding/protojson" ) var ( @@ -410,28 +409,30 @@ func TestClient_HTTP(t *testing.T) { }) t.Run(GetPayloadMethodV5, func(t *testing.T) { payloadId := [8]byte{1} - want, ok := fix["ExecutionBundleFulu"].(*pb.ExecutionBundleFulu) + want, ok := fix["ExecutionBundleFulu"].(*pb.GetPayloadV5ResponseJson) require.Equal(t, true, ok) - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") defer func() { require.NoError(t, r.Body.Close()) }() - // Read and verify request enc, err := io.ReadAll(r.Body) require.NoError(t, err) jsonRequestString := string(enc) - reqArg, err := json.Marshal(pb.PayloadIDBytes(payloadId)) - require.NoError(t, err) - require.Equal(t, strings.Contains(jsonRequestString, string(reqArg)), true) - // Use protojson to marshal the result correctly - marshaled, err := protojson.Marshal(want) + reqArg, err := json.Marshal(pb.PayloadIDBytes(payloadId)) require.NoError(t, err) - response := `{"jsonrpc":"2.0","id":1,"result":` + string(marshaled) + `}` - _, err = w.Write([]byte(response)) + // We expect the JSON string RPC request contains the right arguments. + require.Equal(t, true, strings.Contains( + jsonRequestString, string(reqArg), + )) + resp := map[string]interface{}{ + "jsonrpc": "2.0", + "id": 1, + "result": want, + } + err = json.NewEncoder(w).Encode(resp) require.NoError(t, err) })) defer srv.Close() @@ -440,15 +441,17 @@ func TestClient_HTTP(t *testing.T) { require.NoError(t, err) defer rpcClient.Close() - client := &Service{rpcClient: rpcClient} + client := &Service{} + client.rpcClient = rpcClient + + // We call the RPC method via HTTP and expect a proper result. resp, err := client.GetPayload(ctx, payloadId, 4*params.BeaconConfig().SlotsPerEpoch) require.NoError(t, err) - _, ok = resp.BlobsBundle.(*pb.BlobsBundleV2) if !ok { t.Logf("resp.BlobsBundle has unexpected type: %T", resp.BlobsBundle) } - require.Equal(t, true, ok) + require.Equal(t, ok, true) }) t.Run(ForkchoiceUpdatedMethod+" VALID status", func(t *testing.T) { forkChoiceState := &pb.ForkchoiceState{ @@ -1819,6 +1822,36 @@ func fixturesStruct() *payloadFixtures { append([]byte{pb.WithdrawalRequestType}, withdrawalRequestBytes...), append([]byte{pb.ConsolidationRequestType}, consolidationRequestBytes...)}, } + executionBundleFixtureFulu := &pb.GetPayloadV5ResponseJson{ + ShouldOverrideBuilder: true, + ExecutionPayload: &pb.ExecutionPayloadDenebJSON{ + ParentHash: &common.Hash{'a'}, + FeeRecipient: &common.Address{'b'}, + StateRoot: &common.Hash{'c'}, + ReceiptsRoot: &common.Hash{'d'}, + LogsBloom: &hexutil.Bytes{'e'}, + PrevRandao: &common.Hash{'f'}, + BaseFeePerGas: "0x123", + BlockHash: &common.Hash{'g'}, + Transactions: []hexutil.Bytes{{'h'}}, + Withdrawals: []*pb.Withdrawal{}, + BlockNumber: &hexUint, + GasLimit: &hexUint, + GasUsed: &hexUint, + Timestamp: &hexUint, + BlobGasUsed: &bgu, + ExcessBlobGas: &ebg, + }, + BlockValue: "0x11fffffffff", + BlobsBundle: &pb.BlobBundleV2JSON{ + Commitments: []hexutil.Bytes{[]byte("commitment1"), []byte("commitment2")}, + Proofs: []hexutil.Bytes{[]byte("proof1"), []byte("proof2")}, + Blobs: []hexutil.Bytes{{'a'}, {'b'}}, + }, + ExecutionRequests: []hexutil.Bytes{append([]byte{pb.DepositRequestType}, depositRequestBytes...), + append([]byte{pb.WithdrawalRequestType}, withdrawalRequestBytes...), + append([]byte{pb.ConsolidationRequestType}, consolidationRequestBytes...)}, + } parent := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength) sha3Uncles := bytesutil.PadTo([]byte("sha3Uncles"), fieldparams.RootLength) miner := bytesutil.PadTo([]byte("miner"), fieldparams.FeeRecipientLength) @@ -1904,20 +1937,16 @@ func fixturesStruct() *payloadFixtures { LatestValidHash: foo[:], } return &payloadFixtures{ - ExecutionBlock: executionBlock, - ExecutionPayloadBody: executionPayloadBodyFixture, - ExecutionPayload: executionPayloadFixture, - ExecutionPayloadCapella: executionPayloadFixtureCapella, - ExecutionPayloadDeneb: executionPayloadFixtureDeneb, - EmptyExecutionPayloadDeneb: emptyExecutionPayloadDeneb, - ExecutionPayloadWithValueCapella: executionPayloadWithValueFixtureCapella, - ExecutionPayloadWithValueDeneb: executionPayloadWithValueFixtureDeneb, - ExecutionBundleElectra: executionBundleFixtureElectra, - ExecutionBundleFulu: &pb.ExecutionBundleFulu{ - Payload: &pb.ExecutionPayloadDeneb{}, - BlobsBundle: &pb.BlobsBundleV2{}, - ExecutionRequests: [][]byte{}, - }, + ExecutionBlock: executionBlock, + ExecutionPayloadBody: executionPayloadBodyFixture, + ExecutionPayload: executionPayloadFixture, + ExecutionPayloadCapella: executionPayloadFixtureCapella, + ExecutionPayloadDeneb: executionPayloadFixtureDeneb, + EmptyExecutionPayloadDeneb: emptyExecutionPayloadDeneb, + ExecutionPayloadWithValueCapella: executionPayloadWithValueFixtureCapella, + ExecutionPayloadWithValueDeneb: executionPayloadWithValueFixtureDeneb, + ExecutionBundleElectra: executionBundleFixtureElectra, + ExecutionBundleFulu: executionBundleFixtureFulu, ValidPayloadStatus: validStatus, InvalidBlockHashStatus: inValidBlockHashStatus, AcceptedStatus: acceptedStatus, @@ -1942,7 +1971,7 @@ type payloadFixtures struct { ExecutionPayloadWithValueCapella *pb.GetPayloadV2ResponseJson ExecutionPayloadWithValueDeneb *pb.GetPayloadV3ResponseJson ExecutionBundleElectra *pb.GetPayloadV4ResponseJson - ExecutionBundleFulu *pb.ExecutionBundleFulu + ExecutionBundleFulu *pb.GetPayloadV5ResponseJson ValidPayloadStatus *pb.PayloadStatus InvalidBlockHashStatus *pb.PayloadStatus AcceptedStatus *pb.PayloadStatus diff --git a/proto/engine/v1/json_marshal_unmarshal.go b/proto/engine/v1/json_marshal_unmarshal.go index fd73c1803e79..7181b051996f 100644 --- a/proto/engine/v1/json_marshal_unmarshal.go +++ b/proto/engine/v1/json_marshal_unmarshal.go @@ -305,6 +305,14 @@ type GetPayloadV4ResponseJson struct { ExecutionRequests []hexutil.Bytes `json:"executionRequests"` } +type GetPayloadV5ResponseJson struct { + ExecutionPayload *ExecutionPayloadDenebJSON `json:"executionPayload"` + BlockValue string `json:"blockValue"` + BlobsBundle *BlobBundleV2JSON `json:"blobsBundle"` + ShouldOverrideBuilder bool `json:"shouldOverrideBuilder"` + ExecutionRequests []hexutil.Bytes `json:"executionRequests"` +} + // ExecutionPayloadBody represents the engine API ExecutionPayloadV1 or ExecutionPayloadV2 type. type ExecutionPayloadBody struct { Transactions []hexutil.Bytes `json:"transactions"` @@ -838,6 +846,20 @@ func (b BlobBundleJSON) ToProto() *BlobsBundle { } } +type BlobBundleV2JSON struct { + Commitments []hexutil.Bytes `json:"commitments"` + Proofs []hexutil.Bytes `json:"proofs"` + Blobs []hexutil.Bytes `json:"blobs"` +} + +func (b BlobBundleV2JSON) ToProto() *BlobsBundleV2 { + return &BlobsBundleV2{ + KzgCommitments: bytesutil.SafeCopy2dHexUtilBytes(b.Commitments), + Proofs: bytesutil.SafeCopy2dHexUtilBytes(b.Proofs), + Blobs: bytesutil.SafeCopy2dHexUtilBytes(b.Blobs), + } +} + type BlobAndProofJson struct { Blob hexutil.Bytes `json:"blob"` KzgProof hexutil.Bytes `json:"proof"` @@ -1256,6 +1278,137 @@ func (e *ExecutionBundleElectra) UnmarshalJSON(enc []byte) error { return nil } +func (e *ExecutionBundleFulu) UnmarshalJSON(enc []byte) error { + dec := GetPayloadV5ResponseJson{} + if err := json.Unmarshal(enc, &dec); err != nil { + return err + } + + if dec.ExecutionPayload.ParentHash == nil { + return errors.New("missing required field 'parentHash' for ExecutionPayload") + } + if dec.ExecutionPayload.FeeRecipient == nil { + return errors.New("missing required field 'feeRecipient' for ExecutionPayload") + } + if dec.ExecutionPayload.StateRoot == nil { + return errors.New("missing required field 'stateRoot' for ExecutionPayload") + } + if dec.ExecutionPayload.ReceiptsRoot == nil { + return errors.New("missing required field 'receiptsRoot' for ExecutableDataV1") + } + if dec.ExecutionPayload.LogsBloom == nil { + return errors.New("missing required field 'logsBloom' for ExecutionPayload") + } + if dec.ExecutionPayload.PrevRandao == nil { + return errors.New("missing required field 'prevRandao' for ExecutionPayload") + } + if dec.ExecutionPayload.ExtraData == nil { + return errors.New("missing required field 'extraData' for ExecutionPayload") + } + if dec.ExecutionPayload.BlockHash == nil { + return errors.New("missing required field 'blockHash' for ExecutionPayload") + } + if dec.ExecutionPayload.Transactions == nil { + return errors.New("missing required field 'transactions' for ExecutionPayload") + } + if dec.ExecutionPayload.BlockNumber == nil { + return errors.New("missing required field 'blockNumber' for ExecutionPayload") + } + if dec.ExecutionPayload.Timestamp == nil { + return errors.New("missing required field 'timestamp' for ExecutionPayload") + } + if dec.ExecutionPayload.GasUsed == nil { + return errors.New("missing required field 'gasUsed' for ExecutionPayload") + } + if dec.ExecutionPayload.GasLimit == nil { + return errors.New("missing required field 'gasLimit' for ExecutionPayload") + } + if dec.ExecutionPayload.BlobGasUsed == nil { + return errors.New("missing required field 'blobGasUsed' for ExecutionPayload") + } + if dec.ExecutionPayload.ExcessBlobGas == nil { + return errors.New("missing required field 'excessBlobGas' for ExecutionPayload") + } + + *e = ExecutionBundleFulu{Payload: &ExecutionPayloadDeneb{}} + e.Payload.ParentHash = dec.ExecutionPayload.ParentHash.Bytes() + e.Payload.FeeRecipient = dec.ExecutionPayload.FeeRecipient.Bytes() + e.Payload.StateRoot = dec.ExecutionPayload.StateRoot.Bytes() + e.Payload.ReceiptsRoot = dec.ExecutionPayload.ReceiptsRoot.Bytes() + e.Payload.LogsBloom = *dec.ExecutionPayload.LogsBloom + e.Payload.PrevRandao = dec.ExecutionPayload.PrevRandao.Bytes() + e.Payload.BlockNumber = uint64(*dec.ExecutionPayload.BlockNumber) + e.Payload.GasLimit = uint64(*dec.ExecutionPayload.GasLimit) + e.Payload.GasUsed = uint64(*dec.ExecutionPayload.GasUsed) + e.Payload.Timestamp = uint64(*dec.ExecutionPayload.Timestamp) + e.Payload.ExtraData = dec.ExecutionPayload.ExtraData + baseFee, err := hexutil.DecodeBig(dec.ExecutionPayload.BaseFeePerGas) + if err != nil { + return err + } + e.Payload.BaseFeePerGas = bytesutil.PadTo(bytesutil.ReverseByteOrder(baseFee.Bytes()), fieldparams.RootLength) + + e.Payload.ExcessBlobGas = uint64(*dec.ExecutionPayload.ExcessBlobGas) + e.Payload.BlobGasUsed = uint64(*dec.ExecutionPayload.BlobGasUsed) + + e.Payload.BlockHash = dec.ExecutionPayload.BlockHash.Bytes() + transactions := make([][]byte, len(dec.ExecutionPayload.Transactions)) + for i, tx := range dec.ExecutionPayload.Transactions { + transactions[i] = tx + } + e.Payload.Transactions = transactions + if dec.ExecutionPayload.Withdrawals == nil { + dec.ExecutionPayload.Withdrawals = make([]*Withdrawal, 0) + } + e.Payload.Withdrawals = dec.ExecutionPayload.Withdrawals + + v, err := hexutil.DecodeBig(dec.BlockValue) + if err != nil { + return err + } + e.Value = bytesutil.PadTo(bytesutil.ReverseByteOrder(v.Bytes()), fieldparams.RootLength) + + if dec.BlobsBundle == nil { + return nil + } + e.BlobsBundle = &BlobsBundleV2{} + + commitments := make([][]byte, len(dec.BlobsBundle.Commitments)) + for i, kzg := range dec.BlobsBundle.Commitments { + k := kzg + commitments[i] = bytesutil.PadTo(k[:], fieldparams.BLSPubkeyLength) + } + e.BlobsBundle.KzgCommitments = commitments + + proofs := make([][]byte, len(dec.BlobsBundle.Proofs)) + for i, proof := range dec.BlobsBundle.Proofs { + p := proof + proofs[i] = bytesutil.PadTo(p[:], fieldparams.BLSPubkeyLength) + } + e.BlobsBundle.Proofs = proofs + + blobs := make([][]byte, len(dec.BlobsBundle.Blobs)) + for i, blob := range dec.BlobsBundle.Blobs { + b := make([]byte, fieldparams.BlobLength) + copy(b, blob) + blobs[i] = b + } + e.BlobsBundle.Blobs = blobs + + e.ShouldOverrideBuilder = dec.ShouldOverrideBuilder + + requests := make([][]byte, len(dec.ExecutionRequests)) + for i, request := range dec.ExecutionRequests { + r := make([]byte, len(request)) + copy(r, request) + requests[i] = r + } + + e.ExecutionRequests = requests + + return nil +} + // RecastHexutilByteSlice converts a []hexutil.Bytes to a [][]byte func RecastHexutilByteSlice(h []hexutil.Bytes) [][]byte { r := make([][]byte, len(h)) From 08c1795e0f5e387fdffc7b3b1ccfdd4779a8e61d Mon Sep 17 00:00:00 2001 From: terence tsao Date: Tue, 15 Apr 2025 14:19:19 -0700 Subject: [PATCH 3/3] Manus feedback and fix execution request decode --- beacon-chain/execution/engine_client_test.go | 16 +- .../validator/construct_generic_block.go | 14 +- .../v1alpha1/validator/proposer_bellatrix.go | 24 +- .../validator/proposer_bellatrix_test.go | 4 +- .../prysm/v1alpha1/validator/proposer_test.go | 2 +- consensus-types/blocks/get_payload.go | 9 +- proto/engine/v1/BUILD.bazel | 2 + proto/engine/v1/electra.pb.go | 135 +---------- proto/engine/v1/electra.proto | 8 - proto/engine/v1/fulu.go | 43 ++++ proto/engine/v1/fulu.pb.go | 210 ++++++++++++++++++ proto/engine/v1/fulu.proto | 21 ++ 12 files changed, 322 insertions(+), 166 deletions(-) create mode 100644 proto/engine/v1/fulu.go create mode 100755 proto/engine/v1/fulu.pb.go create mode 100644 proto/engine/v1/fulu.proto diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index a809e760f930..2dd6b9538a75 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -319,11 +319,11 @@ func TestClient_HTTP(t *testing.T) { require.DeepEqual(t, uint64(2), g) commitments := [][]byte{bytesutil.PadTo([]byte("commitment1"), fieldparams.BLSPubkeyLength), bytesutil.PadTo([]byte("commitment2"), fieldparams.BLSPubkeyLength)} - require.DeepEqual(t, commitments, resp.BlobsBundle.GetKzgCommitments()) + require.DeepEqual(t, commitments, resp.BlobsBundler.GetKzgCommitments()) proofs := [][]byte{bytesutil.PadTo([]byte("proof1"), fieldparams.BLSPubkeyLength), bytesutil.PadTo([]byte("proof2"), fieldparams.BLSPubkeyLength)} - require.DeepEqual(t, proofs, resp.BlobsBundle.GetProofs()) + require.DeepEqual(t, proofs, resp.BlobsBundler.GetProofs()) blobs := [][]byte{bytesutil.PadTo([]byte("a"), fieldparams.BlobLength), bytesutil.PadTo([]byte("b"), fieldparams.BlobLength)} - require.DeepEqual(t, blobs, resp.BlobsBundle.GetBlobs()) + require.DeepEqual(t, blobs, resp.BlobsBundler.GetBlobs()) }) t.Run(GetPayloadMethodV4, func(t *testing.T) { payloadId := [8]byte{1} @@ -374,11 +374,11 @@ func TestClient_HTTP(t *testing.T) { require.DeepEqual(t, uint64(2), g) commitments := [][]byte{bytesutil.PadTo([]byte("commitment1"), fieldparams.BLSPubkeyLength), bytesutil.PadTo([]byte("commitment2"), fieldparams.BLSPubkeyLength)} - require.DeepEqual(t, commitments, resp.BlobsBundle.GetKzgCommitments()) + require.DeepEqual(t, commitments, resp.BlobsBundler.GetKzgCommitments()) proofs := [][]byte{bytesutil.PadTo([]byte("proof1"), fieldparams.BLSPubkeyLength), bytesutil.PadTo([]byte("proof2"), fieldparams.BLSPubkeyLength)} - require.DeepEqual(t, proofs, resp.BlobsBundle.GetProofs()) + require.DeepEqual(t, proofs, resp.BlobsBundler.GetProofs()) blobs := [][]byte{bytesutil.PadTo([]byte("a"), fieldparams.BlobLength), bytesutil.PadTo([]byte("b"), fieldparams.BlobLength)} - require.DeepEqual(t, blobs, resp.BlobsBundle.GetBlobs()) + require.DeepEqual(t, blobs, resp.BlobsBundler.GetBlobs()) requests := &pb.ExecutionRequests{ Deposits: []*pb.DepositRequest{ { @@ -447,9 +447,9 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. resp, err := client.GetPayload(ctx, payloadId, 4*params.BeaconConfig().SlotsPerEpoch) require.NoError(t, err) - _, ok = resp.BlobsBundle.(*pb.BlobsBundleV2) + _, ok = resp.BlobsBundler.(*pb.BlobsBundleV2) if !ok { - t.Logf("resp.BlobsBundle has unexpected type: %T", resp.BlobsBundle) + t.Logf("resp.BlobsBundler has unexpected type: %T", resp.BlobsBundler) } require.Equal(t, ok, true) }) diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go b/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go index 947c891c5a81..71426d9305b9 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/construct_generic_block.go @@ -15,7 +15,7 @@ import ( // constructGenericBeaconBlock constructs a `GenericBeaconBlock` based on the block version and other parameters. func (vs *Server) constructGenericBeaconBlock( sBlk interfaces.SignedBeaconBlock, - blobsBundle enginev1.BlobsBundler, + blobsBundler enginev1.BlobsBundler, winningBid primitives.Wei, ) (*ethpb.GenericBeaconBlock, error) { if sBlk == nil || sBlk.Block() == nil { @@ -40,18 +40,18 @@ func (vs *Server) constructGenericBeaconBlock( case version.Capella: return vs.constructCapellaBlock(blockProto, isBlinded, bidStr), nil case version.Deneb, version.Electra: - bundle, ok := blobsBundle.(*enginev1.BlobsBundle) - if blobsBundle != nil && !ok { - return nil, fmt.Errorf("expected *BlobsBundle, got %T", blobsBundle) + bundle, ok := blobsBundler.(*enginev1.BlobsBundle) + if blobsBundler != nil && !ok { + return nil, fmt.Errorf("expected *BlobsBundler, got %T", blobsBundler) } if sBlk.Version() == version.Deneb { return vs.constructDenebBlock(blockProto, isBlinded, bidStr, bundle), nil } return vs.constructElectraBlock(blockProto, isBlinded, bidStr, bundle), nil case version.Fulu: - bundle, ok := blobsBundle.(*enginev1.BlobsBundleV2) - if blobsBundle != nil && !ok { - return nil, fmt.Errorf("expected *BlobsBundleV2, got %T", blobsBundle) + bundle, ok := blobsBundler.(*enginev1.BlobsBundleV2) + if blobsBundler != nil && !ok { + return nil, fmt.Errorf("expected *BlobsBundleV2, got %T", blobsBundler) } return vs.constructFuluBlock(blockProto, isBlinded, bidStr, bundle), nil default: diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go index 87eb0a6bc85a..3c216ac72b74 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go @@ -69,13 +69,13 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc // Use local payload if builder payload is nil. if bid == nil { - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } builderPayload, err := bid.Header() if err != nil { log.WithError(err).Warn("Proposer: failed to retrieve header from BuilderBid") - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } switch { @@ -84,7 +84,7 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc if err != nil { tracing.AnnotateError(span, err) log.WithError(err).Warn("Proposer: failed to match withdrawals root") - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } // Compare payload values between local and builder. Default to the local value if it is higher. @@ -97,7 +97,7 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc "minBuilderBid": minBid, "builderGweiValue": builderValueGwei, }).Warn("Proposer: using local execution payload because min bid not attained") - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } // Use local block if min difference is not attained @@ -108,7 +108,7 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc "minBidDiff": minDiff, "builderGweiValue": builderValueGwei, }).Warn("Proposer: using local execution payload because min difference with local value was not attained") - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } // Use builder payload if the following in true: @@ -133,7 +133,7 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc bidDeneb, ok := bid.(builder.BidDeneb) if !ok { log.Warnf("bid type %T does not implement builder.BidDeneb", bid) - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } else { builderKzgCommitments = bidDeneb.BlobKzgCommitments() } @@ -144,14 +144,14 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc bidElectra, ok := bid.(builder.BidElectra) if !ok { log.Warnf("bid type %T does not implement builder.BidElectra", bid) - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } else { executionRequests = bidElectra.ExecutionRequests() } } if err := setBuilderExecution(blk, builderPayload, builderKzgCommitments, executionRequests); err != nil { log.WithError(err).Warn("Proposer: failed to set builder payload") - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } else { return bid.Value(), nil, nil } @@ -171,11 +171,11 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc trace.Int64Attribute("builderGweiValue", int64(builderValueGwei)), // lint:ignore uintcast -- This is OK for tracing. trace.Int64Attribute("builderBoostFactor", int64(builderBoostFactor)), // lint:ignore uintcast -- This is OK for tracing. ) - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) default: // Bellatrix case. if err := setBuilderExecution(blk, builderPayload, nil, nil); err != nil { log.WithError(err).Warn("Proposer: failed to set builder payload") - return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) + return local.Bid, local.BlobsBundler, setLocalExecution(blk, local) } else { return bid.Value(), nil, nil } @@ -375,8 +375,8 @@ func matchingWithdrawalsRoot(local, builder interfaces.ExecutionData) (bool, err // It delegates to setExecution for the actual work. func setLocalExecution(blk interfaces.SignedBeaconBlock, local *blocks.GetPayloadResponse) error { var kzgCommitments [][]byte - if local.BlobsBundle != nil { - kzgCommitments = local.BlobsBundle.GetKzgCommitments() + if local.BlobsBundler != nil { + kzgCommitments = local.BlobsBundler.GetKzgCommitments() } if local.ExecutionRequests != nil { if err := blk.SetExecutionRequests(local.ExecutionRequests); err != nil { diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix_test.go index 271575ce3884..674dfa8c860e 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix_test.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix_test.go @@ -520,7 +520,7 @@ func TestServer_setExecutionData(t *testing.T) { PayloadIDBytes: id, GetPayloadResponse: &blocks.GetPayloadResponse{ ExecutionData: ed, - BlobsBundle: blobsBundle, + BlobsBundler: blobsBundle, Bid: primitives.ZeroWei(), }, } @@ -528,7 +528,7 @@ func TestServer_setExecutionData(t *testing.T) { res, err := vs.getLocalPayload(ctx, blk.Block(), capellaTransitionState) require.NoError(t, err) require.Equal(t, uint64(4), res.ExecutionData.BlockNumber()) - require.DeepEqual(t, res.BlobsBundle, blobsBundle) + require.DeepEqual(t, res.BlobsBundler, blobsBundle) }) t.Run("Can get builder payload and blobs in Deneb", func(t *testing.T) { cfg := params.BeaconConfig().Copy() diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go index 5b439e0a2f0c..c0f949b0a175 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go @@ -529,7 +529,7 @@ func TestServer_GetBeaconBlock_Deneb(t *testing.T) { PayloadIDBytes: &enginev1.PayloadIDBytes{1}, GetPayloadResponse: &blocks.GetPayloadResponse{ ExecutionData: ed, - BlobsBundle: bundle, + BlobsBundler: bundle, }, } diff --git a/consensus-types/blocks/get_payload.go b/consensus-types/blocks/get_payload.go index 4bac9074d30e..42410df4f9b2 100644 --- a/consensus-types/blocks/get_payload.go +++ b/consensus-types/blocks/get_payload.go @@ -12,7 +12,7 @@ import ( // GetPayloadResponseV(1|2|3|4) value. type GetPayloadResponse struct { ExecutionData interfaces.ExecutionData - BlobsBundle pb.BlobsBundler + BlobsBundler pb.BlobsBundler OverrideBuilder bool // todo: should we convert this to Gwei up front? Bid primitives.Wei @@ -45,14 +45,13 @@ func NewGetPayloadResponse(msg proto.Message) (*GetPayloadResponse, error) { r := &GetPayloadResponse{} bundleGetter, hasBundle := msg.(bundleGetter) if hasBundle { - r.BlobsBundle = bundleGetter.GetBlobsBundle() + r.BlobsBundler = bundleGetter.GetBlobsBundle() } bundleV2Getter, hasBundle := msg.(bundleV2Getter) if hasBundle { - r.BlobsBundle = bundleV2Getter.GetBlobsBundle() + r.BlobsBundler = bundleV2Getter.GetBlobsBundle() } bidValueGetter, hasBid := msg.(bidValueGetter) - executionRequestsGetter, hasExecutionRequests := msg.(executionRequestsGetter) wei := primitives.ZeroWei() if hasBid { // The protobuf types that engine api responses unmarshal into store their values in little endian form. @@ -71,6 +70,8 @@ func NewGetPayloadResponse(msg proto.Message) (*GetPayloadResponse, error) { return nil, errors.Wrap(err, "new wrapped execution data") } r.ExecutionData = ed + + executionRequestsGetter, hasExecutionRequests := msg.(executionRequestsGetter) if hasExecutionRequests { requests, err := executionRequestsGetter.GetDecodedExecutionRequests() if err != nil { diff --git a/proto/engine/v1/BUILD.bazel b/proto/engine/v1/BUILD.bazel index 49bfc9c5a0aa..57fddc49e449 100644 --- a/proto/engine/v1/BUILD.bazel +++ b/proto/engine/v1/BUILD.bazel @@ -76,6 +76,7 @@ go_library( srcs = [ "blobs_bundle.go", "electra.go", + "fulu.go", "execution_engine.go", "json_marshal_unmarshal.go", ":ssz_generated_files", # keep @@ -112,6 +113,7 @@ ssz_proto_files( name = "ssz_proto_files", srcs = [ "electra.proto", + "fulu.proto", "execution_engine.proto", "execution_engine_eip7594.proto", ], diff --git a/proto/engine/v1/electra.pb.go b/proto/engine/v1/electra.pb.go index 47f76995c2e1..d3a6c8295868 100755 --- a/proto/engine/v1/electra.pb.go +++ b/proto/engine/v1/electra.pb.go @@ -369,85 +369,6 @@ func (x *ExecutionBundleElectra) GetExecutionRequests() [][]byte { return nil } -type ExecutionBundleFulu struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Payload *ExecutionPayloadDeneb `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` - Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - BlobsBundle *BlobsBundleV2 `protobuf:"bytes,3,opt,name=blobs_bundle,json=blobsBundle,proto3" json:"blobs_bundle,omitempty"` - ShouldOverrideBuilder bool `protobuf:"varint,4,opt,name=should_override_builder,json=shouldOverrideBuilder,proto3" json:"should_override_builder,omitempty"` - ExecutionRequests [][]byte `protobuf:"bytes,5,rep,name=execution_requests,json=executionRequests,proto3" json:"execution_requests,omitempty"` -} - -func (x *ExecutionBundleFulu) Reset() { - *x = ExecutionBundleFulu{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_engine_v1_electra_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExecutionBundleFulu) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExecutionBundleFulu) ProtoMessage() {} - -func (x *ExecutionBundleFulu) ProtoReflect() protoreflect.Message { - mi := &file_proto_engine_v1_electra_proto_msgTypes[5] - 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 ExecutionBundleFulu.ProtoReflect.Descriptor instead. -func (*ExecutionBundleFulu) Descriptor() ([]byte, []int) { - return file_proto_engine_v1_electra_proto_rawDescGZIP(), []int{5} -} - -func (x *ExecutionBundleFulu) GetPayload() *ExecutionPayloadDeneb { - if x != nil { - return x.Payload - } - return nil -} - -func (x *ExecutionBundleFulu) GetValue() []byte { - if x != nil { - return x.Value - } - return nil -} - -func (x *ExecutionBundleFulu) GetBlobsBundle() *BlobsBundleV2 { - if x != nil { - return x.BlobsBundle - } - return nil -} - -func (x *ExecutionBundleFulu) GetShouldOverrideBuilder() bool { - if x != nil { - return x.ShouldOverrideBuilder - } - return false -} - -func (x *ExecutionBundleFulu) GetExecutionRequests() [][]byte { - if x != nil { - return x.ExecutionRequests - } - return nil -} - var File_proto_engine_v1_electra_proto protoreflect.FileDescriptor var file_proto_engine_v1_electra_proto_rawDesc = []byte{ @@ -524,24 +445,6 @@ var file_proto_engine_v1_electra_proto_rawDesc = []byte{ 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x9d, 0x02, 0x0a, 0x13, - 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x46, - 0x75, 0x6c, 0x75, 0x12, 0x43, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 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, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x52, - 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x44, - 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x56, 0x32, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, - 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x6f, - 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x4f, 0x76, 0x65, - 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x42, 0x8e, 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, 0x0c, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x50, @@ -567,31 +470,27 @@ func file_proto_engine_v1_electra_proto_rawDescGZIP() []byte { return file_proto_engine_v1_electra_proto_rawDescData } -var file_proto_engine_v1_electra_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_proto_engine_v1_electra_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_proto_engine_v1_electra_proto_goTypes = []interface{}{ (*WithdrawalRequest)(nil), // 0: ethereum.engine.v1.WithdrawalRequest (*DepositRequest)(nil), // 1: ethereum.engine.v1.DepositRequest (*ConsolidationRequest)(nil), // 2: ethereum.engine.v1.ConsolidationRequest (*ExecutionRequests)(nil), // 3: ethereum.engine.v1.ExecutionRequests (*ExecutionBundleElectra)(nil), // 4: ethereum.engine.v1.ExecutionBundleElectra - (*ExecutionBundleFulu)(nil), // 5: ethereum.engine.v1.ExecutionBundleFulu - (*ExecutionPayloadDeneb)(nil), // 6: ethereum.engine.v1.ExecutionPayloadDeneb - (*BlobsBundle)(nil), // 7: ethereum.engine.v1.BlobsBundle - (*BlobsBundleV2)(nil), // 8: ethereum.engine.v1.BlobsBundleV2 + (*ExecutionPayloadDeneb)(nil), // 5: ethereum.engine.v1.ExecutionPayloadDeneb + (*BlobsBundle)(nil), // 6: ethereum.engine.v1.BlobsBundle } var file_proto_engine_v1_electra_proto_depIdxs = []int32{ 1, // 0: ethereum.engine.v1.ExecutionRequests.deposits:type_name -> ethereum.engine.v1.DepositRequest 0, // 1: ethereum.engine.v1.ExecutionRequests.withdrawals:type_name -> ethereum.engine.v1.WithdrawalRequest 2, // 2: ethereum.engine.v1.ExecutionRequests.consolidations:type_name -> ethereum.engine.v1.ConsolidationRequest - 6, // 3: ethereum.engine.v1.ExecutionBundleElectra.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb - 7, // 4: ethereum.engine.v1.ExecutionBundleElectra.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle - 6, // 5: ethereum.engine.v1.ExecutionBundleFulu.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb - 8, // 6: ethereum.engine.v1.ExecutionBundleFulu.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundleV2 - 7, // [7:7] is the sub-list for method output_type - 7, // [7:7] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name + 5, // 3: ethereum.engine.v1.ExecutionBundleElectra.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb + 6, // 4: ethereum.engine.v1.ExecutionBundleElectra.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name } func init() { file_proto_engine_v1_electra_proto_init() } @@ -661,18 +560,6 @@ func file_proto_engine_v1_electra_proto_init() { return nil } } - file_proto_engine_v1_electra_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExecutionBundleFulu); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } type x struct{} out := protoimpl.TypeBuilder{ @@ -680,7 +567,7 @@ func file_proto_engine_v1_electra_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_engine_v1_electra_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/engine/v1/electra.proto b/proto/engine/v1/electra.proto index b295a3e7b587..d52f3b58e34f 100644 --- a/proto/engine/v1/electra.proto +++ b/proto/engine/v1/electra.proto @@ -81,11 +81,3 @@ message ExecutionBundleElectra { bool should_override_builder = 4; repeated bytes execution_requests = 5; } - -message ExecutionBundleFulu { - ExecutionPayloadDeneb payload = 1; - bytes value = 2; - BlobsBundleV2 blobs_bundle = 3; - bool should_override_builder = 4; - repeated bytes execution_requests = 5; -} diff --git a/proto/engine/v1/fulu.go b/proto/engine/v1/fulu.go new file mode 100644 index 000000000000..26202a239b42 --- /dev/null +++ b/proto/engine/v1/fulu.go @@ -0,0 +1,43 @@ +package enginev1 + +import ( + "github.com/pkg/errors" +) + +func (ebe *ExecutionBundleFulu) GetDecodedExecutionRequests() (*ExecutionRequests, error) { + requests := &ExecutionRequests{} + var prevTypeNum *uint8 + for i := range ebe.ExecutionRequests { + requestType, requestListInSSZBytes, err := decodeExecutionRequest(ebe.ExecutionRequests[i]) + if err != nil { + return nil, err + } + if prevTypeNum != nil && *prevTypeNum >= requestType { + return nil, errors.New("invalid execution request type order or duplicate requests, requests should be in sorted order and unique") + } + prevTypeNum = &requestType + switch requestType { + case DepositRequestType: + drs, err := unmarshalDeposits(requestListInSSZBytes) + if err != nil { + return nil, err + } + requests.Deposits = drs + case WithdrawalRequestType: + wrs, err := unmarshalWithdrawals(requestListInSSZBytes) + if err != nil { + return nil, err + } + requests.Withdrawals = wrs + case ConsolidationRequestType: + crs, err := unmarshalConsolidations(requestListInSSZBytes) + if err != nil { + return nil, err + } + requests.Consolidations = crs + default: + return nil, errors.Errorf("unsupported request type %d", requestType) + } + } + return requests, nil +} diff --git a/proto/engine/v1/fulu.pb.go b/proto/engine/v1/fulu.pb.go new file mode 100755 index 000000000000..22fbac615b80 --- /dev/null +++ b/proto/engine/v1/fulu.pb.go @@ -0,0 +1,210 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v3.21.7 +// source: proto/engine/v1/fulu.proto + +package enginev1 + +import ( + reflect "reflect" + sync "sync" + + _ "github.com/prysmaticlabs/prysm/v5/proto/eth/ext" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ExecutionBundleFulu struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Payload *ExecutionPayloadDeneb `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + BlobsBundle *BlobsBundleV2 `protobuf:"bytes,3,opt,name=blobs_bundle,json=blobsBundle,proto3" json:"blobs_bundle,omitempty"` + ShouldOverrideBuilder bool `protobuf:"varint,4,opt,name=should_override_builder,json=shouldOverrideBuilder,proto3" json:"should_override_builder,omitempty"` + ExecutionRequests [][]byte `protobuf:"bytes,5,rep,name=execution_requests,json=executionRequests,proto3" json:"execution_requests,omitempty"` +} + +func (x *ExecutionBundleFulu) Reset() { + *x = ExecutionBundleFulu{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_fulu_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutionBundleFulu) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionBundleFulu) ProtoMessage() {} + +func (x *ExecutionBundleFulu) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_fulu_proto_msgTypes[0] + 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 ExecutionBundleFulu.ProtoReflect.Descriptor instead. +func (*ExecutionBundleFulu) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_fulu_proto_rawDescGZIP(), []int{0} +} + +func (x *ExecutionBundleFulu) GetPayload() *ExecutionPayloadDeneb { + if x != nil { + return x.Payload + } + return nil +} + +func (x *ExecutionBundleFulu) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *ExecutionBundleFulu) GetBlobsBundle() *BlobsBundleV2 { + if x != nil { + return x.BlobsBundle + } + return nil +} + +func (x *ExecutionBundleFulu) GetShouldOverrideBuilder() bool { + if x != nil { + return x.ShouldOverrideBuilder + } + return false +} + +func (x *ExecutionBundleFulu) GetExecutionRequests() [][]byte { + if x != nil { + return x.ExecutionRequests + } + return nil +} + +var File_proto_engine_v1_fulu_proto protoreflect.FileDescriptor + +var file_proto_engine_v1_fulu_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, + 0x31, 0x2f, 0x66, 0x75, 0x6c, 0x75, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x1a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x02, 0x0a, 0x13, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x46, 0x75, 0x6c, 0x75, 0x12, 0x43, 0x0a, + 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, + 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, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x44, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x62, + 0x73, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, + 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x56, + 0x32, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x36, + 0x0a, 0x17, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, + 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x15, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, + 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x42, 0x8e, 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, 0x0c, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 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, 0x35, 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 ( + file_proto_engine_v1_fulu_proto_rawDescOnce sync.Once + file_proto_engine_v1_fulu_proto_rawDescData = file_proto_engine_v1_fulu_proto_rawDesc +) + +func file_proto_engine_v1_fulu_proto_rawDescGZIP() []byte { + file_proto_engine_v1_fulu_proto_rawDescOnce.Do(func() { + file_proto_engine_v1_fulu_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_engine_v1_fulu_proto_rawDescData) + }) + return file_proto_engine_v1_fulu_proto_rawDescData +} + +var file_proto_engine_v1_fulu_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_proto_engine_v1_fulu_proto_goTypes = []interface{}{ + (*ExecutionBundleFulu)(nil), // 0: ethereum.engine.v1.ExecutionBundleFulu + (*ExecutionPayloadDeneb)(nil), // 1: ethereum.engine.v1.ExecutionPayloadDeneb + (*BlobsBundleV2)(nil), // 2: ethereum.engine.v1.BlobsBundleV2 +} +var file_proto_engine_v1_fulu_proto_depIdxs = []int32{ + 1, // 0: ethereum.engine.v1.ExecutionBundleFulu.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb + 2, // 1: ethereum.engine.v1.ExecutionBundleFulu.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundleV2 + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_proto_engine_v1_fulu_proto_init() } +func file_proto_engine_v1_fulu_proto_init() { + if File_proto_engine_v1_fulu_proto != nil { + return + } + file_proto_engine_v1_execution_engine_proto_init() + if !protoimpl.UnsafeEnabled { + file_proto_engine_v1_fulu_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutionBundleFulu); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_engine_v1_fulu_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_engine_v1_fulu_proto_goTypes, + DependencyIndexes: file_proto_engine_v1_fulu_proto_depIdxs, + MessageInfos: file_proto_engine_v1_fulu_proto_msgTypes, + }.Build() + File_proto_engine_v1_fulu_proto = out.File + file_proto_engine_v1_fulu_proto_rawDesc = nil + file_proto_engine_v1_fulu_proto_goTypes = nil + file_proto_engine_v1_fulu_proto_depIdxs = nil +} diff --git a/proto/engine/v1/fulu.proto b/proto/engine/v1/fulu.proto new file mode 100644 index 000000000000..2c078546b1ae --- /dev/null +++ b/proto/engine/v1/fulu.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package ethereum.engine.v1; + +import "proto/eth/ext/options.proto"; +import "proto/engine/v1/execution_engine.proto"; + +option csharp_namespace = "Ethereum.Engine.V1"; +option go_package = "github.com/prysmaticlabs/prysm/v5/proto/engine/v1;enginev1"; +option java_multiple_files = true; +option java_outer_classname = "ElectraProto"; +option java_package = "org.ethereum.engine.v1"; +option php_namespace = "Ethereum\\Engine\\v1"; + +message ExecutionBundleFulu { + ExecutionPayloadDeneb payload = 1; + bytes value = 2; + BlobsBundleV2 blobs_bundle = 3; + bool should_override_builder = 4; + repeated bytes execution_requests = 5; +}