From eef2122a9e2e3910e313d439dde43653c53efed2 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Mon, 31 Jan 2022 20:47:34 -0500 Subject: [PATCH] Engine API Protobuf Definitions (#10150) * define proto types for engine api * proto lint * prettify * build bazel * generated pb * txs field * regen * ssz gen marshal * fastssz * ssz * fmt * json marshal unmarshal custom * exec json tests * passing tests * deepsource * gaz * gaz * deps * ssz max * regen proto * regen ssz --- proto/engine/v1/BUILD.bazel | 92 +++ proto/engine/v1/execution_engine.pb.go | 623 ++++++++++++++++++ proto/engine/v1/execution_engine.proto | 68 ++ proto/engine/v1/generated.ssz.go | 380 +++++++++++ proto/engine/v1/json_marshal_unmarshal.go | 47 ++ .../engine/v1/json_marshal_unmarshal_test.go | 93 +++ 6 files changed, 1303 insertions(+) create mode 100644 proto/engine/v1/BUILD.bazel create mode 100755 proto/engine/v1/execution_engine.pb.go create mode 100644 proto/engine/v1/execution_engine.proto create mode 100755 proto/engine/v1/generated.ssz.go create mode 100644 proto/engine/v1/json_marshal_unmarshal.go create mode 100644 proto/engine/v1/json_marshal_unmarshal_test.go diff --git a/proto/engine/v1/BUILD.bazel b/proto/engine/v1/BUILD.bazel new file mode 100644 index 0000000000..14e209e137 --- /dev/null +++ b/proto/engine/v1/BUILD.bazel @@ -0,0 +1,92 @@ +############################################################################## +# Common +############################################################################## + +load("@rules_proto//proto:defs.bzl", "proto_library") + +############################################################################## +# Go +############################################################################## +# gazelle:ignore +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") +load("//proto:ssz_proto_library.bzl", "ssz_proto_files") +load("//tools:ssz.bzl", "SSZ_DEPS", "ssz_gen_marshal") + +proto_library( + name = "proto", + srcs = [ + "execution_engine.proto", + ], + visibility = ["//visibility:public"], + deps = [ + "//proto/eth/ext:proto", + "@go_googleapis//google/api:annotations_proto", + ], +) + +############################################################################## +# Go +############################################################################## +ssz_gen_marshal( + name = "ssz_generated_files", + go_proto = ":go_proto", + objs = [ + "ExecutionPayload", + ], +) + +go_proto_library( + name = "go_proto", + compilers = [ + "@com_github_prysmaticlabs_protoc_gen_go_cast//:go_cast_grpc", + ], + importpath = "github.com/prysmaticlabs/prysm/proto/engine/v1", + proto = ":proto", + visibility = ["//visibility:public"], + deps = [ + "//proto/eth/ext:go_default_library", + "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", + "@com_github_golang_protobuf//proto:go_default_library", + "@com_github_prysmaticlabs_eth2_types//:go_default_library", + "@go_googleapis//google/api:annotations_go_proto", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + ], +) + +go_library( + name = "go_default_library", + srcs = [ + "json_marshal_unmarshal.go", + ":ssz_generated_files", # keep + ], + embed = [ + ":go_proto", + ], + importpath = "github.com/prysmaticlabs/prysm/proto/engine/v1", + visibility = ["//visibility:public"], + deps = [ + "//proto/eth/ext:go_default_library", + "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", + "@com_github_golang_protobuf//proto:go_default_library", + "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", + "@go_googleapis//google/api:annotations_go_proto", + "@org_golang_google_protobuf//encoding/protojson:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + "@com_github_ferranbt_fastssz//:go_default_library" + ], # keep +) + +go_test( + name = "go_default_test", + srcs = [ + "json_marshal_unmarshal_test.go", + ], + deps = [ + "//encoding/bytesutil:go_default_library", + "//testing/require:go_default_library", + ], + embed = [":go_default_library"], +) diff --git a/proto/engine/v1/execution_engine.pb.go b/proto/engine/v1/execution_engine.pb.go new file mode 100755 index 0000000000..d06f31ea63 --- /dev/null +++ b/proto/engine/v1/execution_engine.pb.go @@ -0,0 +1,623 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.15.8 +// source: proto/engine/v1/execution_engine.proto + +package enginev1 + +import ( + reflect "reflect" + sync "sync" + + _ "github.com/prysmaticlabs/prysm/proto/eth/ext" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PayloadStatus_Status int32 + +const ( + PayloadStatus_VALID PayloadStatus_Status = 0 + PayloadStatus_INVALID PayloadStatus_Status = 1 + PayloadStatus_SYNCING PayloadStatus_Status = 2 + PayloadStatus_ACCEPTED PayloadStatus_Status = 3 + PayloadStatus_INVALID_BLOCK_HASH PayloadStatus_Status = 4 + PayloadStatus_INVALID_TERMINAL_BLOCK PayloadStatus_Status = 5 +) + +// Enum value maps for PayloadStatus_Status. +var ( + PayloadStatus_Status_name = map[int32]string{ + 0: "VALID", + 1: "INVALID", + 2: "SYNCING", + 3: "ACCEPTED", + 4: "INVALID_BLOCK_HASH", + 5: "INVALID_TERMINAL_BLOCK", + } + PayloadStatus_Status_value = map[string]int32{ + "VALID": 0, + "INVALID": 1, + "SYNCING": 2, + "ACCEPTED": 3, + "INVALID_BLOCK_HASH": 4, + "INVALID_TERMINAL_BLOCK": 5, + } +) + +func (x PayloadStatus_Status) Enum() *PayloadStatus_Status { + p := new(PayloadStatus_Status) + *p = x + return p +} + +func (x PayloadStatus_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PayloadStatus_Status) Descriptor() protoreflect.EnumDescriptor { + return file_proto_engine_v1_execution_engine_proto_enumTypes[0].Descriptor() +} + +func (PayloadStatus_Status) Type() protoreflect.EnumType { + return &file_proto_engine_v1_execution_engine_proto_enumTypes[0] +} + +func (x PayloadStatus_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PayloadStatus_Status.Descriptor instead. +func (PayloadStatus_Status) EnumDescriptor() ([]byte, []int) { + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{2, 0} +} + +type ExecutionPayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ParentHash []byte `protobuf:"bytes,1,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty" ssz-size:"32"` + FeeRecipient []byte `protobuf:"bytes,2,opt,name=fee_recipient,json=feeRecipient,proto3" json:"fee_recipient,omitempty" ssz-size:"20"` + StateRoot []byte `protobuf:"bytes,3,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty" ssz-size:"32"` + RecipientsRoot []byte `protobuf:"bytes,4,opt,name=recipients_root,json=recipientsRoot,proto3" json:"recipients_root,omitempty" ssz-size:"32"` + LogsBloom []byte `protobuf:"bytes,5,opt,name=logs_bloom,json=logsBloom,proto3" json:"logs_bloom,omitempty" ssz-size:"256"` + Random []byte `protobuf:"bytes,6,opt,name=random,proto3" json:"random,omitempty" ssz-size:"32"` + BlockNumber uint64 `protobuf:"varint,7,opt,name=block_number,json=blockNumber,proto3" json:"block_number,omitempty"` + GasLimit uint64 `protobuf:"varint,8,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` + GasUsed uint64 `protobuf:"varint,9,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` + Timestamp uint64 `protobuf:"varint,10,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + ExtraData []byte `protobuf:"bytes,11,opt,name=extra_data,json=extraData,proto3" json:"extra_data,omitempty" ssz-max:"32"` + BaseFeePerGas []byte `protobuf:"bytes,12,opt,name=base_fee_per_gas,json=baseFeePerGas,proto3" json:"base_fee_per_gas,omitempty" ssz-size:"32"` + BlockHash []byte `protobuf:"bytes,13,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty" ssz-size:"32"` + Transactions [][]byte `protobuf:"bytes,14,rep,name=transactions,proto3" json:"transactions,omitempty" ssz-max:"1048576,1073741824" ssz-size:"?,?"` +} + +func (x *ExecutionPayload) Reset() { + *x = ExecutionPayload{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutionPayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionPayload) ProtoMessage() {} + +func (x *ExecutionPayload) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutionPayload.ProtoReflect.Descriptor instead. +func (*ExecutionPayload) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{0} +} + +func (x *ExecutionPayload) GetParentHash() []byte { + if x != nil { + return x.ParentHash + } + return nil +} + +func (x *ExecutionPayload) GetFeeRecipient() []byte { + if x != nil { + return x.FeeRecipient + } + return nil +} + +func (x *ExecutionPayload) GetStateRoot() []byte { + if x != nil { + return x.StateRoot + } + return nil +} + +func (x *ExecutionPayload) GetRecipientsRoot() []byte { + if x != nil { + return x.RecipientsRoot + } + return nil +} + +func (x *ExecutionPayload) GetLogsBloom() []byte { + if x != nil { + return x.LogsBloom + } + return nil +} + +func (x *ExecutionPayload) GetRandom() []byte { + if x != nil { + return x.Random + } + return nil +} + +func (x *ExecutionPayload) GetBlockNumber() uint64 { + if x != nil { + return x.BlockNumber + } + return 0 +} + +func (x *ExecutionPayload) GetGasLimit() uint64 { + if x != nil { + return x.GasLimit + } + return 0 +} + +func (x *ExecutionPayload) GetGasUsed() uint64 { + if x != nil { + return x.GasUsed + } + return 0 +} + +func (x *ExecutionPayload) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *ExecutionPayload) GetExtraData() []byte { + if x != nil { + return x.ExtraData + } + return nil +} + +func (x *ExecutionPayload) GetBaseFeePerGas() []byte { + if x != nil { + return x.BaseFeePerGas + } + return nil +} + +func (x *ExecutionPayload) GetBlockHash() []byte { + if x != nil { + return x.BlockHash + } + return nil +} + +func (x *ExecutionPayload) GetTransactions() [][]byte { + if x != nil { + return x.Transactions + } + return nil +} + +type PayloadAttributes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Timestamp uint64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Random []byte `protobuf:"bytes,2,opt,name=random,proto3" json:"random,omitempty" ssz-size:"32"` + SuggestedFeeRecipient []byte `protobuf:"bytes,3,opt,name=suggested_fee_recipient,json=suggestedFeeRecipient,proto3" json:"suggested_fee_recipient,omitempty" ssz-size:"20"` +} + +func (x *PayloadAttributes) Reset() { + *x = PayloadAttributes{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PayloadAttributes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PayloadAttributes) ProtoMessage() {} + +func (x *PayloadAttributes) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[1] + 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 PayloadAttributes.ProtoReflect.Descriptor instead. +func (*PayloadAttributes) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{1} +} + +func (x *PayloadAttributes) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *PayloadAttributes) GetRandom() []byte { + if x != nil { + return x.Random + } + return nil +} + +func (x *PayloadAttributes) GetSuggestedFeeRecipient() []byte { + if x != nil { + return x.SuggestedFeeRecipient + } + return nil +} + +type PayloadStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status PayloadStatus_Status `protobuf:"varint,1,opt,name=status,proto3,enum=ethereum.engine.v1.PayloadStatus_Status" json:"status,omitempty"` + LatestValidHash []byte `protobuf:"bytes,2,opt,name=latest_valid_hash,json=latestValidHash,proto3" json:"latest_valid_hash,omitempty" ssz-size:"32"` + ValidationError string `protobuf:"bytes,3,opt,name=validation_error,json=validationError,proto3" json:"validation_error,omitempty"` +} + +func (x *PayloadStatus) Reset() { + *x = PayloadStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PayloadStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PayloadStatus) ProtoMessage() {} + +func (x *PayloadStatus) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[2] + 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 PayloadStatus.ProtoReflect.Descriptor instead. +func (*PayloadStatus) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{2} +} + +func (x *PayloadStatus) GetStatus() PayloadStatus_Status { + if x != nil { + return x.Status + } + return PayloadStatus_VALID +} + +func (x *PayloadStatus) GetLatestValidHash() []byte { + if x != nil { + return x.LatestValidHash + } + return nil +} + +func (x *PayloadStatus) GetValidationError() string { + if x != nil { + return x.ValidationError + } + return "" +} + +type ForkchoiceState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + HeadBlockHash []byte `protobuf:"bytes,1,opt,name=head_block_hash,json=headBlockHash,proto3" json:"head_block_hash,omitempty" ssz-size:"32"` + SafeBlockHash []byte `protobuf:"bytes,2,opt,name=safe_block_hash,json=safeBlockHash,proto3" json:"safe_block_hash,omitempty" ssz-size:"32"` + FinalizedBlockHash []byte `protobuf:"bytes,3,opt,name=finalized_block_hash,json=finalizedBlockHash,proto3" json:"finalized_block_hash,omitempty" ssz-size:"32"` +} + +func (x *ForkchoiceState) Reset() { + *x = ForkchoiceState{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ForkchoiceState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ForkchoiceState) ProtoMessage() {} + +func (x *ForkchoiceState) ProtoReflect() protoreflect.Message { + mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[3] + 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 ForkchoiceState.ProtoReflect.Descriptor instead. +func (*ForkchoiceState) Descriptor() ([]byte, []int) { + return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{3} +} + +func (x *ForkchoiceState) GetHeadBlockHash() []byte { + if x != nil { + return x.HeadBlockHash + } + return nil +} + +func (x *ForkchoiceState) GetSafeBlockHash() []byte { + if x != nil { + return x.SafeBlockHash + } + return nil +} + +func (x *ForkchoiceState) GetFinalizedBlockHash() []byte { + if x != nil { + return x.FinalizedBlockHash + } + return nil +} + +var File_proto_engine_v1_execution_engine_proto protoreflect.FileDescriptor + +var file_proto_engine_v1_execution_engine_proto_rawDesc = []byte{ + 0x0a, 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, 0x12, 0x12, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x65, 0x78, 0x74, 0x2f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x04, 0x0a, 0x10, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x27, + 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0a, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2b, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x5f, 0x72, + 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, + 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, + 0x69, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, + 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, + 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x2f, 0x0a, 0x0f, 0x72, + 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0e, 0x72, 0x65, + 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x26, 0x0a, 0x0a, + 0x6c, 0x6f, 0x67, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, + 0x42, 0x07, 0x8a, 0xb5, 0x18, 0x03, 0x32, 0x35, 0x36, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x73, 0x42, + 0x6c, 0x6f, 0x6f, 0x6d, 0x12, 0x1e, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x06, 0x72, 0x61, + 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, + 0x0a, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0c, 0x42, 0x06, 0x92, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x65, 0x78, 0x74, 0x72, 0x61, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x10, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x66, 0x65, 0x65, + 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, + 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, 0x50, + 0x65, 0x72, 0x47, 0x61, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, + 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x41, 0x0a, 0x0c, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, + 0x28, 0x0c, 0x42, 0x1d, 0x8a, 0xb5, 0x18, 0x03, 0x3f, 0x2c, 0x3f, 0x92, 0xb5, 0x18, 0x12, 0x31, + 0x30, 0x34, 0x38, 0x35, 0x37, 0x36, 0x2c, 0x31, 0x30, 0x37, 0x33, 0x37, 0x34, 0x31, 0x38, 0x32, + 0x34, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x91, 0x01, 0x0a, 0x11, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x1e, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x06, 0x72, 0x61, 0x6e, + 0x64, 0x6f, 0x6d, 0x12, 0x3e, 0x0a, 0x17, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x15, 0x73, 0x75, + 0x67, 0x67, 0x65, 0x73, 0x74, 0x65, 0x64, 0x46, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, + 0x65, 0x6e, 0x74, 0x22, 0xa1, 0x02, 0x0a, 0x0d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x40, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x11, 0x6c, 0x61, 0x74, 0x65, 0x73, + 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0f, 0x6c, 0x61, 0x74, 0x65, + 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x29, 0x0a, 0x10, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x6f, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x09, 0x0a, 0x05, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x59, 0x4e, 0x43, + 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, + 0x44, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, + 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x4c, 0x5f, + 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x05, 0x22, 0xab, 0x01, 0x0a, 0x0f, 0x46, 0x6f, 0x72, 0x6b, + 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x0f, 0x68, + 0x65, 0x61, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0d, 0x68, 0x65, + 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2e, 0x0a, 0x0f, 0x73, + 0x61, 0x66, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0d, 0x73, 0x61, + 0x66, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x38, 0x0a, 0x14, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, + 0x32, 0x52, 0x12, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x48, 0x61, 0x73, 0x68, 0x42, 0x93, 0x01, 0x0a, 0x16, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x42, 0x14, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 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, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x76, + 0x31, 0xaa, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x12, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, + 0x6d, 0x5c, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5c, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_proto_engine_v1_execution_engine_proto_rawDescOnce sync.Once + file_proto_engine_v1_execution_engine_proto_rawDescData = file_proto_engine_v1_execution_engine_proto_rawDesc +) + +func file_proto_engine_v1_execution_engine_proto_rawDescGZIP() []byte { + file_proto_engine_v1_execution_engine_proto_rawDescOnce.Do(func() { + file_proto_engine_v1_execution_engine_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_engine_v1_execution_engine_proto_rawDescData) + }) + return file_proto_engine_v1_execution_engine_proto_rawDescData +} + +var file_proto_engine_v1_execution_engine_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_proto_engine_v1_execution_engine_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_proto_engine_v1_execution_engine_proto_goTypes = []interface{}{ + (PayloadStatus_Status)(0), // 0: ethereum.engine.v1.PayloadStatus.Status + (*ExecutionPayload)(nil), // 1: ethereum.engine.v1.ExecutionPayload + (*PayloadAttributes)(nil), // 2: ethereum.engine.v1.PayloadAttributes + (*PayloadStatus)(nil), // 3: ethereum.engine.v1.PayloadStatus + (*ForkchoiceState)(nil), // 4: ethereum.engine.v1.ForkchoiceState +} +var file_proto_engine_v1_execution_engine_proto_depIdxs = []int32{ + 0, // 0: ethereum.engine.v1.PayloadStatus.status:type_name -> ethereum.engine.v1.PayloadStatus.Status + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_proto_engine_v1_execution_engine_proto_init() } +func file_proto_engine_v1_execution_engine_proto_init() { + if File_proto_engine_v1_execution_engine_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_engine_v1_execution_engine_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutionPayload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_engine_v1_execution_engine_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PayloadAttributes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_engine_v1_execution_engine_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PayloadStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_engine_v1_execution_engine_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ForkchoiceState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_engine_v1_execution_engine_proto_rawDesc, + NumEnums: 1, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_engine_v1_execution_engine_proto_goTypes, + DependencyIndexes: file_proto_engine_v1_execution_engine_proto_depIdxs, + EnumInfos: file_proto_engine_v1_execution_engine_proto_enumTypes, + MessageInfos: file_proto_engine_v1_execution_engine_proto_msgTypes, + }.Build() + File_proto_engine_v1_execution_engine_proto = out.File + file_proto_engine_v1_execution_engine_proto_rawDesc = nil + file_proto_engine_v1_execution_engine_proto_goTypes = nil + file_proto_engine_v1_execution_engine_proto_depIdxs = nil +} diff --git a/proto/engine/v1/execution_engine.proto b/proto/engine/v1/execution_engine.proto new file mode 100644 index 0000000000..8b3c46aab8 --- /dev/null +++ b/proto/engine/v1/execution_engine.proto @@ -0,0 +1,68 @@ +// Copyright 2022 Prysmatic Labs. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +syntax = "proto3"; + +package ethereum.engine.v1; + +import "proto/eth/ext/options.proto"; + +option csharp_namespace = "Ethereum.Engine.V1"; +option go_package = "github.com/prysmaticlabs/prysm/proto/engine/v1;enginev1"; +option java_multiple_files = true; +option java_outer_classname = "ExecutionEngineProto"; +option java_package = "org.ethereum.engine.v1"; +option php_namespace = "Ethereum\\Engine\\v1"; + +message ExecutionPayload { + bytes parent_hash = 1 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes fee_recipient = 2 [(ethereum.eth.ext.ssz_size) = "20"]; + bytes state_root = 3 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes recipients_root = 4 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes logs_bloom = 5 [(ethereum.eth.ext.ssz_size) = "256"]; + bytes random = 6 [(ethereum.eth.ext.ssz_size) = "32"]; + uint64 block_number = 7; + uint64 gas_limit = 8; + uint64 gas_used = 9; + uint64 timestamp = 10; + bytes extra_data = 11 [(ethereum.eth.ext.ssz_max) = "32"]; + bytes base_fee_per_gas = 12 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes block_hash = 13 [(ethereum.eth.ext.ssz_size) = "32"]; + repeated bytes transactions = 14 [(ethereum.eth.ext.ssz_size) = "?,?", (ethereum.eth.ext.ssz_max) = "1048576,1073741824"]; +} + +message PayloadAttributes { + uint64 timestamp = 1; + bytes random = 2 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes suggested_fee_recipient = 3 [(ethereum.eth.ext.ssz_size) = "20"]; +} + +message PayloadStatus { + Status status = 1; + bytes latest_valid_hash = 2 [(ethereum.eth.ext.ssz_size) = "32"]; + string validation_error = 3; + enum Status { + VALID = 0; + INVALID = 1; + SYNCING = 2; + ACCEPTED = 3; + INVALID_BLOCK_HASH = 4; + INVALID_TERMINAL_BLOCK = 5; + } +} + +message ForkchoiceState { + bytes head_block_hash = 1 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes safe_block_hash = 2 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes finalized_block_hash = 3 [(ethereum.eth.ext.ssz_size) = "32"]; +} diff --git a/proto/engine/v1/generated.ssz.go b/proto/engine/v1/generated.ssz.go new file mode 100755 index 0000000000..200c3e10c6 --- /dev/null +++ b/proto/engine/v1/generated.ssz.go @@ -0,0 +1,380 @@ +// Code generated by fastssz. DO NOT EDIT. +// Hash: e694201808b1e0069a274c88e1977511c2e47a735af15f5dcda9ead3d115608d +package enginev1 + +import ( + ssz "github.com/ferranbt/fastssz" +) + +// MarshalSSZ ssz marshals the ExecutionPayload object +func (e *ExecutionPayload) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(e) +} + +// MarshalSSZTo ssz marshals the ExecutionPayload object to a target array +func (e *ExecutionPayload) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(508) + + // Field (0) 'ParentHash' + if len(e.ParentHash) != 32 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.ParentHash...) + + // Field (1) 'FeeRecipient' + if len(e.FeeRecipient) != 20 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.FeeRecipient...) + + // Field (2) 'StateRoot' + if len(e.StateRoot) != 32 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.StateRoot...) + + // Field (3) 'RecipientsRoot' + if len(e.RecipientsRoot) != 32 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.RecipientsRoot...) + + // Field (4) 'LogsBloom' + if len(e.LogsBloom) != 256 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.LogsBloom...) + + // Field (5) 'Random' + if len(e.Random) != 32 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.Random...) + + // Field (6) 'BlockNumber' + dst = ssz.MarshalUint64(dst, e.BlockNumber) + + // Field (7) 'GasLimit' + dst = ssz.MarshalUint64(dst, e.GasLimit) + + // Field (8) 'GasUsed' + dst = ssz.MarshalUint64(dst, e.GasUsed) + + // Field (9) 'Timestamp' + dst = ssz.MarshalUint64(dst, e.Timestamp) + + // Offset (10) 'ExtraData' + dst = ssz.WriteOffset(dst, offset) + offset += len(e.ExtraData) + + // Field (11) 'BaseFeePerGas' + if len(e.BaseFeePerGas) != 32 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.BaseFeePerGas...) + + // Field (12) 'BlockHash' + if len(e.BlockHash) != 32 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.BlockHash...) + + // Offset (13) 'Transactions' + dst = ssz.WriteOffset(dst, offset) + for ii := 0; ii < len(e.Transactions); ii++ { + offset += 4 + offset += len(e.Transactions[ii]) + } + + // Field (10) 'ExtraData' + if len(e.ExtraData) > 32 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.ExtraData...) + + // Field (13) 'Transactions' + if len(e.Transactions) > 1048576 { + err = ssz.ErrListTooBig + return + } + { + offset = 4 * len(e.Transactions) + for ii := 0; ii < len(e.Transactions); ii++ { + dst = ssz.WriteOffset(dst, offset) + offset += len(e.Transactions[ii]) + } + } + for ii := 0; ii < len(e.Transactions); ii++ { + if len(e.Transactions[ii]) > 1073741824 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, e.Transactions[ii]...) + } + + return +} + +// UnmarshalSSZ ssz unmarshals the ExecutionPayload object +func (e *ExecutionPayload) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 508 { + return ssz.ErrSize + } + + tail := buf + var o10, o13 uint64 + + // Field (0) 'ParentHash' + if cap(e.ParentHash) == 0 { + e.ParentHash = make([]byte, 0, len(buf[0:32])) + } + e.ParentHash = append(e.ParentHash, buf[0:32]...) + + // Field (1) 'FeeRecipient' + if cap(e.FeeRecipient) == 0 { + e.FeeRecipient = make([]byte, 0, len(buf[32:52])) + } + e.FeeRecipient = append(e.FeeRecipient, buf[32:52]...) + + // Field (2) 'StateRoot' + if cap(e.StateRoot) == 0 { + e.StateRoot = make([]byte, 0, len(buf[52:84])) + } + e.StateRoot = append(e.StateRoot, buf[52:84]...) + + // Field (3) 'RecipientsRoot' + if cap(e.RecipientsRoot) == 0 { + e.RecipientsRoot = make([]byte, 0, len(buf[84:116])) + } + e.RecipientsRoot = append(e.RecipientsRoot, buf[84:116]...) + + // Field (4) 'LogsBloom' + if cap(e.LogsBloom) == 0 { + e.LogsBloom = make([]byte, 0, len(buf[116:372])) + } + e.LogsBloom = append(e.LogsBloom, buf[116:372]...) + + // Field (5) 'Random' + if cap(e.Random) == 0 { + e.Random = make([]byte, 0, len(buf[372:404])) + } + e.Random = append(e.Random, buf[372:404]...) + + // Field (6) 'BlockNumber' + e.BlockNumber = ssz.UnmarshallUint64(buf[404:412]) + + // Field (7) 'GasLimit' + e.GasLimit = ssz.UnmarshallUint64(buf[412:420]) + + // Field (8) 'GasUsed' + e.GasUsed = ssz.UnmarshallUint64(buf[420:428]) + + // Field (9) 'Timestamp' + e.Timestamp = ssz.UnmarshallUint64(buf[428:436]) + + // Offset (10) 'ExtraData' + if o10 = ssz.ReadOffset(buf[436:440]); o10 > size { + return ssz.ErrOffset + } + + if o10 < 508 { + return ssz.ErrInvalidVariableOffset + } + + // Field (11) 'BaseFeePerGas' + if cap(e.BaseFeePerGas) == 0 { + e.BaseFeePerGas = make([]byte, 0, len(buf[440:472])) + } + e.BaseFeePerGas = append(e.BaseFeePerGas, buf[440:472]...) + + // Field (12) 'BlockHash' + if cap(e.BlockHash) == 0 { + e.BlockHash = make([]byte, 0, len(buf[472:504])) + } + e.BlockHash = append(e.BlockHash, buf[472:504]...) + + // Offset (13) 'Transactions' + if o13 = ssz.ReadOffset(buf[504:508]); o13 > size || o10 > o13 { + return ssz.ErrOffset + } + + // Field (10) 'ExtraData' + { + buf = tail[o10:o13] + if len(buf) > 32 { + return ssz.ErrBytesLength + } + if cap(e.ExtraData) == 0 { + e.ExtraData = make([]byte, 0, len(buf)) + } + e.ExtraData = append(e.ExtraData, buf...) + } + + // Field (13) 'Transactions' + { + buf = tail[o13:] + num, err := ssz.DecodeDynamicLength(buf, 1048576) + if err != nil { + return err + } + e.Transactions = make([][]byte, num) + err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) { + if len(buf) > 1073741824 { + return ssz.ErrBytesLength + } + if cap(e.Transactions[indx]) == 0 { + e.Transactions[indx] = make([]byte, 0, len(buf)) + } + e.Transactions[indx] = append(e.Transactions[indx], buf...) + return nil + }) + if err != nil { + return err + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the ExecutionPayload object +func (e *ExecutionPayload) SizeSSZ() (size int) { + size = 508 + + // Field (10) 'ExtraData' + size += len(e.ExtraData) + + // Field (13) 'Transactions' + for ii := 0; ii < len(e.Transactions); ii++ { + size += 4 + size += len(e.Transactions[ii]) + } + + return +} + +// HashTreeRoot ssz hashes the ExecutionPayload object +func (e *ExecutionPayload) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(e) +} + +// HashTreeRootWith ssz hashes the ExecutionPayload object with a hasher +func (e *ExecutionPayload) HashTreeRootWith(hh *ssz.Hasher) (err error) { + indx := hh.Index() + + // Field (0) 'ParentHash' + if len(e.ParentHash) != 32 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(e.ParentHash) + + // Field (1) 'FeeRecipient' + if len(e.FeeRecipient) != 20 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(e.FeeRecipient) + + // Field (2) 'StateRoot' + if len(e.StateRoot) != 32 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(e.StateRoot) + + // Field (3) 'RecipientsRoot' + if len(e.RecipientsRoot) != 32 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(e.RecipientsRoot) + + // Field (4) 'LogsBloom' + if len(e.LogsBloom) != 256 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(e.LogsBloom) + + // Field (5) 'Random' + if len(e.Random) != 32 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(e.Random) + + // Field (6) 'BlockNumber' + hh.PutUint64(e.BlockNumber) + + // Field (7) 'GasLimit' + hh.PutUint64(e.GasLimit) + + // Field (8) 'GasUsed' + hh.PutUint64(e.GasUsed) + + // Field (9) 'Timestamp' + hh.PutUint64(e.Timestamp) + + // Field (10) 'ExtraData' + { + elemIndx := hh.Index() + byteLen := uint64(len(e.ExtraData)) + if byteLen > 32 { + err = ssz.ErrIncorrectListSize + return + } + hh.PutBytes(e.ExtraData) + hh.MerkleizeWithMixin(elemIndx, byteLen, (32+31)/32) + } + + // Field (11) 'BaseFeePerGas' + if len(e.BaseFeePerGas) != 32 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(e.BaseFeePerGas) + + // Field (12) 'BlockHash' + if len(e.BlockHash) != 32 { + err = ssz.ErrBytesLength + return + } + hh.PutBytes(e.BlockHash) + + // Field (13) 'Transactions' + { + subIndx := hh.Index() + num := uint64(len(e.Transactions)) + if num > 1048576 { + err = ssz.ErrIncorrectListSize + return + } + for _, elem := range e.Transactions { + { + elemIndx := hh.Index() + byteLen := uint64(len(elem)) + if byteLen > 1073741824 { + err = ssz.ErrIncorrectListSize + return + } + hh.AppendBytes32(elem) + hh.MerkleizeWithMixin(elemIndx, byteLen, (1073741824+31)/32) + } + } + hh.MerkleizeWithMixin(subIndx, num, 1048576) + } + + hh.Merkleize(indx) + return +} diff --git a/proto/engine/v1/json_marshal_unmarshal.go b/proto/engine/v1/json_marshal_unmarshal.go new file mode 100644 index 0000000000..cfc899bca0 --- /dev/null +++ b/proto/engine/v1/json_marshal_unmarshal.go @@ -0,0 +1,47 @@ +package enginev1 + +import "google.golang.org/protobuf/encoding/protojson" + +// MarshalJSON defines a custom json.Marshaler interface implementation +// that uses protojson underneath the hood, as protojson will respect +// proper struct tag naming conventions required for the JSON-RPC engine API to work. +func (e *ExecutionPayload) MarshalJSON() ([]byte, error) { + return protojson.Marshal(e) +} + +// UnmarshalJSON defines a custom json.Unmarshaler interface implementation +// that uses protojson underneath the hood, as protojson will respect +// proper struct tag naming conventions required for the JSON-RPC engine API to work. +func (e *ExecutionPayload) UnmarshalJSON(enc []byte) error { + return protojson.Unmarshal(enc, e) +} + +// MarshalJSON -- +func (p *PayloadAttributes) MarshalJSON() ([]byte, error) { + return protojson.Marshal(p) +} + +// UnmarshalJSON -- +func (p *PayloadAttributes) UnmarshalJSON(enc []byte) error { + return protojson.Unmarshal(enc, p) +} + +// MarshalJSON -- +func (p *PayloadStatus) MarshalJSON() ([]byte, error) { + return protojson.Marshal(p) +} + +// UnmarshalJSON -- +func (p *PayloadStatus) UnmarshalJSON(enc []byte) error { + return protojson.Unmarshal(enc, p) +} + +// MarshalJSON -- +func (f *ForkchoiceState) MarshalJSON() ([]byte, error) { + return protojson.Marshal(f) +} + +// UnmarshalJSON -- +func (f *ForkchoiceState) UnmarshalJSON(enc []byte) error { + return protojson.Unmarshal(enc, f) +} diff --git a/proto/engine/v1/json_marshal_unmarshal_test.go b/proto/engine/v1/json_marshal_unmarshal_test.go new file mode 100644 index 0000000000..a0cee64fac --- /dev/null +++ b/proto/engine/v1/json_marshal_unmarshal_test.go @@ -0,0 +1,93 @@ +package enginev1 + +import ( + "encoding/json" + "testing" + + "github.com/prysmaticlabs/prysm/encoding/bytesutil" + "github.com/prysmaticlabs/prysm/testing/require" +) + +func TestJsonMarshalUnmarshal(t *testing.T) { + foo := bytesutil.ToBytes32([]byte("foo")) + bar := bytesutil.PadTo([]byte("bar"), 20) + baz := bytesutil.PadTo([]byte("baz"), 256) + t.Run("payload attributes", func(t *testing.T) { + jsonPayload := map[string]interface{}{ + "timestamp": 1, + "random": foo[:], + "suggestedFeeRecipient": bar, + } + enc, err := json.Marshal(jsonPayload) + require.NoError(t, err) + payloadPb := &PayloadAttributes{} + require.NoError(t, json.Unmarshal(enc, payloadPb)) + require.DeepEqual(t, uint64(1), payloadPb.Timestamp) + require.DeepEqual(t, foo[:], payloadPb.Random) + require.DeepEqual(t, bar, payloadPb.SuggestedFeeRecipient) + }) + t.Run("payload status", func(t *testing.T) { + jsonPayload := map[string]interface{}{ + "status": "INVALID", + "latestValidHash": foo[:], + "validationError": "failed validation", + } + enc, err := json.Marshal(jsonPayload) + require.NoError(t, err) + payloadPb := &PayloadStatus{} + require.NoError(t, json.Unmarshal(enc, payloadPb)) + require.DeepEqual(t, "INVALID", payloadPb.Status.String()) + require.DeepEqual(t, foo[:], payloadPb.LatestValidHash) + require.DeepEqual(t, "failed validation", payloadPb.ValidationError) + }) + t.Run("forkchoice state", func(t *testing.T) { + jsonPayload := map[string]interface{}{ + "headBlockHash": foo[:], + "safeBlockHash": foo[:], + "finalizedBlockHash": foo[:], + } + enc, err := json.Marshal(jsonPayload) + require.NoError(t, err) + payloadPb := &ForkchoiceState{} + require.NoError(t, json.Unmarshal(enc, payloadPb)) + require.DeepEqual(t, foo[:], payloadPb.HeadBlockHash) + require.DeepEqual(t, foo[:], payloadPb.SafeBlockHash) + require.DeepEqual(t, foo[:], payloadPb.FinalizedBlockHash) + }) + t.Run("execution payload", func(t *testing.T) { + jsonPayload := map[string]interface{}{ + "parentHash": foo[:], + "feeRecipient": bar, + "stateRoot": foo[:], + "recipientsRoot": foo[:], + "logsBloom": baz, + "random": foo[:], + "blockNumber": 1, + "gasLimit": 1, + "gasUsed": 1, + "timestamp": 1, + "extraData": foo[:], + "baseFeePerGas": foo[:], + "blockHash": foo[:], + "transactions": [][]byte{foo[:]}, + } + enc, err := json.Marshal(jsonPayload) + require.NoError(t, err) + payloadPb := &ExecutionPayload{} + require.NoError(t, json.Unmarshal(enc, payloadPb)) + require.DeepEqual(t, foo[:], payloadPb.ParentHash) + require.DeepEqual(t, bar, payloadPb.FeeRecipient) + require.DeepEqual(t, foo[:], payloadPb.StateRoot) + require.DeepEqual(t, foo[:], payloadPb.RecipientsRoot) + require.DeepEqual(t, baz, payloadPb.LogsBloom) + require.DeepEqual(t, foo[:], payloadPb.Random) + require.DeepEqual(t, uint64(1), payloadPb.BlockNumber) + require.DeepEqual(t, uint64(1), payloadPb.GasLimit) + require.DeepEqual(t, uint64(1), payloadPb.GasUsed) + require.DeepEqual(t, uint64(1), payloadPb.Timestamp) + require.DeepEqual(t, foo[:], payloadPb.ExtraData) + require.DeepEqual(t, foo[:], payloadPb.BaseFeePerGas) + require.DeepEqual(t, foo[:], payloadPb.BlockHash) + require.DeepEqual(t, [][]byte{foo[:]}, payloadPb.Transactions) + }) +}