From 31727899ee6fc5bbdfab4e3dcc5f3c990a5bddc5 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Mon, 30 Sep 2024 16:35:30 -0500 Subject: [PATCH 01/26] wip --- beacon-chain/execution/engine_client.go | 3 + .../v1alpha1/validator/proposer_bellatrix.go | 8 + consensus-types/blocks/get_payload.go | 15 +- consensus-types/blocks/setters.go | 10 + consensus-types/interfaces/beacon_block.go | 1 + proto/engine/v1/BUILD.bazel | 1 + proto/engine/v1/electra.go | 5 + proto/engine/v1/electra.pb.go | 256 +++++++++++++----- proto/engine/v1/electra.proto | 14 +- 9 files changed, 241 insertions(+), 72 deletions(-) diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 07075ffa7d37..8a42b80a4d78 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -259,6 +259,9 @@ func (s *Service) ForkchoiceUpdated( func getPayloadMethodAndMessage(slot primitives.Slot) (string, proto.Message) { pe := slots.ToEpoch(slot) + if pe >= params.BeaconConfig().ElectraForkEpoch { + return GetPayloadMethodV4, &pb.ExecutionEnvelopeElectra{} + } if pe >= params.BeaconConfig().DenebForkEpoch { return GetPayloadMethodV3, &pb.ExecutionPayloadDenebWithValueAndBlobsBundle{} } diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go index 5380eb374a90..be60623f76a1 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go @@ -77,6 +77,7 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc log.WithError(err).Warn("Proposer: failed to retrieve header from BuilderBid") return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) } + //TODO: add execution requests here. if bid.Version() >= version.Deneb { builderKzgCommitments, err = bid.BlobKzgCommitments() if err != nil { @@ -353,12 +354,19 @@ func setLocalExecution(blk interfaces.SignedBeaconBlock, local *blocks.GetPayloa if local.BlobsBundle != nil { kzgCommitments = local.BlobsBundle.KzgCommitments } + if local.ExecutionRequests != nil { + if err := blk.SetExecutionRequests(local.ExecutionRequests); err != nil { + return errors.Wrap(err, "could not set execution requests") + } + } + return setExecution(blk, local.ExecutionData, false, kzgCommitments) } // setBuilderExecution sets the execution context for a builder's beacon block. // It delegates to setExecution for the actual work. func setBuilderExecution(blk interfaces.SignedBeaconBlock, execution interfaces.ExecutionData, builderKzgCommitments [][]byte) error { + // TODO #14344: add execution requests for electra return setExecution(blk, execution, true, builderKzgCommitments) } diff --git a/consensus-types/blocks/get_payload.go b/consensus-types/blocks/get_payload.go index c12e84a3acd0..9ee52ccfc7e9 100644 --- a/consensus-types/blocks/get_payload.go +++ b/consensus-types/blocks/get_payload.go @@ -14,7 +14,8 @@ type GetPayloadResponse struct { BlobsBundle *pb.BlobsBundle OverrideBuilder bool // todo: should we convert this to Gwei up front? - Bid primitives.Wei + Bid primitives.Wei + ExecutionRequests *pb.ExecutionRequests } // bundleGetter is an interface satisfied by get payload responses that have a blobs bundle. @@ -31,6 +32,10 @@ type shouldOverrideBuilderGetter interface { GetShouldOverrideBuilder() bool } +type executionRequestsGetter interface { + GetDecodedExecutionRequests() (*pb.ExecutionRequests, error) +} + func NewGetPayloadResponse(msg proto.Message) (*GetPayloadResponse, error) { r := &GetPayloadResponse{} bundleGetter, hasBundle := msg.(bundleGetter) @@ -38,6 +43,7 @@ func NewGetPayloadResponse(msg proto.Message) (*GetPayloadResponse, error) { r.BlobsBundle = bundleGetter.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. @@ -56,5 +62,12 @@ func NewGetPayloadResponse(msg proto.Message) (*GetPayloadResponse, error) { return nil, err } r.ExecutionData = ed + if hasExecutionRequests { + requests, err := executionRequestsGetter.GetDecodedExecutionRequests() + if err != nil { + return nil, err + } + r.ExecutionRequests = requests + } return r, nil } diff --git a/consensus-types/blocks/setters.go b/consensus-types/blocks/setters.go index 3650903404d0..a3eac1e54658 100644 --- a/consensus-types/blocks/setters.go +++ b/consensus-types/blocks/setters.go @@ -6,6 +6,7 @@ import ( consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types" "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" eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" ) @@ -172,3 +173,12 @@ func (b *SignedBeaconBlock) SetBlobKzgCommitments(c [][]byte) error { b.block.body.blobKzgCommitments = c return nil } + +// SetExecutionRequests sets the execution requests in the block. +func (b *SignedBeaconBlock) SetExecutionRequests(er *enginev1.ExecutionRequests) error { + if b.version < version.Electra { + return consensus_types.ErrNotSupported("SetExecutionRequests", b.version) + } + b.block.body.executionRequests = er + return nil +} diff --git a/consensus-types/interfaces/beacon_block.go b/consensus-types/interfaces/beacon_block.go index ff3e83e61fef..1e9c704d2e7c 100644 --- a/consensus-types/interfaces/beacon_block.go +++ b/consensus-types/interfaces/beacon_block.go @@ -91,6 +91,7 @@ type SignedBeaconBlock interface { SetProposerIndex(idx primitives.ValidatorIndex) SetSlot(slot primitives.Slot) SetSignature(sig []byte) + SetExecutionRequests(er *enginev1.ExecutionRequests) error Unblind(e ExecutionData) error } diff --git a/proto/engine/v1/BUILD.bazel b/proto/engine/v1/BUILD.bazel index f496c41b1814..769b7cdce76f 100644 --- a/proto/engine/v1/BUILD.bazel +++ b/proto/engine/v1/BUILD.bazel @@ -75,6 +75,7 @@ go_library( name = "go_default_library", srcs = [ "electra.go", + "electra.go" "execution_engine.go", "json_marshal_unmarshal.go", ":ssz_generated_files", # keep diff --git a/proto/engine/v1/electra.go b/proto/engine/v1/electra.go index 386cce1bfe16..b3de9426116c 100644 --- a/proto/engine/v1/electra.go +++ b/proto/engine/v1/electra.go @@ -2,3 +2,8 @@ package enginev1 type ExecutionPayloadElectra = ExecutionPayloadDeneb type ExecutionPayloadHeaderElectra = ExecutionPayloadHeaderDeneb + +func (eee *ExecutionEnvelopeElectra) GetDecodedExecutionRequests() (*ExecutionRequests, error) { + // work on decode here + return nil, nil +} diff --git a/proto/engine/v1/electra.pb.go b/proto/engine/v1/electra.pb.go index a23e9a678154..7d8ba55bcf92 100755 --- a/proto/engine/v1/electra.pb.go +++ b/proto/engine/v1/electra.pb.go @@ -290,6 +290,85 @@ func (x *ExecutionRequests) GetConsolidations() []*ConsolidationRequest { return nil } +type ExecutionEnvelopeElectra 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 *BlobsBundle `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 *ExecutionEnvelopeElectra) Reset() { + *x = ExecutionEnvelopeElectra{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_electra_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutionEnvelopeElectra) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionEnvelopeElectra) ProtoMessage() {} + +func (x *ExecutionEnvelopeElectra) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_electra_proto_msgTypes[4] + 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 ExecutionEnvelopeElectra.ProtoReflect.Descriptor instead. +func (*ExecutionEnvelopeElectra) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_electra_proto_rawDescGZIP(), []int{4} +} + +func (x *ExecutionEnvelopeElectra) GetPayload() *ExecutionPayloadDeneb { + if x != nil { + return x.Payload + } + return nil +} + +func (x *ExecutionEnvelopeElectra) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *ExecutionEnvelopeElectra) GetBlobsBundle() *BlobsBundle { + if x != nil { + return x.BlobsBundle + } + return nil +} + +func (x *ExecutionEnvelopeElectra) GetShouldOverrideBuilder() bool { + if x != nil { + return x.ShouldOverrideBuilder + } + return false +} + +func (x *ExecutionEnvelopeElectra) 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{ @@ -298,64 +377,85 @@ var file_proto_engine_v1_electra_proto_rawDesc = []byte{ 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, - 0x22, 0x8d, 0x01, 0x0a, 0x11, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, - 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x31, 0x0a, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, - 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, - 0x22, 0xc3, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x06, 0x70, 0x75, 0x62, - 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x16, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, - 0x6c, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x15, 0x77, 0x69, 0x74, - 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, - 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, - 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x9f, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x73, 0x6f, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x2d, 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, - 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, - 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x0c, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x0d, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x87, 0x02, 0x0a, 0x11, 0x45, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x48, - 0x0a, 0x08, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x42, 0x08, 0x92, 0xb5, 0x18, 0x04, 0x38, 0x31, 0x39, 0x32, 0x52, 0x08, - 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x12, 0x4f, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, - 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, - 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x42, 0x06, 0x92, 0xb5, 0x18, 0x02, 0x31, 0x36, 0x52, 0x0b, 0x77, 0x69, - 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x73, 0x12, 0x57, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, - 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x05, 0x92, 0xb5, 0x18, - 0x01, 0x31, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 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, + 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, 0x8d, 0x01, 0x0a, 0x11, 0x57, 0x69, 0x74, + 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, + 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x0d, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x31, 0x0a, + 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, + 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, + 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xc3, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x06, 0x70, + 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, + 0x02, 0x34, 0x38, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x16, 0x77, + 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, + 0x02, 0x33, 0x32, 0x52, 0x15, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x9f, + 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, + 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x0d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, + 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x75, 0x62, + 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, + 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, + 0x34, 0x38, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, + 0x22, 0x87, 0x02, 0x0a, 0x11, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x48, 0x0a, 0x08, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x08, 0x92, 0xb5, + 0x18, 0x04, 0x38, 0x31, 0x39, 0x32, 0x52, 0x08, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x73, + 0x12, 0x4f, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, + 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x06, 0x92, 0xb5, + 0x18, 0x02, 0x31, 0x36, 0x52, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, + 0x73, 0x12, 0x57, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x42, 0x05, 0x92, 0xb5, 0x18, 0x01, 0x31, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa0, 0x02, 0x0a, 0x18, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, + 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 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, 0x42, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x5f, 0x62, 0x75, 0x6e, 0x64, + 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 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, 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 ( @@ -370,22 +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, 4) +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 + (*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 + (*ExecutionEnvelopeElectra)(nil), // 4: ethereum.engine.v1.ExecutionEnvelopeElectra + (*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 - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 5, // 3: ethereum.engine.v1.ExecutionEnvelopeElectra.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb + 6, // 4: ethereum.engine.v1.ExecutionEnvelopeElectra.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() } @@ -393,6 +498,7 @@ func file_proto_engine_v1_electra_proto_init() { if File_proto_engine_v1_electra_proto != nil { return } + file_proto_engine_v1_execution_engine_proto_init() if !protoimpl.UnsafeEnabled { file_proto_engine_v1_electra_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*WithdrawalRequest); i { @@ -442,6 +548,18 @@ func file_proto_engine_v1_electra_proto_init() { return nil } } + file_proto_engine_v1_electra_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutionEnvelopeElectra); 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{ @@ -449,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: 4, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/engine/v1/electra.proto b/proto/engine/v1/electra.proto index 5b77f682d475..ae7ece53b4a1 100644 --- a/proto/engine/v1/electra.proto +++ b/proto/engine/v1/electra.proto @@ -16,6 +16,7 @@ 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"; @@ -60,7 +61,16 @@ message ConsolidationRequest { // ExecutionRequests is a container that contains all the requests from the execution layer to be included in a block message ExecutionRequests { - repeated DepositRequest deposits = 1 [(ethereum.eth.ext.ssz_max) = "max_deposit_requests_per_payload.size"]; + repeated DepositRequest deposits = 1 [(ethereum.eth.ext.ssz_max) = "max_deposit_requests_per_payload.size"]; repeated WithdrawalRequest withdrawals = 2 [(ethereum.eth.ext.ssz_max) = "max_withdrawal_requests_per_payload.size"]; - repeated ConsolidationRequest consolidations = 3 [(ethereum.eth.ext.ssz_max) = "max_consolidation_requests_per_payload.size"]; + repeated ConsolidationRequest consolidations = 3 [(ethereum.eth.ext.ssz_max) = "max_consolidation_requests_per_payload.size"]; +} + +// ExecutionEnvelopeElectra is a container that builds on Payload V4 and includes execution requests sidecar needed post Electra +message ExecutionEnvelopeElectra { + ExecutionPayloadDeneb payload = 1; + bytes value = 2; + BlobsBundle blobs_bundle = 3; + bool should_override_builder = 4; + repeated bytes execution_requests = 5; } From e5b8bd348c400b7fb45985d809cfc7adb21a52fa Mon Sep 17 00:00:00 2001 From: james-prysm Date: Mon, 30 Sep 2024 16:56:35 -0500 Subject: [PATCH 02/26] gaz --- proto/engine/v1/BUILD.bazel | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/proto/engine/v1/BUILD.bazel b/proto/engine/v1/BUILD.bazel index 769b7cdce76f..93ff16e405fb 100644 --- a/proto/engine/v1/BUILD.bazel +++ b/proto/engine/v1/BUILD.bazel @@ -48,7 +48,7 @@ ssz_gen_marshal( "WithdrawalRequest", "DepositRequest", "ConsolidationRequest", - "ExecutionRequests", + "ExecutionRequests", ], ) @@ -74,8 +74,7 @@ go_proto_library( go_library( name = "go_default_library", srcs = [ - "electra.go", - "electra.go" + "electra.go", "execution_engine.go", "json_marshal_unmarshal.go", ":ssz_generated_files", # keep From 5976923f1f9d050634a6eabdb2a60db034aff842 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Tue, 1 Oct 2024 09:18:04 -0500 Subject: [PATCH 03/26] rename field --- proto/engine/v1/BUILD.bazel | 4 ++-- proto/engine/v1/electra.pb.go | 36 +++++++++++++++++------------------ proto/engine/v1/electra.proto | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/proto/engine/v1/BUILD.bazel b/proto/engine/v1/BUILD.bazel index 93ff16e405fb..fad2e889531d 100644 --- a/proto/engine/v1/BUILD.bazel +++ b/proto/engine/v1/BUILD.bazel @@ -48,7 +48,7 @@ ssz_gen_marshal( "WithdrawalRequest", "DepositRequest", "ConsolidationRequest", - "ExecutionRequests", + "ExecutionRequests", ], ) @@ -74,7 +74,7 @@ go_proto_library( go_library( name = "go_default_library", srcs = [ - "electra.go", + "electra.go", "execution_engine.go", "json_marshal_unmarshal.go", ":ssz_generated_files", # keep diff --git a/proto/engine/v1/electra.pb.go b/proto/engine/v1/electra.pb.go index 7d8ba55bcf92..45584b70dfb9 100755 --- a/proto/engine/v1/electra.pb.go +++ b/proto/engine/v1/electra.pb.go @@ -299,7 +299,7 @@ type ExecutionEnvelopeElectra struct { Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` BlobsBundle *BlobsBundle `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"` + ExecutionRequestsHash [][]byte `protobuf:"bytes,5,rep,name=execution_requests_hash,json=executionRequestsHash,proto3" json:"execution_requests_hash,omitempty"` } func (x *ExecutionEnvelopeElectra) Reset() { @@ -362,9 +362,9 @@ func (x *ExecutionEnvelopeElectra) GetShouldOverrideBuilder() bool { return false } -func (x *ExecutionEnvelopeElectra) GetExecutionRequests() [][]byte { +func (x *ExecutionEnvelopeElectra) GetExecutionRequestsHash() [][]byte { if x != nil { - return x.ExecutionRequests + return x.ExecutionRequestsHash } return nil } @@ -427,7 +427,7 @@ var file_proto_engine_v1_electra_proto_rawDesc = []byte{ 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x05, 0x92, 0xb5, 0x18, 0x01, 0x31, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa0, 0x02, 0x0a, 0x18, 0x45, + 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa9, 0x02, 0x0a, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 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, @@ -442,20 +442,20 @@ var file_proto_engine_v1_electra_proto_rawDesc = []byte{ 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, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x36, + 0x0a, 0x17, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x15, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x73, 0x48, 0x61, 0x73, 0x68, 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 ( diff --git a/proto/engine/v1/electra.proto b/proto/engine/v1/electra.proto index ae7ece53b4a1..7630b3687cb7 100644 --- a/proto/engine/v1/electra.proto +++ b/proto/engine/v1/electra.proto @@ -72,5 +72,5 @@ message ExecutionEnvelopeElectra { bytes value = 2; BlobsBundle blobs_bundle = 3; bool should_override_builder = 4; - repeated bytes execution_requests = 5; + repeated bytes execution_requests_hash = 5; } From 426f664f8ba23cfe511aa2dd341f8b64a700d85d Mon Sep 17 00:00:00 2001 From: james-prysm Date: Tue, 1 Oct 2024 09:46:40 -0500 Subject: [PATCH 04/26] sammy review --- beacon-chain/execution/engine_client.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 8a42b80a4d78..4b659ab17772 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -259,16 +259,16 @@ func (s *Service) ForkchoiceUpdated( func getPayloadMethodAndMessage(slot primitives.Slot) (string, proto.Message) { pe := slots.ToEpoch(slot) - if pe >= params.BeaconConfig().ElectraForkEpoch { + switch { + case pe >= params.BeaconConfig().ElectraForkEpoch: return GetPayloadMethodV4, &pb.ExecutionEnvelopeElectra{} - } - if pe >= params.BeaconConfig().DenebForkEpoch { + case pe == params.BeaconConfig().DenebForkEpoch: return GetPayloadMethodV3, &pb.ExecutionPayloadDenebWithValueAndBlobsBundle{} - } - if pe >= params.BeaconConfig().CapellaForkEpoch { + case pe == params.BeaconConfig().CapellaForkEpoch: return GetPayloadMethodV2, &pb.ExecutionPayloadCapellaWithValue{} + default: + return GetPayloadMethod, &pb.ExecutionPayload{} } - return GetPayloadMethod, &pb.ExecutionPayload{} } // GetPayload calls the engine_getPayloadVX method via JSON-RPC. From 3b0c6e282599e58dece8d5cb13a6455a5c70c5bb Mon Sep 17 00:00:00 2001 From: james-prysm Date: Tue, 1 Oct 2024 11:14:43 -0500 Subject: [PATCH 05/26] updating execution api request and reverting response back --- beacon-chain/blockchain/execution_engine.go | 19 +++++++-- beacon-chain/execution/engine_client.go | 19 ++++++--- beacon-chain/execution/engine_client_test.go | 39 ++++++++++++------- .../execution/testing/mock_engine_client.go | 2 +- proto/engine/v1/electra.pb.go | 36 ++++++++--------- proto/engine/v1/electra.proto | 2 +- 6 files changed, 72 insertions(+), 45 deletions(-) diff --git a/beacon-chain/blockchain/execution_engine.go b/beacon-chain/blockchain/execution_engine.go index 387bc552e9cc..0e5dcded4603 100644 --- a/beacon-chain/blockchain/execution_engine.go +++ b/beacon-chain/blockchain/execution_engine.go @@ -219,16 +219,27 @@ func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion int, } var lastValidHash []byte - if blk.Version() >= version.Deneb { + switch { + case blk.Version() >= version.Electra: + var versionedHashes []common.Hash + versionedHashes, err = kzgCommitmentsToVersionedHashes(blk.Block().Body()) + if err != nil { + return false, errors.Wrap(err, "could not get versioned hashes to feed the engine") + } + pr := common.Hash(blk.Block().ParentRoot()) + // TODO: get encoded hash for execution requests + executionRequestsHash := &common.Hash{} + lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr, executionRequestsHash) + case blk.Version() >= version.Deneb: var versionedHashes []common.Hash versionedHashes, err = kzgCommitmentsToVersionedHashes(blk.Block().Body()) if err != nil { return false, errors.Wrap(err, "could not get versioned hashes to feed the engine") } pr := common.Hash(blk.Block().ParentRoot()) - lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr) - } else { - lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, []common.Hash{}, &common.Hash{} /*empty version hashes and root before Deneb*/) + lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr, nil) + default: + lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, []common.Hash{}, &common.Hash{} /*empty version hashes and root before Deneb*/, nil) } switch { case err == nil: diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 4b659ab17772..572b18289afd 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -114,7 +114,7 @@ type PayloadReconstructor interface { // EngineCaller defines a client that can interact with an Ethereum // execution node's engine service via JSON-RPC. type EngineCaller interface { - NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash) ([]byte, error) + NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash, executionRequestsHash *common.Hash) ([]byte, error) ForkchoiceUpdated( ctx context.Context, state *pb.ForkchoiceState, attrs payloadattribute.Attributer, ) (*pb.PayloadIDBytes, []byte, error) @@ -125,8 +125,8 @@ type EngineCaller interface { var ErrEmptyBlockHash = errors.New("Block hash is empty 0x0000...") -// NewPayload calls the engine_newPayloadVX method via JSON-RPC. -func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash) ([]byte, error) { +// NewPayload request calls the engine_newPayloadVX method via JSON-RPC. +func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash, executionRequestsHash *common.Hash) ([]byte, error) { ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.NewPayload") defer span.End() start := time.Now() @@ -163,9 +163,16 @@ func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionDa if !ok { return nil, errors.New("execution data must be a Deneb execution payload") } - err := s.rpcClient.CallContext(ctx, result, NewPayloadMethodV3, payloadPb, versionedHashes, parentBlockRoot) - if err != nil { - return nil, handleRPCError(err) + if executionRequestsHash == nil { + err := s.rpcClient.CallContext(ctx, result, NewPayloadMethodV3, payloadPb, versionedHashes, parentBlockRoot) + if err != nil { + return nil, handleRPCError(err) + } + } else { + err := s.rpcClient.CallContext(ctx, result, NewPayloadMethodV4, payloadPb, versionedHashes, parentBlockRoot, executionRequestsHash) + if err != nil { + return nil, handleRPCError(err) + } } default: return nil, errors.New("unknown execution data type") diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index d0ec2a48feb4..31f8c224a47d 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -123,7 +123,7 @@ func TestClient_IPC(t *testing.T) { require.Equal(t, true, ok) wrappedPayload, err := blocks.WrappedExecutionPayload(req) require.NoError(t, err) - latestValidHash, err := srv.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + latestValidHash, err := srv.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.NoError(t, err) require.DeepEqual(t, bytesutil.ToBytes32(want.LatestValidHash), bytesutil.ToBytes32(latestValidHash)) }) @@ -134,7 +134,7 @@ func TestClient_IPC(t *testing.T) { require.Equal(t, true, ok) wrappedPayload, err := blocks.WrappedExecutionPayloadCapella(req) require.NoError(t, err) - latestValidHash, err := srv.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + latestValidHash, err := srv.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.NoError(t, err) require.DeepEqual(t, bytesutil.ToBytes32(want.LatestValidHash), bytesutil.ToBytes32(latestValidHash)) }) @@ -470,7 +470,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayload(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.NoError(t, err) require.DeepEqual(t, want.LatestValidHash, resp) }) @@ -484,7 +484,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayloadCapella(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.NoError(t, err) require.DeepEqual(t, want.LatestValidHash, resp) }) @@ -498,7 +498,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayloadDeneb(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, nil) require.NoError(t, err) require.DeepEqual(t, want.LatestValidHash, resp) }) @@ -512,7 +512,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayload(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.ErrorIs(t, ErrAcceptedSyncingPayloadStatus, err) require.DeepEqual(t, []uint8(nil), resp) }) @@ -526,7 +526,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayloadCapella(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.ErrorIs(t, ErrAcceptedSyncingPayloadStatus, err) require.DeepEqual(t, []uint8(nil), resp) }) @@ -540,10 +540,13 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayloadDeneb(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, nil) require.ErrorIs(t, ErrAcceptedSyncingPayloadStatus, err) require.DeepEqual(t, []uint8(nil), resp) }) + t.Run(NewPayloadMethodV4+" SYNCING status", func(t *testing.T) { + // TODO: add a test for PayloadV4 Requests + }) t.Run(NewPayloadMethod+" INVALID_BLOCK_HASH status", func(t *testing.T) { execPayload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload) require.Equal(t, true, ok) @@ -554,7 +557,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayload(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.ErrorIs(t, ErrInvalidBlockHashPayloadStatus, err) require.DeepEqual(t, []uint8(nil), resp) }) @@ -568,7 +571,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayloadCapella(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.ErrorIs(t, ErrInvalidBlockHashPayloadStatus, err) require.DeepEqual(t, []uint8(nil), resp) }) @@ -582,10 +585,13 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayloadDeneb(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, nil) require.ErrorIs(t, ErrInvalidBlockHashPayloadStatus, err) require.DeepEqual(t, []uint8(nil), resp) }) + t.Run(NewPayloadMethodV4+" INVALID_BLOCK_HASH status", func(t *testing.T) { + // TODO: add a test for PayloadV4 Requests + }) t.Run(NewPayloadMethod+" INVALID status", func(t *testing.T) { execPayload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload) require.Equal(t, true, ok) @@ -596,7 +602,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayload(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.ErrorIs(t, ErrInvalidPayloadStatus, err) require.DeepEqual(t, want.LatestValidHash, resp) }) @@ -610,7 +616,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayloadCapella(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.ErrorIs(t, ErrInvalidPayloadStatus, err) require.DeepEqual(t, want.LatestValidHash, resp) }) @@ -624,10 +630,13 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayloadDeneb(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, nil) require.ErrorIs(t, ErrInvalidPayloadStatus, err) require.DeepEqual(t, want.LatestValidHash, resp) }) + t.Run(NewPayloadMethodV4+" INVALID status", func(t *testing.T) { + // TODO: add a test for PayloadV4 Requests + }) t.Run(NewPayloadMethod+" UNKNOWN status", func(t *testing.T) { execPayload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload) require.Equal(t, true, ok) @@ -638,7 +647,7 @@ func TestClient_HTTP(t *testing.T) { // We call the RPC method via HTTP and expect a proper result. wrappedPayload, err := blocks.WrappedExecutionPayload(execPayload) require.NoError(t, err) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{}, nil) require.ErrorIs(t, ErrUnknownPayloadStatus, err) require.DeepEqual(t, []uint8(nil), resp) }) diff --git a/beacon-chain/execution/testing/mock_engine_client.go b/beacon-chain/execution/testing/mock_engine_client.go index 5fd5c41bd25c..5df7e3b7bffb 100644 --- a/beacon-chain/execution/testing/mock_engine_client.go +++ b/beacon-chain/execution/testing/mock_engine_client.go @@ -39,7 +39,7 @@ type EngineClient struct { } // NewPayload -- -func (e *EngineClient) NewPayload(_ context.Context, _ interfaces.ExecutionData, _ []common.Hash, _ *common.Hash) ([]byte, error) { +func (e *EngineClient) NewPayload(_ context.Context, _ interfaces.ExecutionData, _ []common.Hash, _ *common.Hash, _ *common.Hash) ([]byte, error) { return e.NewPayloadResp, e.ErrNewPayload } diff --git a/proto/engine/v1/electra.pb.go b/proto/engine/v1/electra.pb.go index 45584b70dfb9..7d8ba55bcf92 100755 --- a/proto/engine/v1/electra.pb.go +++ b/proto/engine/v1/electra.pb.go @@ -299,7 +299,7 @@ type ExecutionEnvelopeElectra struct { Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` BlobsBundle *BlobsBundle `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"` - ExecutionRequestsHash [][]byte `protobuf:"bytes,5,rep,name=execution_requests_hash,json=executionRequestsHash,proto3" json:"execution_requests_hash,omitempty"` + ExecutionRequests [][]byte `protobuf:"bytes,5,rep,name=execution_requests,json=executionRequests,proto3" json:"execution_requests,omitempty"` } func (x *ExecutionEnvelopeElectra) Reset() { @@ -362,9 +362,9 @@ func (x *ExecutionEnvelopeElectra) GetShouldOverrideBuilder() bool { return false } -func (x *ExecutionEnvelopeElectra) GetExecutionRequestsHash() [][]byte { +func (x *ExecutionEnvelopeElectra) GetExecutionRequests() [][]byte { if x != nil { - return x.ExecutionRequestsHash + return x.ExecutionRequests } return nil } @@ -427,7 +427,7 @@ var file_proto_engine_v1_electra_proto_rawDesc = []byte{ 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x05, 0x92, 0xb5, 0x18, 0x01, 0x31, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa9, 0x02, 0x0a, 0x18, 0x45, + 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa0, 0x02, 0x0a, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 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, @@ -442,20 +442,20 @@ var file_proto_engine_v1_electra_proto_rawDesc = []byte{ 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, 0x36, - 0x0a, 0x17, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, - 0x15, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x48, 0x61, 0x73, 0x68, 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, + 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 ( diff --git a/proto/engine/v1/electra.proto b/proto/engine/v1/electra.proto index 7630b3687cb7..ae7ece53b4a1 100644 --- a/proto/engine/v1/electra.proto +++ b/proto/engine/v1/electra.proto @@ -72,5 +72,5 @@ message ExecutionEnvelopeElectra { bytes value = 2; BlobsBundle blobs_bundle = 3; bool should_override_builder = 4; - repeated bytes execution_requests_hash = 5; + repeated bytes execution_requests = 5; } From c215ba9f2649282750e5592c993b7d2db12c6204 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Tue, 1 Oct 2024 11:20:39 -0500 Subject: [PATCH 06/26] fixing linting --- testing/spectest/shared/common/forkchoice/service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/spectest/shared/common/forkchoice/service.go b/testing/spectest/shared/common/forkchoice/service.go index 6395907b9da2..27b01ec1d073 100644 --- a/testing/spectest/shared/common/forkchoice/service.go +++ b/testing/spectest/shared/common/forkchoice/service.go @@ -103,7 +103,7 @@ func (m *engineMock) ForkchoiceUpdated(context.Context, *pb.ForkchoiceState, pay return nil, m.latestValidHash, m.payloadStatus } -func (m *engineMock) NewPayload(context.Context, interfaces.ExecutionData, []common.Hash, *common.Hash) ([]byte, error) { +func (m *engineMock) NewPayload(context.Context, interfaces.ExecutionData, []common.Hash, *common.Hash, *common.Hash) ([]byte, error) { return m.latestValidHash, m.payloadStatus } From ed07b7539a25779ac74782be5031b62481234f50 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Tue, 1 Oct 2024 11:22:03 -0500 Subject: [PATCH 07/26] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eda07f65687..5f26b255682a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - GetBeaconStateV2: add Electra case. - Implement [consensus-specs/3875](https://github.com/ethereum/consensus-specs/pull/3875) - Tests to ensure sepolia config matches the official upstream yaml +- `engine_newPayloadV4` used for electra payload communication with execution client ### Changed From 015aeed7cec1e10a6ddcd3245dbb33316eb5f098 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Wed, 9 Oct 2024 16:37:46 -0500 Subject: [PATCH 08/26] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c377ebd017a..b29f61caddb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Updated Sepolia bootnodes. - Make committee aware packing the default by deprecating `--enable-committee-aware-packing`. - Moved `ConvertKzgCommitmentToVersionedHash` to the `primitives` package. +- Updated Execution API to support Electra. [pr](https://github.com/prysmaticlabs/prysm/pull/14492) ### Deprecated - `--disable-grpc-gateway` flag is deprecated due to grpc gateway removal. From 0e7a0580811d7fdba70a3ba457db89ce2dcc5d96 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 11:26:39 -0500 Subject: [PATCH 09/26] adding in serialization of requests --- beacon-chain/blockchain/execution_engine.go | 8 +- beacon-chain/execution/engine_client.go | 12 +- proto/engine/v1/electra.go | 104 +++++++++++++++++- .../shared/common/forkchoice/service.go | 2 +- 4 files changed, 116 insertions(+), 10 deletions(-) diff --git a/beacon-chain/blockchain/execution_engine.go b/beacon-chain/blockchain/execution_engine.go index 3e2b36349e3c..b559e3463d61 100644 --- a/beacon-chain/blockchain/execution_engine.go +++ b/beacon-chain/blockchain/execution_engine.go @@ -224,9 +224,11 @@ func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion int, return false, errors.Wrap(err, "could not get versioned hashes to feed the engine") } pr := common.Hash(blk.Block().ParentRoot()) - // TODO: get encoded hash for execution requests - executionRequestsHash := &common.Hash{} - lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr, executionRequestsHash) + requests, err := blk.Block().Body().ExecutionRequests() + if err != nil { + return false, errors.Wrap(err, "could not get execution requests") + } + lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr, requests) case blk.Version() >= version.Deneb: var versionedHashes []common.Hash versionedHashes, err = kzgCommitmentsToVersionedHashes(blk.Block().Body()) diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 572b18289afd..c43c02aa558b 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -114,7 +114,7 @@ type PayloadReconstructor interface { // EngineCaller defines a client that can interact with an Ethereum // execution node's engine service via JSON-RPC. type EngineCaller interface { - NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash, executionRequestsHash *common.Hash) ([]byte, error) + NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash, executionRequests *pb.ExecutionRequests) ([]byte, error) ForkchoiceUpdated( ctx context.Context, state *pb.ForkchoiceState, attrs payloadattribute.Attributer, ) (*pb.PayloadIDBytes, []byte, error) @@ -126,7 +126,7 @@ type EngineCaller interface { var ErrEmptyBlockHash = errors.New("Block hash is empty 0x0000...") // NewPayload request calls the engine_newPayloadVX method via JSON-RPC. -func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash, executionRequestsHash *common.Hash) ([]byte, error) { +func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionData, versionedHashes []common.Hash, parentBlockRoot *common.Hash, executionRequests *pb.ExecutionRequests) ([]byte, error) { ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.NewPayload") defer span.End() start := time.Now() @@ -163,13 +163,17 @@ func (s *Service) NewPayload(ctx context.Context, payload interfaces.ExecutionDa if !ok { return nil, errors.New("execution data must be a Deneb execution payload") } - if executionRequestsHash == nil { + if executionRequests == nil { err := s.rpcClient.CallContext(ctx, result, NewPayloadMethodV3, payloadPb, versionedHashes, parentBlockRoot) if err != nil { return nil, handleRPCError(err) } } else { - err := s.rpcClient.CallContext(ctx, result, NewPayloadMethodV4, payloadPb, versionedHashes, parentBlockRoot, executionRequestsHash) + flattenedRequests, err := pb.EncodeExecutionRequests(executionRequests) + if err != nil { + return nil, errors.Wrap(err, "failed to encode execution requests") + } + err = s.rpcClient.CallContext(ctx, result, NewPayloadMethodV4, payloadPb, versionedHashes, parentBlockRoot, flattenedRequests) if err != nil { return nil, handleRPCError(err) } diff --git a/proto/engine/v1/electra.go b/proto/engine/v1/electra.go index b3de9426116c..b80211dcebc9 100644 --- a/proto/engine/v1/electra.go +++ b/proto/engine/v1/electra.go @@ -1,9 +1,109 @@ package enginev1 +import ( + "github.com/pkg/errors" +) + type ExecutionPayloadElectra = ExecutionPayloadDeneb type ExecutionPayloadHeaderElectra = ExecutionPayloadHeaderDeneb +var ( + drExample = &DepositRequest{} + drSize = drExample.SizeSSZ() + wrExample = &WithdrawalRequest{} + wrSize = wrExample.SizeSSZ() + crExample = &ConsolidationRequest{} + crSize = crExample.SizeSSZ() +) + func (eee *ExecutionEnvelopeElectra) GetDecodedExecutionRequests() (*ExecutionRequests, error) { - // work on decode here - return nil, nil + requests := &ExecutionRequests{} + + if len(eee.ExecutionRequests) != 3 /* types of requests */ { + return nil, errors.Errorf("invalid execution request size: %d", len(eee.ExecutionRequests)) + } + + // deposit requests + drBytes := eee.ExecutionRequests[0] + if len(drBytes)%drSize != 0 { + return nil, errors.New("invalid ssz length for deposit requests") + } + numDepositRequests := len(drBytes) / drSize + requests.Deposits = make([]*DepositRequest, numDepositRequests) + for i := range requests.Deposits { + requestBytes := drBytes[i*drSize : (i+1)*drSize] + dr := &DepositRequest{} + if err := dr.UnmarshalSSZ(requestBytes); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal deposit request") + } + requests.Deposits[i] = dr + } + + // withdrawal requests + wrBytes := eee.ExecutionRequests[1] + if len(wrBytes)%wrSize != 0 { + return nil, errors.New("invalid ssz length for withdrawal requests") + } + numWithdrawalRequests := len(wrBytes) / wrSize + requests.Withdrawals = make([]*WithdrawalRequest, numWithdrawalRequests) + for i := range requests.Withdrawals { + requestBytes := wrBytes[i*wrSize : (i+1)*wrSize] + wr := &WithdrawalRequest{} + if err := wr.UnmarshalSSZ(requestBytes); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal withdrawal request") + } + requests.Withdrawals[i] = wr + } + + // consolidation requests + crBytes := eee.ExecutionRequests[2] + if len(crBytes)%crSize != 0 { + return nil, errors.New("invalid ssz length for consolidation requests") + } + numConsolidationRequests := len(crBytes) / crSize + requests.Consolidations = make([]*ConsolidationRequest, numConsolidationRequests) + for i := range requests.Consolidations { + requestBytes := crBytes[i*wrSize : (i+1)*wrSize] + cr := &ConsolidationRequest{} + if err := cr.UnmarshalSSZ(requestBytes); err != nil { + return nil, errors.Wrap(err, "failed to unmarshal consolidation request") + } + requests.Consolidations[i] = cr + } + + return requests, nil +} + +func EncodeExecutionRequests(requests *ExecutionRequests) ([][]byte, error) { + if requests == nil { + return nil, errors.New("invalid execution requests") + } + + drBytes := make([]byte, len(requests.Deposits)*drSize) + for i, deposit := range requests.Deposits { + dr, err := deposit.MarshalSSZ() + if err != nil { + return nil, errors.Wrap(err, "failed to marshal deposit request") + } + copy(drBytes[i:i+drSize], dr) + } + + wrBytes := make([]byte, len(requests.Withdrawals)*wrSize) + for i, withdrawal := range requests.Withdrawals { + wr, err := withdrawal.MarshalSSZ() + if err != nil { + return nil, errors.Wrap(err, "failed to marshal withdrawal request") + } + copy(wrBytes[i*wrSize:i+wrSize], wr) + } + + crBytes := make([]byte, len(requests.Consolidations)*crSize) + for i, consolidation := range requests.Consolidations { + cr, err := consolidation.MarshalSSZ() + if err != nil { + return nil, errors.Wrap(err, "failed to marshal consolidation request") + } + copy(crBytes[i*crSize:i+crSize], cr) + } + return [][]byte{drBytes, wrBytes, crBytes}, nil } diff --git a/testing/spectest/shared/common/forkchoice/service.go b/testing/spectest/shared/common/forkchoice/service.go index 27b01ec1d073..648f6bd42523 100644 --- a/testing/spectest/shared/common/forkchoice/service.go +++ b/testing/spectest/shared/common/forkchoice/service.go @@ -103,7 +103,7 @@ func (m *engineMock) ForkchoiceUpdated(context.Context, *pb.ForkchoiceState, pay return nil, m.latestValidHash, m.payloadStatus } -func (m *engineMock) NewPayload(context.Context, interfaces.ExecutionData, []common.Hash, *common.Hash, *common.Hash) ([]byte, error) { +func (m *engineMock) NewPayload(context.Context, interfaces.ExecutionData, []common.Hash, *common.Hash, *pb.ExecutionRequests) ([]byte, error) { return m.latestValidHash, m.payloadStatus } From 575b52813160db85844ca9a3c66eff27caf252d4 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 13:39:16 -0500 Subject: [PATCH 10/26] code cleanup --- proto/engine/v1/electra.go | 125 ++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 58 deletions(-) diff --git a/proto/engine/v1/electra.go b/proto/engine/v1/electra.go index b80211dcebc9..7cfe94d109f0 100644 --- a/proto/engine/v1/electra.go +++ b/proto/engine/v1/electra.go @@ -1,6 +1,8 @@ package enginev1 import ( + "fmt" + "github.com/pkg/errors" ) @@ -24,52 +26,25 @@ func (eee *ExecutionEnvelopeElectra) GetDecodedExecutionRequests() (*ExecutionRe } // deposit requests - drBytes := eee.ExecutionRequests[0] - if len(drBytes)%drSize != 0 { - return nil, errors.New("invalid ssz length for deposit requests") - } - numDepositRequests := len(drBytes) / drSize - requests.Deposits = make([]*DepositRequest, numDepositRequests) - for i := range requests.Deposits { - requestBytes := drBytes[i*drSize : (i+1)*drSize] - dr := &DepositRequest{} - if err := dr.UnmarshalSSZ(requestBytes); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal deposit request") - } - requests.Deposits[i] = dr + drs, err := unmarshalItems(eee.ExecutionRequests[0], drSize, func() *DepositRequest { return &DepositRequest{} }) + if err != nil { + return nil, err } + requests.Deposits = drs // withdrawal requests - wrBytes := eee.ExecutionRequests[1] - if len(wrBytes)%wrSize != 0 { - return nil, errors.New("invalid ssz length for withdrawal requests") - } - numWithdrawalRequests := len(wrBytes) / wrSize - requests.Withdrawals = make([]*WithdrawalRequest, numWithdrawalRequests) - for i := range requests.Withdrawals { - requestBytes := wrBytes[i*wrSize : (i+1)*wrSize] - wr := &WithdrawalRequest{} - if err := wr.UnmarshalSSZ(requestBytes); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal withdrawal request") - } - requests.Withdrawals[i] = wr + wrs, err := unmarshalItems(eee.ExecutionRequests[1], wrSize, func() *WithdrawalRequest { return &WithdrawalRequest{} }) + if err != nil { + return nil, err } + requests.Withdrawals = wrs // consolidation requests - crBytes := eee.ExecutionRequests[2] - if len(crBytes)%crSize != 0 { - return nil, errors.New("invalid ssz length for consolidation requests") - } - numConsolidationRequests := len(crBytes) / crSize - requests.Consolidations = make([]*ConsolidationRequest, numConsolidationRequests) - for i := range requests.Consolidations { - requestBytes := crBytes[i*wrSize : (i+1)*wrSize] - cr := &ConsolidationRequest{} - if err := cr.UnmarshalSSZ(requestBytes); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal consolidation request") - } - requests.Consolidations[i] = cr + crs, err := unmarshalItems(eee.ExecutionRequests[2], crSize, func() *ConsolidationRequest { return &ConsolidationRequest{} }) + if err != nil { + return nil, err } + requests.Consolidations = crs return requests, nil } @@ -79,31 +54,65 @@ func EncodeExecutionRequests(requests *ExecutionRequests) ([][]byte, error) { return nil, errors.New("invalid execution requests") } - drBytes := make([]byte, len(requests.Deposits)*drSize) - for i, deposit := range requests.Deposits { - dr, err := deposit.MarshalSSZ() - if err != nil { - return nil, errors.Wrap(err, "failed to marshal deposit request") - } - copy(drBytes[i:i+drSize], dr) + drBytes, err := marshalItems(requests.Deposits) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal deposit requests") + } + + wrBytes, err := marshalItems(requests.Withdrawals) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal withdrawal requests") + } + + crBytes, err := marshalItems(requests.Consolidations) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal consolidation requests") } + return [][]byte{drBytes, wrBytes, crBytes}, nil +} + +type sszUnmarshaler interface { + UnmarshalSSZ([]byte) error +} - wrBytes := make([]byte, len(requests.Withdrawals)*wrSize) - for i, withdrawal := range requests.Withdrawals { - wr, err := withdrawal.MarshalSSZ() +type sszMarshaler interface { + MarshalSSZ() ([]byte, error) +} + +func marshalItems[T sszMarshaler](items []T) ([]byte, error) { + var totalSize int + marshaledItems := make([][]byte, len(items)) + for i, item := range items { + bytes, err := item.MarshalSSZ() if err != nil { - return nil, errors.Wrap(err, "failed to marshal withdrawal request") + return nil, fmt.Errorf("failed to marshal item at index %d: %w", i, err) } - copy(wrBytes[i*wrSize:i+wrSize], wr) + marshaledItems[i] = bytes + totalSize += len(bytes) } - crBytes := make([]byte, len(requests.Consolidations)*crSize) - for i, consolidation := range requests.Consolidations { - cr, err := consolidation.MarshalSSZ() - if err != nil { - return nil, errors.Wrap(err, "failed to marshal consolidation request") + result := make([]byte, totalSize) + + for i, bytes := range marshaledItems { + copy(result[i*len(bytes):(i+1)*len(bytes)], bytes) + } + return result, nil +} + +// Generic function to unmarshal items +func unmarshalItems[T sszUnmarshaler](data []byte, itemSize int, newItem func() T) ([]T, error) { + if len(data)%itemSize != 0 { + return nil, fmt.Errorf("invalid data length: data size (%d) is not a multiple of item size (%d)", len(data), itemSize) + } + numItems := len(data) / itemSize + items := make([]T, numItems) + for i := range items { + itemBytes := data[i*itemSize : (i+1)*itemSize] + item := newItem() + if err := item.UnmarshalSSZ(itemBytes); err != nil { + return nil, fmt.Errorf("failed to unmarshal item at index %d: %w", i, err) } - copy(crBytes[i*crSize:i+crSize], cr) + items[i] = item } - return [][]byte{drBytes, wrBytes, crBytes}, nil + return items, nil } From f854fdf20ae88801ad8d3c6d52a63e3286e07c01 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 14:47:04 -0500 Subject: [PATCH 11/26] adding some happy path tests and fixing mock --- .../execution/testing/mock_engine_client.go | 4 +- proto/engine/v1/electra_test.go | 56 +++++++++++++++++++ proto/engine/v1/export_test.go | 8 +++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 proto/engine/v1/electra_test.go diff --git a/beacon-chain/execution/testing/mock_engine_client.go b/beacon-chain/execution/testing/mock_engine_client.go index 5df7e3b7bffb..58aed533a993 100644 --- a/beacon-chain/execution/testing/mock_engine_client.go +++ b/beacon-chain/execution/testing/mock_engine_client.go @@ -39,7 +39,7 @@ type EngineClient struct { } // NewPayload -- -func (e *EngineClient) NewPayload(_ context.Context, _ interfaces.ExecutionData, _ []common.Hash, _ *common.Hash, _ *common.Hash) ([]byte, error) { +func (e *EngineClient) NewPayload(_ context.Context, _ interfaces.ExecutionData, _ []common.Hash, _ *common.Hash, _ [][]byte) ([]byte, error) { return e.NewPayloadResp, e.ErrNewPayload } @@ -54,7 +54,7 @@ func (e *EngineClient) ForkchoiceUpdated( } // GetPayload -- -func (e *EngineClient) GetPayload(_ context.Context, _ [8]byte, s primitives.Slot) (*blocks.GetPayloadResponse, error) { +func (e *EngineClient) GetPayload(_ context.Context, _ [8]byte, _ primitives.Slot) (*blocks.GetPayloadResponse, error) { return e.GetPayloadResponse, e.ErrGetPayload } diff --git a/proto/engine/v1/electra_test.go b/proto/engine/v1/electra_test.go new file mode 100644 index 000000000000..15f7f88f0e7a --- /dev/null +++ b/proto/engine/v1/electra_test.go @@ -0,0 +1,56 @@ +package enginev1_test + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" + enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1" + "github.com/prysmaticlabs/prysm/v5/testing/require" +) + +var depositRequestsSSZHex = "0x706b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077630000000000000000000000000000000000000000000000000000000000007b00000000000000736967000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c801000000000000706b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000776300000000000000000000000000000000000000000000000000000000000090010000000000007369670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000" + +func TestMarshalItems_OK(t *testing.T) { + drb, err := hexutil.Decode(depositRequestsSSZHex) + require.NoError(t, err) + exampleRequest := &enginev1.DepositRequest{} + depositRequests, err := enginev1.UnmarshalItems(drb, exampleRequest.SizeSSZ(), func() *enginev1.DepositRequest { return &enginev1.DepositRequest{} }) + require.NoError(t, err) + + exampleRequest1 := &enginev1.DepositRequest{ + Pubkey: bytesutil.PadTo([]byte("pk"), 48), + WithdrawalCredentials: bytesutil.PadTo([]byte("wc"), 32), + Amount: 123, + Signature: bytesutil.PadTo([]byte("sig"), 96), + Index: 456, + } + exampleRequest2 := &enginev1.DepositRequest{ + Pubkey: bytesutil.PadTo([]byte("pk"), 48), + WithdrawalCredentials: bytesutil.PadTo([]byte("wc"), 32), + Amount: 400, + Signature: bytesutil.PadTo([]byte("sig"), 96), + Index: 32, + } + require.DeepEqual(t, depositRequests, []*enginev1.DepositRequest{exampleRequest1, exampleRequest2}) +} + +func TestUnmarshalItems_OK(t *testing.T) { + exampleRequest1 := &enginev1.DepositRequest{ + Pubkey: bytesutil.PadTo([]byte("pk"), 48), + WithdrawalCredentials: bytesutil.PadTo([]byte("wc"), 32), + Amount: 123, + Signature: bytesutil.PadTo([]byte("sig"), 96), + Index: 456, + } + exampleRequest2 := &enginev1.DepositRequest{ + Pubkey: bytesutil.PadTo([]byte("pk"), 48), + WithdrawalCredentials: bytesutil.PadTo([]byte("wc"), 32), + Amount: 400, + Signature: bytesutil.PadTo([]byte("sig"), 96), + Index: 32, + } + drbs, err := enginev1.MarshalItems([]*enginev1.DepositRequest{exampleRequest1, exampleRequest2}) + require.NoError(t, err) + require.DeepEqual(t, depositRequestsSSZHex, hexutil.Encode(drbs)) +} diff --git a/proto/engine/v1/export_test.go b/proto/engine/v1/export_test.go index 17f4cde64607..2466b7fa44d1 100644 --- a/proto/engine/v1/export_test.go +++ b/proto/engine/v1/export_test.go @@ -1,3 +1,11 @@ package enginev1 type Copier[T any] copier[T] + +func MarshalItems[T sszMarshaler](items []T) ([]byte, error) { + return marshalItems(items) +} + +func UnmarshalItems[T sszUnmarshaler](data []byte, itemSize int, newItem func() T) ([]T, error) { + return unmarshalItems(data, itemSize, newItem) +} From 4a44864a8ad7e125bfee052496951bc25f10134c Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 14:54:55 -0500 Subject: [PATCH 12/26] mock still broken --- beacon-chain/execution/testing/mock_engine_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon-chain/execution/testing/mock_engine_client.go b/beacon-chain/execution/testing/mock_engine_client.go index 58aed533a993..397384fb6d25 100644 --- a/beacon-chain/execution/testing/mock_engine_client.go +++ b/beacon-chain/execution/testing/mock_engine_client.go @@ -39,7 +39,7 @@ type EngineClient struct { } // NewPayload -- -func (e *EngineClient) NewPayload(_ context.Context, _ interfaces.ExecutionData, _ []common.Hash, _ *common.Hash, _ [][]byte) ([]byte, error) { +func (e *EngineClient) NewPayload(_ context.Context, _ interfaces.ExecutionData, _ []common.Hash, _ *common.Hash, _ *pb.ExecutionRequests) ([]byte, error) { return e.NewPayloadResp, e.ErrNewPayload } From e533241389c68ba4385a49231d7b8f616b726505 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 15:14:17 -0500 Subject: [PATCH 13/26] fixing linting --- beacon-chain/blockchain/execution_engine.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/beacon-chain/blockchain/execution_engine.go b/beacon-chain/blockchain/execution_engine.go index b559e3463d61..a5d69ecf4a2d 100644 --- a/beacon-chain/blockchain/execution_engine.go +++ b/beacon-chain/blockchain/execution_engine.go @@ -224,7 +224,8 @@ func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion int, return false, errors.Wrap(err, "could not get versioned hashes to feed the engine") } pr := common.Hash(blk.Block().ParentRoot()) - requests, err := blk.Block().Body().ExecutionRequests() + var requests *enginev1.ExecutionRequests + requests, err = blk.Block().Body().ExecutionRequests() if err != nil { return false, errors.Wrap(err, "could not get execution requests") } From 539a6339c8d49f4a3d613a38df9e3fdb600f0c5b Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 15:50:13 -0500 Subject: [PATCH 14/26] updating name on proto --- .../v1alpha1/validator/proposer_bellatrix.go | 2 +- proto/engine/v1/electra.go | 2 +- proto/engine/v1/electra.pb.go | 104 +++++++++--------- proto/engine/v1/electra.proto | 4 +- 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go index be60623f76a1..e9d74693cb91 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_bellatrix.go @@ -77,7 +77,7 @@ func setExecutionData(ctx context.Context, blk interfaces.SignedBeaconBlock, loc log.WithError(err).Warn("Proposer: failed to retrieve header from BuilderBid") return local.Bid, local.BlobsBundle, setLocalExecution(blk, local) } - //TODO: add execution requests here. + //TODO: add builder execution requests here. if bid.Version() >= version.Deneb { builderKzgCommitments, err = bid.BlobKzgCommitments() if err != nil { diff --git a/proto/engine/v1/electra.go b/proto/engine/v1/electra.go index 7cfe94d109f0..f30615b38049 100644 --- a/proto/engine/v1/electra.go +++ b/proto/engine/v1/electra.go @@ -18,7 +18,7 @@ var ( crSize = crExample.SizeSSZ() ) -func (eee *ExecutionEnvelopeElectra) GetDecodedExecutionRequests() (*ExecutionRequests, error) { +func (eee *ExecutionBundleElectra) GetDecodedExecutionRequests() (*ExecutionRequests, error) { requests := &ExecutionRequests{} if len(eee.ExecutionRequests) != 3 /* types of requests */ { diff --git a/proto/engine/v1/electra.pb.go b/proto/engine/v1/electra.pb.go index 7d8ba55bcf92..aa0e0809d7a1 100755 --- a/proto/engine/v1/electra.pb.go +++ b/proto/engine/v1/electra.pb.go @@ -290,7 +290,7 @@ func (x *ExecutionRequests) GetConsolidations() []*ConsolidationRequest { return nil } -type ExecutionEnvelopeElectra struct { +type ExecutionBundleElectra struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -302,8 +302,8 @@ type ExecutionEnvelopeElectra struct { ExecutionRequests [][]byte `protobuf:"bytes,5,rep,name=execution_requests,json=executionRequests,proto3" json:"execution_requests,omitempty"` } -func (x *ExecutionEnvelopeElectra) Reset() { - *x = ExecutionEnvelopeElectra{} +func (x *ExecutionBundleElectra) Reset() { + *x = ExecutionBundleElectra{} if protoimpl.UnsafeEnabled { mi := &file_proto_engine_v1_electra_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -311,13 +311,13 @@ func (x *ExecutionEnvelopeElectra) Reset() { } } -func (x *ExecutionEnvelopeElectra) String() string { +func (x *ExecutionBundleElectra) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ExecutionEnvelopeElectra) ProtoMessage() {} +func (*ExecutionBundleElectra) ProtoMessage() {} -func (x *ExecutionEnvelopeElectra) ProtoReflect() protoreflect.Message { +func (x *ExecutionBundleElectra) ProtoReflect() protoreflect.Message { mi := &file_proto_engine_v1_electra_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -329,40 +329,40 @@ func (x *ExecutionEnvelopeElectra) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ExecutionEnvelopeElectra.ProtoReflect.Descriptor instead. -func (*ExecutionEnvelopeElectra) Descriptor() ([]byte, []int) { +// Deprecated: Use ExecutionBundleElectra.ProtoReflect.Descriptor instead. +func (*ExecutionBundleElectra) Descriptor() ([]byte, []int) { return file_proto_engine_v1_electra_proto_rawDescGZIP(), []int{4} } -func (x *ExecutionEnvelopeElectra) GetPayload() *ExecutionPayloadDeneb { +func (x *ExecutionBundleElectra) GetPayload() *ExecutionPayloadDeneb { if x != nil { return x.Payload } return nil } -func (x *ExecutionEnvelopeElectra) GetValue() []byte { +func (x *ExecutionBundleElectra) GetValue() []byte { if x != nil { return x.Value } return nil } -func (x *ExecutionEnvelopeElectra) GetBlobsBundle() *BlobsBundle { +func (x *ExecutionBundleElectra) GetBlobsBundle() *BlobsBundle { if x != nil { return x.BlobsBundle } return nil } -func (x *ExecutionEnvelopeElectra) GetShouldOverrideBuilder() bool { +func (x *ExecutionBundleElectra) GetShouldOverrideBuilder() bool { if x != nil { return x.ShouldOverrideBuilder } return false } -func (x *ExecutionEnvelopeElectra) GetExecutionRequests() [][]byte { +func (x *ExecutionBundleElectra) GetExecutionRequests() [][]byte { if x != nil { return x.ExecutionRequests } @@ -427,35 +427,35 @@ var file_proto_engine_v1_electra_proto_rawDesc = []byte{ 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x05, 0x92, 0xb5, 0x18, 0x01, 0x31, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa0, 0x02, 0x0a, 0x18, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, - 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 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, 0x42, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x5f, 0x62, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 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, 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, + 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x9e, 0x02, 0x0a, 0x16, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x45, 0x6c, + 0x65, 0x63, 0x74, 0x72, 0x61, 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, 0x42, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 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, 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 ( @@ -472,20 +472,20 @@ func file_proto_engine_v1_electra_proto_rawDescGZIP() []byte { 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 - (*ExecutionEnvelopeElectra)(nil), // 4: ethereum.engine.v1.ExecutionEnvelopeElectra - (*ExecutionPayloadDeneb)(nil), // 5: ethereum.engine.v1.ExecutionPayloadDeneb - (*BlobsBundle)(nil), // 6: ethereum.engine.v1.BlobsBundle + (*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 } 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.ExecutionEnvelopeElectra.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb - 6, // 4: ethereum.engine.v1.ExecutionEnvelopeElectra.blobs_bundle:type_name -> ethereum.engine.v1.BlobsBundle + 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 @@ -549,7 +549,7 @@ func file_proto_engine_v1_electra_proto_init() { } } file_proto_engine_v1_electra_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExecutionEnvelopeElectra); i { + switch v := v.(*ExecutionBundleElectra); i { case 0: return &v.state case 1: diff --git a/proto/engine/v1/electra.proto b/proto/engine/v1/electra.proto index ae7ece53b4a1..9ac48bf0d478 100644 --- a/proto/engine/v1/electra.proto +++ b/proto/engine/v1/electra.proto @@ -66,8 +66,8 @@ message ExecutionRequests { repeated ConsolidationRequest consolidations = 3 [(ethereum.eth.ext.ssz_max) = "max_consolidation_requests_per_payload.size"]; } -// ExecutionEnvelopeElectra is a container that builds on Payload V4 and includes execution requests sidecar needed post Electra -message ExecutionEnvelopeElectra { +// ExecutionBundleElectra is a container that builds on Payload V4 and includes execution requests sidecar needed post Electra +message ExecutionBundleElectra { ExecutionPayloadDeneb payload = 1; bytes value = 2; BlobsBundle blobs_bundle = 3; From 2cec3a46c8029716c2296d8054b285926551390c Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 15:56:12 -0500 Subject: [PATCH 15/26] missed naming --- beacon-chain/execution/engine_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index c43c02aa558b..d984c77d778f 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -272,7 +272,7 @@ func getPayloadMethodAndMessage(slot primitives.Slot) (string, proto.Message) { pe := slots.ToEpoch(slot) switch { case pe >= params.BeaconConfig().ElectraForkEpoch: - return GetPayloadMethodV4, &pb.ExecutionEnvelopeElectra{} + return GetPayloadMethodV4, &pb.ExecutionBundleElectra{} case pe == params.BeaconConfig().DenebForkEpoch: return GetPayloadMethodV3, &pb.ExecutionPayloadDenebWithValueAndBlobsBundle{} case pe == params.BeaconConfig().CapellaForkEpoch: From 12f0a068ce9ed51e2dd39aaad040cfbc2ffcc80e Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 16:30:20 -0500 Subject: [PATCH 16/26] placeholder fix for TestClient_HTTP --- beacon-chain/execution/engine_client_test.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index 31f8c224a47d..784676ffc4f7 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -163,7 +163,7 @@ func TestClient_HTTP(t *testing.T) { cfg := params.BeaconConfig().Copy() cfg.CapellaForkEpoch = 1 cfg.DenebForkEpoch = 2 - cfg.ElectraForkEpoch = 2 + cfg.ElectraForkEpoch = 3 params.OverrideBeaconConfig(cfg) t.Run(GetPayloadMethod, func(t *testing.T) { @@ -320,6 +320,10 @@ func TestClient_HTTP(t *testing.T) { blobs := [][]byte{bytesutil.PadTo([]byte("a"), fieldparams.BlobLength), bytesutil.PadTo([]byte("b"), fieldparams.BlobLength)} require.DeepEqual(t, blobs, resp.BlobsBundle.Blobs) }) + t.Run(GetPayloadMethodV4, func(t *testing.T) { + // TODO: add electra test + }) + t.Run(ForkchoiceUpdatedMethod+" VALID status", func(t *testing.T) { forkChoiceState := &pb.ForkchoiceState{ HeadBlockHash: []byte("head"), @@ -502,6 +506,9 @@ func TestClient_HTTP(t *testing.T) { require.NoError(t, err) require.DeepEqual(t, want.LatestValidHash, resp) }) + t.Run(NewPayloadMethodV4+" VALID status", func(t *testing.T) { + // TODO: add electra test + }) t.Run(NewPayloadMethod+" SYNCING status", func(t *testing.T) { execPayload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload) require.Equal(t, true, ok) From ff3170ad340299fad1c645a40a257dd6eecd0ae3 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Fri, 11 Oct 2024 16:43:19 -0500 Subject: [PATCH 17/26] removing duplicate change log --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fad443d2bdb..8546fa1c002b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - GetBeaconStateV2: add Electra case. - Implement [consensus-specs/3875](https://github.com/ethereum/consensus-specs/pull/3875). - Tests to ensure sepolia config matches the official upstream yaml. -- `engine_newPayloadV4`,`engine_getPayloadV4` used for electra payload communication with execution client. +- `engine_newPayloadV4`,`engine_getPayloadV4` used for electra payload communication with execution client. [pr](https://github.com/prysmaticlabs/prysm/pull/14492) - HTTP endpoint for PublishBlobs. - GetBlockV2, GetBlindedBlock, ProduceBlockV2, ProduceBlockV3: add Electra case. - Add Electra support and tests for light client functions. @@ -57,7 +57,6 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Make committee aware packing the default by deprecating `--enable-committee-aware-packing`. - Moved `ConvertKzgCommitmentToVersionedHash` to the `primitives` package. - reversed the boolean return on `BatchVerifyDepositsSignatures`, from need verification, to all keys successfully verified -- Updated Execution API to support Electra. [pr](https://github.com/prysmaticlabs/prysm/pull/14492) ### Deprecated - `--disable-grpc-gateway` flag is deprecated due to grpc gateway removal. From 9dae72107979b1b025d7c7821b680f6f8b0a8beb Mon Sep 17 00:00:00 2001 From: james-prysm Date: Mon, 14 Oct 2024 14:01:52 -0500 Subject: [PATCH 18/26] adding in test for get payloadv4 as well as some tests --- beacon-chain/execution/engine_client_test.go | 131 ++++++++++++++++- consensus-types/blocks/execution.go | 3 + proto/engine/v1/json_marshal_unmarshal.go | 139 ++++++++++++++++++ .../engine/v1/json_marshal_unmarshal_test.go | 3 + 4 files changed, 275 insertions(+), 1 deletion(-) diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index 784676ffc4f7..c7adbe4629d0 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -321,7 +321,86 @@ func TestClient_HTTP(t *testing.T) { require.DeepEqual(t, blobs, resp.BlobsBundle.Blobs) }) t.Run(GetPayloadMethodV4, func(t *testing.T) { - // TODO: add electra test + payloadId := [8]byte{1} + want, ok := fix["ExecutionBundleElectra"].(*pb.GetPayloadV4ResponseJson) + 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()) + }() + enc, err := io.ReadAll(r.Body) + require.NoError(t, err) + jsonRequestString := string(enc) + + reqArg, err := json.Marshal(pb.PayloadIDBytes(payloadId)) + require.NoError(t, err) + + // 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() + + rpcClient, err := rpc.DialHTTP(srv.URL) + require.NoError(t, err) + defer rpcClient.Close() + + client := &Service{} + client.rpcClient = rpcClient + + // We call the RPC method via HTTP and expect a proper result. + resp, err := client.GetPayload(ctx, payloadId, 3*params.BeaconConfig().SlotsPerEpoch) + require.NoError(t, err) + require.Equal(t, true, resp.OverrideBuilder) + g, err := resp.ExecutionData.ExcessBlobGas() + require.NoError(t, err) + require.DeepEqual(t, uint64(3), g) + g, err = resp.ExecutionData.BlobGasUsed() + require.NoError(t, err) + 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.KzgCommitments) + proofs := [][]byte{bytesutil.PadTo([]byte("proof1"), fieldparams.BLSPubkeyLength), bytesutil.PadTo([]byte("proof2"), fieldparams.BLSPubkeyLength)} + require.DeepEqual(t, proofs, resp.BlobsBundle.Proofs) + blobs := [][]byte{bytesutil.PadTo([]byte("a"), fieldparams.BlobLength), bytesutil.PadTo([]byte("b"), fieldparams.BlobLength)} + require.DeepEqual(t, blobs, resp.BlobsBundle.Blobs) + requests := &pb.ExecutionRequests{ + Deposits: []*pb.DepositRequest{ + { + Pubkey: bytesutil.PadTo([]byte{byte('a')}, fieldparams.BLSPubkeyLength), + WithdrawalCredentials: bytesutil.PadTo([]byte{byte('b')}, fieldparams.RootLength), + Amount: params.BeaconConfig().MinActivationBalance, + Signature: bytesutil.PadTo([]byte{byte('c')}, fieldparams.BLSSignatureLength), + Index: 0, + }, + }, + Withdrawals: []*pb.WithdrawalRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('d')}, common.AddressLength), + ValidatorPubkey: bytesutil.PadTo([]byte{byte('e')}, fieldparams.BLSPubkeyLength), + Amount: params.BeaconConfig().MinActivationBalance, + }, + }, + Consolidations: []*pb.ConsolidationRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('f')}, common.AddressLength), + SourcePubkey: bytesutil.PadTo([]byte{byte('g')}, fieldparams.BLSPubkeyLength), + TargetPubkey: bytesutil.PadTo([]byte{byte('h')}, fieldparams.BLSPubkeyLength), + }, + }, + } + + require.DeepEqual(t, requests, resp.ExecutionRequests) }) t.Run(ForkchoiceUpdatedMethod+" VALID status", func(t *testing.T) { @@ -1313,6 +1392,7 @@ func fixtures() map[string]interface{} { "ExecutionPayloadDeneb": s.ExecutionPayloadDeneb, "ExecutionPayloadCapellaWithValue": s.ExecutionPayloadWithValueCapella, "ExecutionPayloadDenebWithValue": s.ExecutionPayloadWithValueDeneb, + "ExecutionBundleElectra": s.ExecutionBundleElectra, "ValidPayloadStatus": s.ValidPayloadStatus, "InvalidBlockHashStatus": s.InvalidBlockHashStatus, "AcceptedStatus": s.AcceptedStatus, @@ -1499,6 +1579,53 @@ func fixturesStruct() *payloadFixtures { Blobs: []hexutil.Bytes{{'a'}, {'b'}}, }, } + + depositRequestBytes, err := hexutil.Decode("0x610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + + "620000000000000000000000000000000000000000000000000000000000000000" + + "4059730700000063000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + + "00000000000000000000000000000000000000000000000000000000000000000000000000000000") + if err != nil { + panic("failed to decode deposit request") + } + withdrawalRequestBytes, err := hexutil.Decode("0x6400000000000000000000000000000000000000" + + "6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040597307000000") + if err != nil { + panic("failed to decode withdrawal request") + } + consolidationRequestBytes, err := hexutil.Decode("0x6600000000000000000000000000000000000000" + + "670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + + "680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + if err != nil { + panic("failed to decode consolidation request") + } + executionBundleFixtureElectra := &pb.GetPayloadV4ResponseJson{ + 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.BlobBundleJSON{ + Commitments: []hexutil.Bytes{[]byte("commitment1"), []byte("commitment2")}, + Proofs: []hexutil.Bytes{[]byte("proof1"), []byte("proof2")}, + Blobs: []hexutil.Bytes{{'a'}, {'b'}}, + }, + ExecutionRequests: []hexutil.Bytes{depositRequestBytes, withdrawalRequestBytes, consolidationRequestBytes}, + } parent := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength) sha3Uncles := bytesutil.PadTo([]byte("sha3Uncles"), fieldparams.RootLength) miner := bytesutil.PadTo([]byte("miner"), fieldparams.FeeRecipientLength) @@ -1592,6 +1719,7 @@ func fixturesStruct() *payloadFixtures { EmptyExecutionPayloadDeneb: emptyExecutionPayloadDeneb, ExecutionPayloadWithValueCapella: executionPayloadWithValueFixtureCapella, ExecutionPayloadWithValueDeneb: executionPayloadWithValueFixtureDeneb, + ExecutionBundleElectra: executionBundleFixtureElectra, ValidPayloadStatus: validStatus, InvalidBlockHashStatus: inValidBlockHashStatus, AcceptedStatus: acceptedStatus, @@ -1615,6 +1743,7 @@ type payloadFixtures struct { ExecutionPayloadDeneb *pb.ExecutionPayloadDeneb ExecutionPayloadWithValueCapella *pb.GetPayloadV2ResponseJson ExecutionPayloadWithValueDeneb *pb.GetPayloadV3ResponseJson + ExecutionBundleElectra *pb.GetPayloadV4ResponseJson ValidPayloadStatus *pb.PayloadStatus InvalidBlockHashStatus *pb.PayloadStatus AcceptedStatus *pb.PayloadStatus diff --git a/consensus-types/blocks/execution.go b/consensus-types/blocks/execution.go index ee74f18011b4..0c75f1d43128 100644 --- a/consensus-types/blocks/execution.go +++ b/consensus-types/blocks/execution.go @@ -37,6 +37,9 @@ func NewWrappedExecutionData(v proto.Message) (interfaces.ExecutionData, error) return WrappedExecutionPayloadDeneb(pbStruct) case *enginev1.ExecutionPayloadDenebWithValueAndBlobsBundle: return WrappedExecutionPayloadDeneb(pbStruct.Payload) + case *enginev1.ExecutionBundleElectra: + // note: no payload changes in electra so using deneb + return WrappedExecutionPayloadDeneb(pbStruct.Payload) default: return nil, ErrUnsupportedVersion } diff --git a/proto/engine/v1/json_marshal_unmarshal.go b/proto/engine/v1/json_marshal_unmarshal.go index 13ed85726cad..c06b937136d0 100644 --- a/proto/engine/v1/json_marshal_unmarshal.go +++ b/proto/engine/v1/json_marshal_unmarshal.go @@ -297,6 +297,14 @@ type GetPayloadV3ResponseJson struct { ShouldOverrideBuilder bool `json:"shouldOverrideBuilder"` } +type GetPayloadV4ResponseJson struct { + ExecutionPayload *ExecutionPayloadDenebJSON `json:"executionPayload"` + BlockValue string `json:"blockValue"` + BlobsBundle *BlobBundleJSON `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"` @@ -1112,6 +1120,137 @@ func (e *ExecutionPayloadDenebWithValueAndBlobsBundle) UnmarshalJSON(enc []byte) return nil } +func (e *ExecutionBundleElectra) UnmarshalJSON(enc []byte) error { + dec := GetPayloadV4ResponseJson{} + 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 = ExecutionBundleElectra{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 = &BlobsBundle{} + + 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)) diff --git a/proto/engine/v1/json_marshal_unmarshal_test.go b/proto/engine/v1/json_marshal_unmarshal_test.go index 9ce48ac0b680..7070f7ce6c30 100644 --- a/proto/engine/v1/json_marshal_unmarshal_test.go +++ b/proto/engine/v1/json_marshal_unmarshal_test.go @@ -607,6 +607,9 @@ func TestJsonMarshalUnmarshal(t *testing.T) { // Expect no transaction objects in the unmarshaled data. require.Equal(t, 0, len(payloadPb.Transactions)) }) + t.Run("execution bundle electra with deneb payload, blob data, and execution requests", func(t *testing.T) { + //TODO: add in test for electra + }) } func TestPayloadIDBytes_MarshalUnmarshalJSON(t *testing.T) { From 8362871c9a66d6e592559960d94b024399171586 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Mon, 14 Oct 2024 15:40:58 -0500 Subject: [PATCH 19/26] added tests for execution client testing, fixed encode type --- beacon-chain/execution/engine_client_test.go | 199 ++++++++++++++++++- proto/engine/v1/electra.go | 9 +- 2 files changed, 201 insertions(+), 7 deletions(-) diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index c7adbe4629d0..ea21423dea79 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -586,7 +586,43 @@ func TestClient_HTTP(t *testing.T) { require.DeepEqual(t, want.LatestValidHash, resp) }) t.Run(NewPayloadMethodV4+" VALID status", func(t *testing.T) { - // TODO: add electra test + execPayload, ok := fix["ExecutionPayloadDeneb"].(*pb.ExecutionPayloadDeneb) + require.Equal(t, true, ok) + want, ok := fix["ValidPayloadStatus"].(*pb.PayloadStatus) + require.Equal(t, true, ok) + + // We call the RPC method via HTTP and expect a proper result. + wrappedPayload, err := blocks.WrappedExecutionPayloadDeneb(execPayload) + require.NoError(t, err) + requests := &pb.ExecutionRequests{ + Deposits: []*pb.DepositRequest{ + { + Pubkey: bytesutil.PadTo([]byte{byte('a')}, fieldparams.BLSPubkeyLength), + WithdrawalCredentials: bytesutil.PadTo([]byte{byte('b')}, fieldparams.RootLength), + Amount: params.BeaconConfig().MinActivationBalance, + Signature: bytesutil.PadTo([]byte{byte('c')}, fieldparams.BLSSignatureLength), + Index: 0, + }, + }, + Withdrawals: []*pb.WithdrawalRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('d')}, common.AddressLength), + ValidatorPubkey: bytesutil.PadTo([]byte{byte('e')}, fieldparams.BLSPubkeyLength), + Amount: params.BeaconConfig().MinActivationBalance, + }, + }, + Consolidations: []*pb.ConsolidationRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('f')}, common.AddressLength), + SourcePubkey: bytesutil.PadTo([]byte{byte('g')}, fieldparams.BLSPubkeyLength), + TargetPubkey: bytesutil.PadTo([]byte{byte('h')}, fieldparams.BLSPubkeyLength), + }, + }, + } + client := newPayloadV4Setup(t, want, execPayload, requests) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, requests) + require.NoError(t, err) + require.DeepEqual(t, want.LatestValidHash, resp) }) t.Run(NewPayloadMethod+" SYNCING status", func(t *testing.T) { execPayload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload) @@ -631,7 +667,43 @@ func TestClient_HTTP(t *testing.T) { require.DeepEqual(t, []uint8(nil), resp) }) t.Run(NewPayloadMethodV4+" SYNCING status", func(t *testing.T) { - // TODO: add a test for PayloadV4 Requests + execPayload, ok := fix["ExecutionPayloadDeneb"].(*pb.ExecutionPayloadDeneb) + require.Equal(t, true, ok) + want, ok := fix["SyncingStatus"].(*pb.PayloadStatus) + require.Equal(t, true, ok) + + // We call the RPC method via HTTP and expect a proper result. + wrappedPayload, err := blocks.WrappedExecutionPayloadDeneb(execPayload) + require.NoError(t, err) + requests := &pb.ExecutionRequests{ + Deposits: []*pb.DepositRequest{ + { + Pubkey: bytesutil.PadTo([]byte{byte('a')}, fieldparams.BLSPubkeyLength), + WithdrawalCredentials: bytesutil.PadTo([]byte{byte('b')}, fieldparams.RootLength), + Amount: params.BeaconConfig().MinActivationBalance, + Signature: bytesutil.PadTo([]byte{byte('c')}, fieldparams.BLSSignatureLength), + Index: 0, + }, + }, + Withdrawals: []*pb.WithdrawalRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('d')}, common.AddressLength), + ValidatorPubkey: bytesutil.PadTo([]byte{byte('e')}, fieldparams.BLSPubkeyLength), + Amount: params.BeaconConfig().MinActivationBalance, + }, + }, + Consolidations: []*pb.ConsolidationRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('f')}, common.AddressLength), + SourcePubkey: bytesutil.PadTo([]byte{byte('g')}, fieldparams.BLSPubkeyLength), + TargetPubkey: bytesutil.PadTo([]byte{byte('h')}, fieldparams.BLSPubkeyLength), + }, + }, + } + client := newPayloadV4Setup(t, want, execPayload, requests) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, requests) + require.ErrorIs(t, ErrAcceptedSyncingPayloadStatus, err) + require.DeepEqual(t, []uint8(nil), resp) }) t.Run(NewPayloadMethod+" INVALID_BLOCK_HASH status", func(t *testing.T) { execPayload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload) @@ -676,7 +748,42 @@ func TestClient_HTTP(t *testing.T) { require.DeepEqual(t, []uint8(nil), resp) }) t.Run(NewPayloadMethodV4+" INVALID_BLOCK_HASH status", func(t *testing.T) { - // TODO: add a test for PayloadV4 Requests + execPayload, ok := fix["ExecutionPayloadDeneb"].(*pb.ExecutionPayloadDeneb) + require.Equal(t, true, ok) + want, ok := fix["InvalidBlockHashStatus"].(*pb.PayloadStatus) + require.Equal(t, true, ok) + // We call the RPC method via HTTP and expect a proper result. + wrappedPayload, err := blocks.WrappedExecutionPayloadDeneb(execPayload) + require.NoError(t, err) + requests := &pb.ExecutionRequests{ + Deposits: []*pb.DepositRequest{ + { + Pubkey: bytesutil.PadTo([]byte{byte('a')}, fieldparams.BLSPubkeyLength), + WithdrawalCredentials: bytesutil.PadTo([]byte{byte('b')}, fieldparams.RootLength), + Amount: params.BeaconConfig().MinActivationBalance, + Signature: bytesutil.PadTo([]byte{byte('c')}, fieldparams.BLSSignatureLength), + Index: 0, + }, + }, + Withdrawals: []*pb.WithdrawalRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('d')}, common.AddressLength), + ValidatorPubkey: bytesutil.PadTo([]byte{byte('e')}, fieldparams.BLSPubkeyLength), + Amount: params.BeaconConfig().MinActivationBalance, + }, + }, + Consolidations: []*pb.ConsolidationRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('f')}, common.AddressLength), + SourcePubkey: bytesutil.PadTo([]byte{byte('g')}, fieldparams.BLSPubkeyLength), + TargetPubkey: bytesutil.PadTo([]byte{byte('h')}, fieldparams.BLSPubkeyLength), + }, + }, + } + client := newPayloadV4Setup(t, want, execPayload, requests) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, requests) + require.ErrorIs(t, ErrInvalidBlockHashPayloadStatus, err) + require.DeepEqual(t, []uint8(nil), resp) }) t.Run(NewPayloadMethod+" INVALID status", func(t *testing.T) { execPayload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload) @@ -721,7 +828,43 @@ func TestClient_HTTP(t *testing.T) { require.DeepEqual(t, want.LatestValidHash, resp) }) t.Run(NewPayloadMethodV4+" INVALID status", func(t *testing.T) { - // TODO: add a test for PayloadV4 Requests + execPayload, ok := fix["ExecutionPayloadDeneb"].(*pb.ExecutionPayloadDeneb) + require.Equal(t, true, ok) + want, ok := fix["InvalidStatus"].(*pb.PayloadStatus) + require.Equal(t, true, ok) + + // We call the RPC method via HTTP and expect a proper result. + wrappedPayload, err := blocks.WrappedExecutionPayloadDeneb(execPayload) + require.NoError(t, err) + requests := &pb.ExecutionRequests{ + Deposits: []*pb.DepositRequest{ + { + Pubkey: bytesutil.PadTo([]byte{byte('a')}, fieldparams.BLSPubkeyLength), + WithdrawalCredentials: bytesutil.PadTo([]byte{byte('b')}, fieldparams.RootLength), + Amount: params.BeaconConfig().MinActivationBalance, + Signature: bytesutil.PadTo([]byte{byte('c')}, fieldparams.BLSSignatureLength), + Index: 0, + }, + }, + Withdrawals: []*pb.WithdrawalRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('d')}, common.AddressLength), + ValidatorPubkey: bytesutil.PadTo([]byte{byte('e')}, fieldparams.BLSPubkeyLength), + Amount: params.BeaconConfig().MinActivationBalance, + }, + }, + Consolidations: []*pb.ConsolidationRequest{ + { + SourceAddress: bytesutil.PadTo([]byte{byte('f')}, common.AddressLength), + SourcePubkey: bytesutil.PadTo([]byte{byte('g')}, fieldparams.BLSPubkeyLength), + TargetPubkey: bytesutil.PadTo([]byte{byte('h')}, fieldparams.BLSPubkeyLength), + }, + }, + } + client := newPayloadV4Setup(t, want, execPayload, requests) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, nil) + require.ErrorIs(t, ErrInvalidPayloadStatus, err) + require.DeepEqual(t, want.LatestValidHash, resp) }) t.Run(NewPayloadMethod+" UNKNOWN status", func(t *testing.T) { execPayload, ok := fix["ExecutionPayload"].(*pb.ExecutionPayload) @@ -2102,6 +2245,54 @@ func newPayloadV3Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.Execu return service } +func newPayloadV4Setup(t *testing.T, status *pb.PayloadStatus, payload *pb.ExecutionPayloadDeneb, requests *pb.ExecutionRequests) *Service { + 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()) + }() + enc, err := io.ReadAll(r.Body) + require.NoError(t, err) + jsonRequestString := string(enc) + require.Equal(t, true, strings.Contains( + jsonRequestString, string("engine_newPayloadV4"), + )) + + reqPayload, err := json.Marshal(payload) + require.NoError(t, err) + + // We expect the JSON string RPC request contains the right arguments. + require.Equal(t, true, strings.Contains( + jsonRequestString, string(reqPayload), + )) + + reqRequests, err := pb.EncodeExecutionRequests(requests) + require.NoError(t, err) + + jsonRequests, err := json.Marshal(reqRequests) + require.NoError(t, err) + + require.Equal(t, true, strings.Contains( + jsonRequestString, string(jsonRequests), + )) + + resp := map[string]interface{}{ + "jsonrpc": "2.0", + "id": 1, + "result": status, + } + err = json.NewEncoder(w).Encode(resp) + require.NoError(t, err) + })) + + rpcClient, err := rpc.DialHTTP(srv.URL) + require.NoError(t, err) + + service := &Service{} + service.rpcClient = rpcClient + return service +} + func TestReconstructBlindedBlockBatch(t *testing.T) { t.Run("empty response works", func(t *testing.T) { ctx := context.Background() diff --git a/proto/engine/v1/electra.go b/proto/engine/v1/electra.go index f30615b38049..f77dd35bc4ba 100644 --- a/proto/engine/v1/electra.go +++ b/proto/engine/v1/electra.go @@ -3,6 +3,7 @@ package enginev1 import ( "fmt" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" ) @@ -18,10 +19,12 @@ var ( crSize = crExample.SizeSSZ() ) +const LenExecutionRequestsElectra = 3 + func (eee *ExecutionBundleElectra) GetDecodedExecutionRequests() (*ExecutionRequests, error) { requests := &ExecutionRequests{} - if len(eee.ExecutionRequests) != 3 /* types of requests */ { + if len(eee.ExecutionRequests) != LenExecutionRequestsElectra /* types of requests */ { return nil, errors.Errorf("invalid execution request size: %d", len(eee.ExecutionRequests)) } @@ -49,7 +52,7 @@ func (eee *ExecutionBundleElectra) GetDecodedExecutionRequests() (*ExecutionRequ return requests, nil } -func EncodeExecutionRequests(requests *ExecutionRequests) ([][]byte, error) { +func EncodeExecutionRequests(requests *ExecutionRequests) ([]hexutil.Bytes, error) { if requests == nil { return nil, errors.New("invalid execution requests") } @@ -68,7 +71,7 @@ func EncodeExecutionRequests(requests *ExecutionRequests) ([][]byte, error) { if err != nil { return nil, errors.Wrap(err, "failed to marshal consolidation requests") } - return [][]byte{drBytes, wrBytes, crBytes}, nil + return []hexutil.Bytes{drBytes, wrBytes, crBytes}, nil } type sszUnmarshaler interface { From 43e01c4b2255fdd040f4cf5a3d02ad89e372af59 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Mon, 14 Oct 2024 15:54:00 -0500 Subject: [PATCH 20/26] adding comment for placeholder test --- proto/engine/v1/json_marshal_unmarshal_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto/engine/v1/json_marshal_unmarshal_test.go b/proto/engine/v1/json_marshal_unmarshal_test.go index 7070f7ce6c30..a3104f42fef9 100644 --- a/proto/engine/v1/json_marshal_unmarshal_test.go +++ b/proto/engine/v1/json_marshal_unmarshal_test.go @@ -608,7 +608,7 @@ func TestJsonMarshalUnmarshal(t *testing.T) { require.Equal(t, 0, len(payloadPb.Transactions)) }) t.Run("execution bundle electra with deneb payload, blob data, and execution requests", func(t *testing.T) { - //TODO: add in test for electra + // TODO #14351: update this test when geth updates }) } From f7ef1f3b84fd93c219383d21237ad29eb7620b6c Mon Sep 17 00:00:00 2001 From: james-prysm Date: Mon, 14 Oct 2024 16:02:09 -0500 Subject: [PATCH 21/26] fixing test and addressing feedback --- beacon-chain/blockchain/execution_engine.go | 24 ++++++++------------ beacon-chain/execution/engine_client_test.go | 2 +- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/beacon-chain/blockchain/execution_engine.go b/beacon-chain/blockchain/execution_engine.go index a5d69ecf4a2d..ab68de103240 100644 --- a/beacon-chain/blockchain/execution_engine.go +++ b/beacon-chain/blockchain/execution_engine.go @@ -216,29 +216,23 @@ func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion int, } var lastValidHash []byte - switch { - case blk.Version() >= version.Electra: + if blk.Version() >= version.Deneb { var versionedHashes []common.Hash - versionedHashes, err = kzgCommitmentsToVersionedHashes(blk.Block().Body()) - if err != nil { - return false, errors.Wrap(err, "could not get versioned hashes to feed the engine") - } - pr := common.Hash(blk.Block().ParentRoot()) var requests *enginev1.ExecutionRequests - requests, err = blk.Block().Body().ExecutionRequests() - if err != nil { - return false, errors.Wrap(err, "could not get execution requests") + + if blk.Version() >= version.Electra { + requests, err = blk.Block().Body().ExecutionRequests() + if err != nil { + return false, errors.Wrap(err, "could not get execution requests") + } } - lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr, requests) - case blk.Version() >= version.Deneb: - var versionedHashes []common.Hash versionedHashes, err = kzgCommitmentsToVersionedHashes(blk.Block().Body()) if err != nil { return false, errors.Wrap(err, "could not get versioned hashes to feed the engine") } pr := common.Hash(blk.Block().ParentRoot()) - lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr, nil) - default: + lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr, requests) + } else { lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, []common.Hash{}, &common.Hash{} /*empty version hashes and root before Deneb*/, nil) } switch { diff --git a/beacon-chain/execution/engine_client_test.go b/beacon-chain/execution/engine_client_test.go index ea21423dea79..9406543ccb20 100644 --- a/beacon-chain/execution/engine_client_test.go +++ b/beacon-chain/execution/engine_client_test.go @@ -862,7 +862,7 @@ func TestClient_HTTP(t *testing.T) { }, } client := newPayloadV4Setup(t, want, execPayload, requests) - resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, nil) + resp, err := client.NewPayload(ctx, wrappedPayload, []common.Hash{}, &common.Hash{'a'}, requests) require.ErrorIs(t, ErrInvalidPayloadStatus, err) require.DeepEqual(t, want.LatestValidHash, resp) }) From 9cc52a3a9d30925b9e49ce439af17f60a2e1c435 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Tue, 15 Oct 2024 15:16:44 -0500 Subject: [PATCH 22/26] feedback --- beacon-chain/blockchain/execution_engine.go | 26 ++++++++++----------- consensus-types/blocks/setters.go | 4 ++-- proto/engine/v1/electra.go | 12 +++++----- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/beacon-chain/blockchain/execution_engine.go b/beacon-chain/blockchain/execution_engine.go index ab68de103240..0317098b0923 100644 --- a/beacon-chain/blockchain/execution_engine.go +++ b/beacon-chain/blockchain/execution_engine.go @@ -216,25 +216,25 @@ func (s *Service) notifyNewPayload(ctx context.Context, preStateVersion int, } var lastValidHash []byte + var parentRoot *common.Hash + var versionedHashes []common.Hash + var requests *enginev1.ExecutionRequests if blk.Version() >= version.Deneb { - var versionedHashes []common.Hash - var requests *enginev1.ExecutionRequests - - if blk.Version() >= version.Electra { - requests, err = blk.Block().Body().ExecutionRequests() - if err != nil { - return false, errors.Wrap(err, "could not get execution requests") - } - } versionedHashes, err = kzgCommitmentsToVersionedHashes(blk.Block().Body()) if err != nil { return false, errors.Wrap(err, "could not get versioned hashes to feed the engine") } - pr := common.Hash(blk.Block().ParentRoot()) - lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, &pr, requests) - } else { - lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, []common.Hash{}, &common.Hash{} /*empty version hashes and root before Deneb*/, nil) + prh := common.Hash(blk.Block().ParentRoot()) + parentRoot = &prh } + if blk.Version() >= version.Electra { + requests, err = blk.Block().Body().ExecutionRequests() + if err != nil { + return false, errors.Wrap(err, "could not get execution requests") + } + } + lastValidHash, err = s.cfg.ExecutionEngineCaller.NewPayload(ctx, payload, versionedHashes, parentRoot, requests) + switch { case err == nil: newPayloadValidNodeCount.Inc() diff --git a/consensus-types/blocks/setters.go b/consensus-types/blocks/setters.go index a3eac1e54658..a2f376c76c0f 100644 --- a/consensus-types/blocks/setters.go +++ b/consensus-types/blocks/setters.go @@ -175,10 +175,10 @@ func (b *SignedBeaconBlock) SetBlobKzgCommitments(c [][]byte) error { } // SetExecutionRequests sets the execution requests in the block. -func (b *SignedBeaconBlock) SetExecutionRequests(er *enginev1.ExecutionRequests) error { +func (b *SignedBeaconBlock) SetExecutionRequests(req *enginev1.ExecutionRequests) error { if b.version < version.Electra { return consensus_types.ErrNotSupported("SetExecutionRequests", b.version) } - b.block.body.executionRequests = er + b.block.body.executionRequests = req return nil } diff --git a/proto/engine/v1/electra.go b/proto/engine/v1/electra.go index f77dd35bc4ba..55c40b03860f 100644 --- a/proto/engine/v1/electra.go +++ b/proto/engine/v1/electra.go @@ -21,29 +21,29 @@ var ( const LenExecutionRequestsElectra = 3 -func (eee *ExecutionBundleElectra) GetDecodedExecutionRequests() (*ExecutionRequests, error) { +func (ebe *ExecutionBundleElectra) GetDecodedExecutionRequests() (*ExecutionRequests, error) { requests := &ExecutionRequests{} - if len(eee.ExecutionRequests) != LenExecutionRequestsElectra /* types of requests */ { - return nil, errors.Errorf("invalid execution request size: %d", len(eee.ExecutionRequests)) + if len(ebe.ExecutionRequests) != LenExecutionRequestsElectra /* types of requests */ { + return nil, errors.Errorf("invalid execution request size: %d", len(ebe.ExecutionRequests)) } // deposit requests - drs, err := unmarshalItems(eee.ExecutionRequests[0], drSize, func() *DepositRequest { return &DepositRequest{} }) + drs, err := unmarshalItems(ebe.ExecutionRequests[0], drSize, func() *DepositRequest { return &DepositRequest{} }) if err != nil { return nil, err } requests.Deposits = drs // withdrawal requests - wrs, err := unmarshalItems(eee.ExecutionRequests[1], wrSize, func() *WithdrawalRequest { return &WithdrawalRequest{} }) + wrs, err := unmarshalItems(ebe.ExecutionRequests[1], wrSize, func() *WithdrawalRequest { return &WithdrawalRequest{} }) if err != nil { return nil, err } requests.Withdrawals = wrs // consolidation requests - crs, err := unmarshalItems(eee.ExecutionRequests[2], crSize, func() *ConsolidationRequest { return &ConsolidationRequest{} }) + crs, err := unmarshalItems(ebe.ExecutionRequests[2], crSize, func() *ConsolidationRequest { return &ConsolidationRequest{} }) if err != nil { return nil, err } From ad564800a605ec4ba642839dd5f52d711c7cd005 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Tue, 15 Oct 2024 16:04:14 -0500 Subject: [PATCH 23/26] flipping the test names, was used in reverse --- proto/engine/v1/electra_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proto/engine/v1/electra_test.go b/proto/engine/v1/electra_test.go index 15f7f88f0e7a..2d4c9903b98f 100644 --- a/proto/engine/v1/electra_test.go +++ b/proto/engine/v1/electra_test.go @@ -11,7 +11,7 @@ import ( var depositRequestsSSZHex = "0x706b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077630000000000000000000000000000000000000000000000000000000000007b00000000000000736967000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c801000000000000706b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000776300000000000000000000000000000000000000000000000000000000000090010000000000007369670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000" -func TestMarshalItems_OK(t *testing.T) { +func TestUnmarshalItems_OK(t *testing.T) { drb, err := hexutil.Decode(depositRequestsSSZHex) require.NoError(t, err) exampleRequest := &enginev1.DepositRequest{} @@ -35,7 +35,7 @@ func TestMarshalItems_OK(t *testing.T) { require.DeepEqual(t, depositRequests, []*enginev1.DepositRequest{exampleRequest1, exampleRequest2}) } -func TestUnmarshalItems_OK(t *testing.T) { +func TestMarshalItems_OK(t *testing.T) { exampleRequest1 := &enginev1.DepositRequest{ Pubkey: bytesutil.PadTo([]byte("pk"), 48), WithdrawalCredentials: bytesutil.PadTo([]byte("wc"), 32), From 5f95c3dd865cc2525d075c26c791357acc5249ce Mon Sep 17 00:00:00 2001 From: james-prysm Date: Tue, 15 Oct 2024 16:26:53 -0500 Subject: [PATCH 24/26] feedback from kasey --- proto/engine/v1/electra.go | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/proto/engine/v1/electra.go b/proto/engine/v1/electra.go index 55c40b03860f..90d003ec2a7d 100644 --- a/proto/engine/v1/electra.go +++ b/proto/engine/v1/electra.go @@ -79,27 +79,24 @@ type sszUnmarshaler interface { } type sszMarshaler interface { - MarshalSSZ() ([]byte, error) + MarshalSSZTo(buf []byte) ([]byte, error) + SizeSSZ() int } func marshalItems[T sszMarshaler](items []T) ([]byte, error) { - var totalSize int - marshaledItems := make([][]byte, len(items)) + if len(items) == 0 { + return []byte{}, nil + } + size := items[0].SizeSSZ() + buf := make([]byte, 0, size*len(items)) + var err error for i, item := range items { - bytes, err := item.MarshalSSZ() + buf, err = item.MarshalSSZTo(buf) if err != nil { return nil, fmt.Errorf("failed to marshal item at index %d: %w", i, err) } - marshaledItems[i] = bytes - totalSize += len(bytes) - } - - result := make([]byte, totalSize) - - for i, bytes := range marshaledItems { - copy(result[i*len(bytes):(i+1)*len(bytes)], bytes) } - return result, nil + return buf, nil } // Generic function to unmarshal items From 0580bb5caf1ee9e18740ad946c2bfc1df9e336df Mon Sep 17 00:00:00 2001 From: james-prysm Date: Wed, 16 Oct 2024 14:29:23 -0500 Subject: [PATCH 25/26] reverting switch back to if statements to fix bug --- beacon-chain/execution/engine_client.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 0a7af56ec0ef..1da3249de4a8 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -264,16 +264,17 @@ func (s *Service) ForkchoiceUpdated( func getPayloadMethodAndMessage(slot primitives.Slot) (string, proto.Message) { pe := slots.ToEpoch(slot) - switch { - case pe >= params.BeaconConfig().ElectraForkEpoch: + if pe >= params.BeaconConfig().ElectraForkEpoch { return GetPayloadMethodV4, &pb.ExecutionBundleElectra{} - case pe == params.BeaconConfig().DenebForkEpoch: + } + if pe >= params.BeaconConfig().DenebForkEpoch { return GetPayloadMethodV3, &pb.ExecutionPayloadDenebWithValueAndBlobsBundle{} - case pe == params.BeaconConfig().CapellaForkEpoch: + } + if pe >= params.BeaconConfig().CapellaForkEpoch { return GetPayloadMethodV2, &pb.ExecutionPayloadCapellaWithValue{} - default: - return GetPayloadMethod, &pb.ExecutionPayload{} } + return GetPayloadMethod, &pb.ExecutionPayload{} + } // GetPayload calls the engine_getPayloadVX method via JSON-RPC. From 2ffb01b14089385be63fb799ea1ae47094fde424 Mon Sep 17 00:00:00 2001 From: james-prysm Date: Wed, 16 Oct 2024 14:35:55 -0500 Subject: [PATCH 26/26] lint --- beacon-chain/execution/engine_client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/beacon-chain/execution/engine_client.go b/beacon-chain/execution/engine_client.go index 1da3249de4a8..2dfc479f4214 100644 --- a/beacon-chain/execution/engine_client.go +++ b/beacon-chain/execution/engine_client.go @@ -274,7 +274,6 @@ func getPayloadMethodAndMessage(slot primitives.Slot) (string, proto.Message) { return GetPayloadMethodV2, &pb.ExecutionPayloadCapellaWithValue{} } return GetPayloadMethod, &pb.ExecutionPayload{} - } // GetPayload calls the engine_getPayloadVX method via JSON-RPC.