mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
beacon/engine: improve hand-written JSON marshaling
- remove unmarshal methods (for now) - use jsonw library instead of string concatenation
This commit is contained in:
parent
bf3464a34c
commit
469cd8d781
9 changed files with 153 additions and 1056 deletions
|
|
@ -16,166 +16,54 @@
|
|||
|
||||
package engine
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// estimateBlobAndProofV1Size returns a rough estimate of the JSON size for a BlobAndProofV1.
|
||||
func estimateBlobAndProofV1Size(item *BlobAndProofV1) int {
|
||||
if item == nil {
|
||||
return 4
|
||||
}
|
||||
return len(item.Blob)*2 + len(item.Proof)*2 + 30
|
||||
}
|
||||
|
||||
// marshalBlobAndProofV1 writes a BlobAndProofV1 as JSON and appends it to buf.
|
||||
func marshalBlobAndProofV1(buf []byte, item *BlobAndProofV1) []byte {
|
||||
if item == nil {
|
||||
return append(buf, "null"...)
|
||||
}
|
||||
buf = append(buf, `{"blob":`...)
|
||||
buf = writeHexBytes(buf, item.Blob)
|
||||
|
||||
buf = append(buf, `,"proof":`...)
|
||||
buf = writeHexBytes(buf, item.Proof)
|
||||
|
||||
buf = append(buf, '}')
|
||||
return buf
|
||||
}
|
||||
|
||||
// estimateBlobAndProofV2Size returns a rough estimate of the JSON size for a BlobAndProofV2.
|
||||
func estimateBlobAndProofV2Size(item *BlobAndProofV2) int {
|
||||
if item == nil {
|
||||
return 4
|
||||
}
|
||||
size := len(item.Blob)*2 + 30
|
||||
for _, proof := range item.CellProofs {
|
||||
size += len(proof)*2 + 6
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
// marshalBlobAndProofV2 writes a BlobAndProofV2 as JSON and appends it to buf.
|
||||
func marshalBlobAndProofV2(buf []byte, item *BlobAndProofV2) []byte {
|
||||
if item == nil {
|
||||
return append(buf, "null"...)
|
||||
}
|
||||
buf = append(buf, `{"blob":`...)
|
||||
buf = writeHexBytes(buf, item.Blob)
|
||||
|
||||
buf = append(buf, `,"proofs":`...)
|
||||
buf = marshalHexBytesArray(buf, item.CellProofs)
|
||||
|
||||
buf = append(buf, '}')
|
||||
return buf
|
||||
}
|
||||
import (
|
||||
jsonw "github.com/fjl/jsonw"
|
||||
)
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
func (list BlobAndProofListV1) MarshalJSON() ([]byte, error) {
|
||||
// Estimate buffer size.
|
||||
size := 2
|
||||
for _, item := range list {
|
||||
size += estimateBlobAndProofV1Size(item) + 1
|
||||
}
|
||||
buf := make([]byte, 0, size)
|
||||
|
||||
// Write the array elements to the buffer.
|
||||
buf = append(buf, '[')
|
||||
for i, item := range list {
|
||||
if i > 0 {
|
||||
buf = append(buf, ',')
|
||||
var b jsonw.Buffer
|
||||
b.Array(func() {
|
||||
for _, item := range list {
|
||||
marshalBlobAndProofV1(&b, item)
|
||||
}
|
||||
buf = marshalBlobAndProofV1(buf, item)
|
||||
}
|
||||
buf = append(buf, ']')
|
||||
return buf, nil
|
||||
})
|
||||
return b.Output(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
func (list *BlobAndProofListV1) UnmarshalJSON(input []byte) error {
|
||||
if isJSONNull(input) {
|
||||
*list = nil
|
||||
return nil
|
||||
func marshalBlobAndProofV1(b *jsonw.Buffer, item *BlobAndProofV1) {
|
||||
if item == nil {
|
||||
b.Null()
|
||||
} else {
|
||||
b.Object(func() {
|
||||
b.Key("blob")
|
||||
b.HexBytes(item.Blob)
|
||||
b.Key("proof")
|
||||
b.HexBytes(item.Proof)
|
||||
})
|
||||
}
|
||||
items := make(BlobAndProofListV1, 0)
|
||||
if err := decodeJSONArray(input, func(value json.RawMessage) error {
|
||||
if isJSONNull(value) {
|
||||
items = append(items, nil)
|
||||
return nil
|
||||
}
|
||||
item := new(BlobAndProofV1)
|
||||
if err := decodeJSONObject(value, func(key string, value json.RawMessage) error {
|
||||
switch key {
|
||||
case "blob":
|
||||
return item.Blob.UnmarshalJSON(value)
|
||||
case "proof":
|
||||
return item.Proof.UnmarshalJSON(value)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
items = append(items, item)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
*list = items
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
func (list BlobAndProofListV2) MarshalJSON() ([]byte, error) {
|
||||
// Estimate buffer size.
|
||||
size := 2
|
||||
for _, item := range list {
|
||||
size += estimateBlobAndProofV2Size(item) + 1
|
||||
}
|
||||
buf := make([]byte, 0, size)
|
||||
|
||||
// Write the array elements to the buffer.
|
||||
buf = append(buf, '[')
|
||||
for i, item := range list {
|
||||
if i > 0 {
|
||||
buf = append(buf, ',')
|
||||
var b jsonw.Buffer
|
||||
b.Array(func() {
|
||||
for _, item := range list {
|
||||
marshalBlobAndProofV2(&b, item)
|
||||
}
|
||||
buf = marshalBlobAndProofV2(buf, item)
|
||||
}
|
||||
buf = append(buf, ']')
|
||||
return buf, nil
|
||||
})
|
||||
return b.Output(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
func (list *BlobAndProofListV2) UnmarshalJSON(input []byte) error {
|
||||
if isJSONNull(input) {
|
||||
*list = nil
|
||||
return nil
|
||||
func marshalBlobAndProofV2(b *jsonw.Buffer, item *BlobAndProofV2) {
|
||||
if item == nil {
|
||||
b.Null()
|
||||
} else {
|
||||
b.Object(func() {
|
||||
b.Key("blob")
|
||||
b.HexBytes(item.Blob)
|
||||
b.Key("proofs")
|
||||
appendHexBytesArray(b, item.CellProofs)
|
||||
})
|
||||
}
|
||||
items := make(BlobAndProofListV2, 0)
|
||||
if err := decodeJSONArray(input, func(value json.RawMessage) error {
|
||||
if isJSONNull(value) {
|
||||
items = append(items, nil)
|
||||
return nil
|
||||
}
|
||||
item := new(BlobAndProofV2)
|
||||
if err := decodeJSONObject(value, func(key string, value json.RawMessage) error {
|
||||
switch key {
|
||||
case "blob":
|
||||
return item.Blob.UnmarshalJSON(value)
|
||||
case "proofs":
|
||||
proofs, err := unmarshalHexBytesArray(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
item.CellProofs = proofs
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
items = append(items, item)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
*list = items
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,329 +0,0 @@
|
|||
// Copyright 2026 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
// canonicalBlobAndProofV1 is a reference type for BlobAndProofV1 that uses
|
||||
// standard json.Marshal (no custom MarshalJSON).
|
||||
type canonicalBlobAndProofV1 struct {
|
||||
Blob hexutil.Bytes `json:"blob"`
|
||||
Proof hexutil.Bytes `json:"proof"`
|
||||
}
|
||||
|
||||
// canonicalBlobAndProofV2 is a reference type for BlobAndProofV2 that uses
|
||||
// standard json.Marshal (no custom MarshalJSON).
|
||||
type canonicalBlobAndProofV2 struct {
|
||||
Blob hexutil.Bytes `json:"blob"`
|
||||
CellProofs []hexutil.Bytes `json:"proofs"`
|
||||
}
|
||||
|
||||
func toCanonicalBlobAndProofListV1(list BlobAndProofListV1) []*canonicalBlobAndProofV1 {
|
||||
canonical := make([]*canonicalBlobAndProofV1, len(list))
|
||||
for i, item := range list {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
canonical[i] = &canonicalBlobAndProofV1{
|
||||
Blob: item.Blob,
|
||||
Proof: item.Proof,
|
||||
}
|
||||
}
|
||||
return canonical
|
||||
}
|
||||
|
||||
func toCanonicalBlobAndProofListV2(list BlobAndProofListV2) []*canonicalBlobAndProofV2 {
|
||||
canonical := make([]*canonicalBlobAndProofV2, len(list))
|
||||
for i, item := range list {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
canonical[i] = &canonicalBlobAndProofV2{
|
||||
Blob: item.Blob,
|
||||
CellProofs: item.CellProofs,
|
||||
}
|
||||
}
|
||||
return canonical
|
||||
}
|
||||
|
||||
func TestBlobAndProofListV1MarshalJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
list BlobAndProofListV1
|
||||
}{
|
||||
{
|
||||
name: "multiple items",
|
||||
list: BlobAndProofListV1{
|
||||
{
|
||||
Blob: hexutil.Bytes{0x01, 0x02},
|
||||
Proof: hexutil.Bytes{0x03, 0x04},
|
||||
},
|
||||
{
|
||||
Blob: hexutil.Bytes{},
|
||||
Proof: hexutil.Bytes{0x05},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil item",
|
||||
list: BlobAndProofListV1{
|
||||
nil,
|
||||
{
|
||||
Blob: hexutil.Bytes{0xaa},
|
||||
Proof: hexutil.Bytes{0xbb},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty list",
|
||||
list: BlobAndProofListV1{},
|
||||
},
|
||||
{
|
||||
name: "nil list",
|
||||
list: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := tt.list.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatalf("MarshalJSON error: %v", err)
|
||||
}
|
||||
want, err := json.Marshal(toCanonicalBlobAndProofListV1(tt.list))
|
||||
if err != nil {
|
||||
t.Fatalf("canonical marshal error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(compactJSON(got), compactJSON(want)) {
|
||||
t.Errorf("JSON mismatch\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlobAndProofListV1UnmarshalJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
json string
|
||||
want BlobAndProofListV1
|
||||
}{
|
||||
{
|
||||
name: "multiple items",
|
||||
json: `[{"blob":"0x0102","proof":"0x0304"},{"blob":"0x","proof":"0x05"}]`,
|
||||
want: BlobAndProofListV1{
|
||||
{
|
||||
Blob: hexutil.Bytes{0x01, 0x02},
|
||||
Proof: hexutil.Bytes{0x03, 0x04},
|
||||
},
|
||||
{
|
||||
Blob: hexutil.Bytes{},
|
||||
Proof: hexutil.Bytes{0x05},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil item",
|
||||
json: `[null,{"blob":"0xaa","proof":"0xbb"}]`,
|
||||
want: BlobAndProofListV1{
|
||||
nil,
|
||||
{
|
||||
Blob: hexutil.Bytes{0xaa},
|
||||
Proof: hexutil.Bytes{0xbb},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "null list",
|
||||
json: `null`,
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var got BlobAndProofListV1
|
||||
if err := got.UnmarshalJSON([]byte(tt.json)); err != nil {
|
||||
t.Fatalf("UnmarshalJSON error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Fatalf("decoded mismatch\ngot: %#v\nwant: %#v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlobAndProofListV2MarshalJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
list BlobAndProofListV2
|
||||
}{
|
||||
{
|
||||
name: "multiple items",
|
||||
list: BlobAndProofListV2{
|
||||
{
|
||||
Blob: hexutil.Bytes{0x01, 0x02},
|
||||
CellProofs: []hexutil.Bytes{{0x03, 0x04}, {0x05}},
|
||||
},
|
||||
{
|
||||
Blob: hexutil.Bytes{},
|
||||
CellProofs: []hexutil.Bytes{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil item",
|
||||
list: BlobAndProofListV2{
|
||||
nil,
|
||||
{
|
||||
Blob: hexutil.Bytes{0xaa},
|
||||
CellProofs: []hexutil.Bytes{{0xbb}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil proofs slice",
|
||||
list: BlobAndProofListV2{
|
||||
{
|
||||
Blob: hexutil.Bytes{0xcc},
|
||||
CellProofs: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty list",
|
||||
list: BlobAndProofListV2{},
|
||||
},
|
||||
{
|
||||
name: "nil list",
|
||||
list: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := tt.list.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatalf("MarshalJSON error: %v", err)
|
||||
}
|
||||
want, err := json.Marshal(toCanonicalBlobAndProofListV2(tt.list))
|
||||
if err != nil {
|
||||
t.Fatalf("canonical marshal error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(compactJSON(got), compactJSON(want)) {
|
||||
t.Errorf("JSON mismatch\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlobAndProofListV2UnmarshalJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
json string
|
||||
want BlobAndProofListV2
|
||||
}{
|
||||
{
|
||||
name: "multiple items",
|
||||
json: `[{"blob":"0x0102","proofs":["0x0304","0x05"]},{"blob":"0x","proofs":[]}]`,
|
||||
want: BlobAndProofListV2{
|
||||
{
|
||||
Blob: hexutil.Bytes{0x01, 0x02},
|
||||
CellProofs: []hexutil.Bytes{{0x03, 0x04}, {0x05}},
|
||||
},
|
||||
{
|
||||
Blob: hexutil.Bytes{},
|
||||
CellProofs: []hexutil.Bytes{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil item and nil proofs",
|
||||
json: `[null,{"blob":"0xcc","proofs":null}]`,
|
||||
want: BlobAndProofListV2{
|
||||
nil,
|
||||
{
|
||||
Blob: hexutil.Bytes{0xcc},
|
||||
CellProofs: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "null list",
|
||||
json: `null`,
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var got BlobAndProofListV2
|
||||
if err := got.UnmarshalJSON([]byte(tt.json)); err != nil {
|
||||
t.Fatalf("UnmarshalJSON error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Fatalf("decoded mismatch\ngot: %#v\nwant: %#v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlobAndProofFieldCoverage(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
typ reflect.Type
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "BlobAndProofV1",
|
||||
typ: reflect.TypeOf(BlobAndProofV1{}),
|
||||
expected: []string{
|
||||
"Blob",
|
||||
"Proof",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "BlobAndProofV2",
|
||||
typ: reflect.TypeOf(BlobAndProofV2{}),
|
||||
expected: []string{
|
||||
"Blob",
|
||||
"CellProofs",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.typ.NumField() != len(tt.expected) {
|
||||
t.Fatalf("%s has %d fields, expected %d; update marshal_bap_list.go",
|
||||
tt.name, tt.typ.NumField(), len(tt.expected))
|
||||
}
|
||||
for i, name := range tt.expected {
|
||||
if tt.typ.Field(i).Name != name {
|
||||
t.Errorf("field %d: got %q, want %q; update marshal_bap_list.go",
|
||||
i, tt.typ.Field(i).Name, name)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -19,61 +19,25 @@ package engine
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
jsonw "github.com/fjl/jsonw"
|
||||
)
|
||||
|
||||
// estimateBlobsBundleSize returns a rough estimate of the JSON size for a BlobsBundle.
|
||||
func estimateBlobsBundleSize(b *BlobsBundle) int {
|
||||
size := 80 // JSON structure overhead
|
||||
for _, blob := range b.Blobs {
|
||||
size += len(blob)*2 + 6
|
||||
}
|
||||
for _, c := range b.Commitments {
|
||||
size += len(c)*2 + 6
|
||||
}
|
||||
for _, p := range b.Proofs {
|
||||
size += len(p)*2 + 6
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
// marshalBlobsBundle writes BlobsBundle as JSON and appends it to buf.
|
||||
func marshalBlobsBundle(buf []byte, b *BlobsBundle) []byte {
|
||||
buf = append(buf, `{"commitments":`...)
|
||||
buf = marshalHexBytesArray(buf, b.Commitments)
|
||||
|
||||
buf = append(buf, `,"proofs":`...)
|
||||
buf = marshalHexBytesArray(buf, b.Proofs)
|
||||
|
||||
buf = append(buf, `,"blobs":`...)
|
||||
buf = marshalHexBytesArray(buf, b.Blobs)
|
||||
|
||||
buf = append(buf, '}')
|
||||
return buf
|
||||
}
|
||||
|
||||
func unmarshalBlobsBundle(input []byte) (*BlobsBundle, error) {
|
||||
if isJSONNull(input) {
|
||||
return nil, nil
|
||||
func marshalBlobsBundle(b *jsonw.Buffer, bundle *BlobsBundle) {
|
||||
if bundle == nil {
|
||||
b.Null()
|
||||
return
|
||||
}
|
||||
var bundle BlobsBundle
|
||||
if err := decodeJSONObject(input, func(key string, value json.RawMessage) error {
|
||||
var err error
|
||||
switch key {
|
||||
case "commitments":
|
||||
bundle.Commitments, err = unmarshalHexBytesArray(value)
|
||||
case "proofs":
|
||||
bundle.Proofs, err = unmarshalHexBytesArray(value)
|
||||
case "blobs":
|
||||
bundle.Blobs, err = unmarshalHexBytesArray(value)
|
||||
}
|
||||
return err
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &bundle, nil
|
||||
b.Object(func() {
|
||||
b.Key("commitments")
|
||||
appendHexBytesArray(b, bundle.Commitments)
|
||||
b.Key("proofs")
|
||||
appendHexBytesArray(b, bundle.Proofs)
|
||||
b.Key("blobs")
|
||||
appendHexBytesArray(b, bundle.Blobs)
|
||||
})
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
|
|
@ -82,38 +46,12 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
|
|||
return nil, errors.New("missing required field 'executionPayload' for ExecutionPayloadEnvelope")
|
||||
}
|
||||
|
||||
// Marshal the execution payload using its gencodec MarshalJSON.
|
||||
// Pre-marshal the execution payload using its gencodec MarshalJSON.
|
||||
payload, err := e.ExecutionPayload.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Marshal the block value.
|
||||
blockValue, err := json.Marshal((*hexutil.Big)(e.BlockValue))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Marshal the execution requests.
|
||||
var requests []byte
|
||||
if e.Requests != nil {
|
||||
hexRequests := make([]hexutil.Bytes, len(e.Requests))
|
||||
for i, req := range e.Requests {
|
||||
hexRequests[i] = req
|
||||
}
|
||||
requests, err = json.Marshal(hexRequests)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal the override.
|
||||
override, err := json.Marshal(e.Override)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Marshal the witness.
|
||||
// Pre-marshal the witness.
|
||||
var witness []byte
|
||||
if e.Witness != nil {
|
||||
witness, err = json.Marshal(e.Witness)
|
||||
|
|
@ -122,131 +60,40 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Estimate buffer size.
|
||||
size := len(payload) + len(blockValue) + len(requests) + len(override) + len(witness)
|
||||
if e.BlobsBundle != nil {
|
||||
size += estimateBlobsBundleSize(e.BlobsBundle)
|
||||
}
|
||||
size += 256 // JSON bloat (keys, braces, commas, etc. and room for growth)
|
||||
buf := make([]byte, 0, size)
|
||||
|
||||
// Write the execution payload to the buffer
|
||||
buf = append(buf, `{"executionPayload":`...)
|
||||
buf = append(buf, payload...)
|
||||
|
||||
// Write the block value to the buffer
|
||||
buf = append(buf, `,"blockValue":`...)
|
||||
buf = append(buf, blockValue...)
|
||||
|
||||
// Write the blobs bundle to the buffer
|
||||
buf = append(buf, `,"blobsBundle":`...)
|
||||
if e.BlobsBundle != nil {
|
||||
buf = marshalBlobsBundle(buf, e.BlobsBundle)
|
||||
} else {
|
||||
buf = append(buf, "null"...)
|
||||
}
|
||||
|
||||
// Write the execution requests to the buffer
|
||||
buf = append(buf, `,"executionRequests":`...)
|
||||
if requests != nil {
|
||||
buf = append(buf, requests...)
|
||||
} else {
|
||||
buf = append(buf, "null"...)
|
||||
}
|
||||
|
||||
// Write the override to the buffer
|
||||
buf = append(buf, `,"shouldOverrideBuilder":`...)
|
||||
buf = append(buf, override...)
|
||||
|
||||
// Write the witness to the buffer if present
|
||||
if witness != nil {
|
||||
buf = append(buf, `,"witness":`...)
|
||||
buf = append(buf, witness...)
|
||||
}
|
||||
|
||||
// Close the envelope
|
||||
buf = append(buf, '}')
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
|
||||
var (
|
||||
payloadSeen bool
|
||||
blockValueSeen bool
|
||||
)
|
||||
*e = ExecutionPayloadEnvelope{}
|
||||
if err := decodeJSONObject(input, func(key string, value json.RawMessage) error {
|
||||
switch key {
|
||||
case "executionPayload":
|
||||
payloadSeen = true
|
||||
if isJSONNull(value) {
|
||||
e.ExecutionPayload = nil
|
||||
return nil
|
||||
}
|
||||
var payload ExecutableData
|
||||
if err := payload.UnmarshalJSON(value); err != nil {
|
||||
return err
|
||||
}
|
||||
e.ExecutionPayload = &payload
|
||||
case "blockValue":
|
||||
blockValueSeen = true
|
||||
if isJSONNull(value) {
|
||||
e.BlockValue = nil
|
||||
return nil
|
||||
}
|
||||
var blockValue hexutil.Big
|
||||
if err := blockValue.UnmarshalJSON(value); err != nil {
|
||||
return err
|
||||
}
|
||||
e.BlockValue = (*big.Int)(&blockValue)
|
||||
case "blobsBundle":
|
||||
bundle, err := unmarshalBlobsBundle(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.BlobsBundle = bundle
|
||||
case "executionRequests":
|
||||
requests, err := unmarshalHexBytesArray(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if requests == nil {
|
||||
e.Requests = nil
|
||||
return nil
|
||||
}
|
||||
e.Requests = make([][]byte, len(requests))
|
||||
for i, req := range requests {
|
||||
e.Requests[i] = req
|
||||
}
|
||||
case "shouldOverrideBuilder":
|
||||
if isJSONNull(value) {
|
||||
e.Override = false
|
||||
return nil
|
||||
}
|
||||
if err := json.Unmarshal(value, &e.Override); err != nil {
|
||||
return err
|
||||
}
|
||||
case "witness":
|
||||
if isJSONNull(value) {
|
||||
e.Witness = nil
|
||||
return nil
|
||||
}
|
||||
var witness hexutil.Bytes
|
||||
if err := witness.UnmarshalJSON(value); err != nil {
|
||||
return err
|
||||
}
|
||||
e.Witness = &witness
|
||||
var b jsonw.Buffer
|
||||
b.Object(func() {
|
||||
b.Key("executionPayload")
|
||||
b.RawValue(payload)
|
||||
b.Key("blockValue")
|
||||
b.MustValue((*hexutil.Big)(e.BlockValue))
|
||||
b.Key("blobsBundle")
|
||||
marshalBlobsBundle(&b, e.BlobsBundle)
|
||||
b.Key("executionRequests")
|
||||
if e.Requests == nil {
|
||||
b.Null()
|
||||
} else {
|
||||
b.Array(func() {
|
||||
for _, r := range e.Requests {
|
||||
b.HexBytes(r)
|
||||
}
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if !payloadSeen || e.ExecutionPayload == nil {
|
||||
return errors.New("missing required field 'executionPayload' for ExecutionPayloadEnvelope")
|
||||
}
|
||||
if !blockValueSeen || e.BlockValue == nil {
|
||||
return errors.New("missing required field 'blockValue' for ExecutionPayloadEnvelope")
|
||||
}
|
||||
return nil
|
||||
b.Key("shouldOverrideBuilder")
|
||||
b.Bool(e.Override)
|
||||
if e.Witness != nil {
|
||||
b.Key("witness")
|
||||
b.RawValue(witness)
|
||||
}
|
||||
})
|
||||
|
||||
return b.Output(), nil
|
||||
}
|
||||
|
||||
func appendHexBytesArray[T ~[]byte](b *jsonw.Buffer, slice []T) {
|
||||
b.Array(func() {
|
||||
for _, elem := range slice {
|
||||
b.HexBytes(elem)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,42 +27,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
// canonicalEnvelope is a reference type for ExecutionPayloadEnvelope that uses
|
||||
// standard json.Marshal (no custom MarshalJSON). It mirrors the gencodec type
|
||||
// overrides so its output matches what the generated code would produce.
|
||||
type canonicalEnvelope struct {
|
||||
ExecutionPayload *ExecutableData `json:"executionPayload"`
|
||||
BlockValue *hexutil.Big `json:"blockValue"`
|
||||
BlobsBundle *BlobsBundle `json:"blobsBundle"`
|
||||
Requests []hexutil.Bytes `json:"executionRequests"`
|
||||
Override bool `json:"shouldOverrideBuilder"`
|
||||
Witness *hexutil.Bytes `json:"witness,omitempty"`
|
||||
}
|
||||
|
||||
func toCanonical(e *ExecutionPayloadEnvelope) *canonicalEnvelope {
|
||||
c := &canonicalEnvelope{
|
||||
ExecutionPayload: e.ExecutionPayload,
|
||||
BlockValue: (*hexutil.Big)(e.BlockValue),
|
||||
BlobsBundle: e.BlobsBundle,
|
||||
Override: e.Override,
|
||||
Witness: e.Witness,
|
||||
}
|
||||
if e.Requests != nil {
|
||||
c.Requests = make([]hexutil.Bytes, len(e.Requests))
|
||||
for i, r := range e.Requests {
|
||||
c.Requests[i] = r
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// compactJSON returns the compacted form of a JSON byte slice.
|
||||
func compactJSON(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
json.Compact(&buf, data)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func makeTestPayload() *ExecutableData {
|
||||
return &ExecutableData{
|
||||
ParentHash: common.HexToHash("0x01"),
|
||||
|
|
@ -82,93 +46,6 @@ func makeTestPayload() *ExecutableData {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMarshalJSON(t *testing.T) {
|
||||
witness := hexutil.Bytes{0xde, 0xad}
|
||||
tests := []struct {
|
||||
name string
|
||||
env ExecutionPayloadEnvelope
|
||||
}{
|
||||
{
|
||||
name: "full envelope with blobs",
|
||||
env: ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
BlockValue: big.NewInt(12345),
|
||||
BlobsBundle: &BlobsBundle{
|
||||
Commitments: []hexutil.Bytes{{0x01, 0x02}},
|
||||
Proofs: []hexutil.Bytes{{0x03, 0x04}},
|
||||
Blobs: []hexutil.Bytes{{0x05, 0x06}},
|
||||
},
|
||||
Requests: [][]byte{{0xaa}, {0xbb, 0xcc}},
|
||||
Override: true,
|
||||
Witness: &witness,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil BlobsBundle",
|
||||
env: ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
BlockValue: big.NewInt(0),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil Requests",
|
||||
env: ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
BlockValue: big.NewInt(1),
|
||||
Requests: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty Requests",
|
||||
env: ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
BlockValue: big.NewInt(1),
|
||||
Requests: [][]byte{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nil Witness",
|
||||
env: ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
BlockValue: big.NewInt(1),
|
||||
Witness: nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty blobs bundle arrays",
|
||||
env: ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
BlockValue: big.NewInt(1),
|
||||
BlobsBundle: &BlobsBundle{
|
||||
Commitments: []hexutil.Bytes{},
|
||||
Proofs: []hexutil.Bytes{},
|
||||
Blobs: []hexutil.Bytes{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Hand-rolled marshal.
|
||||
got, err := tt.env.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatalf("MarshalJSON error: %v", err)
|
||||
}
|
||||
|
||||
// Canonical marshal via reference struct.
|
||||
want, err := json.Marshal(toCanonical(&tt.env))
|
||||
if err != nil {
|
||||
t.Fatalf("canonical marshal error: %v", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(compactJSON(got), compactJSON(want)) {
|
||||
t.Errorf("JSON mismatch\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalJSONRoundtrip(t *testing.T) {
|
||||
witness := hexutil.Bytes{0xde, 0xad}
|
||||
original := ExecutionPayloadEnvelope{
|
||||
|
|
@ -190,7 +67,7 @@ func TestMarshalJSONRoundtrip(t *testing.T) {
|
|||
}
|
||||
|
||||
var decoded ExecutionPayloadEnvelope
|
||||
if err := decoded.UnmarshalJSON(data); err != nil {
|
||||
if err := json.Unmarshal(data, &decoded); err != nil {
|
||||
t.Fatalf("UnmarshalJSON error: %v", err)
|
||||
}
|
||||
|
||||
|
|
@ -214,100 +91,6 @@ func TestMarshalJSONRoundtrip(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalJSON(t *testing.T) {
|
||||
witness := hexutil.Bytes{0xde, 0xad}
|
||||
tests := []struct {
|
||||
name string
|
||||
env ExecutionPayloadEnvelope
|
||||
}{
|
||||
{
|
||||
name: "full envelope with blobs",
|
||||
env: ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
BlockValue: big.NewInt(12345),
|
||||
BlobsBundle: &BlobsBundle{
|
||||
Commitments: []hexutil.Bytes{{0x01, 0x02}},
|
||||
Proofs: []hexutil.Bytes{{0x03, 0x04}},
|
||||
Blobs: []hexutil.Bytes{{0x05, 0x06}},
|
||||
},
|
||||
Requests: [][]byte{{0xaa}, {0xbb, 0xcc}},
|
||||
Override: true,
|
||||
Witness: &witness,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "null optional fields",
|
||||
env: ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
BlockValue: big.NewInt(1),
|
||||
BlobsBundle: nil,
|
||||
Requests: nil,
|
||||
Override: false,
|
||||
Witness: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
input, err := json.Marshal(toCanonical(&tt.env))
|
||||
if err != nil {
|
||||
t.Fatalf("canonical marshal error: %v", err)
|
||||
}
|
||||
|
||||
var got ExecutionPayloadEnvelope
|
||||
if err := got.UnmarshalJSON(input); err != nil {
|
||||
t.Fatalf("UnmarshalJSON error: %v", err)
|
||||
}
|
||||
|
||||
gotJSON, err := json.Marshal(toCanonical(&got))
|
||||
if err != nil {
|
||||
t.Fatalf("canonical marshal after unmarshal error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(compactJSON(gotJSON), compactJSON(input)) {
|
||||
t.Errorf("JSON mismatch after unmarshal\ngot: %s\nwant: %s", gotJSON, input)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalJSONMissingRequiredFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
json func(t *testing.T) []byte
|
||||
}{
|
||||
{
|
||||
name: "missing executionPayload",
|
||||
json: func(t *testing.T) []byte {
|
||||
return []byte(`{"blockValue":"0x1"}`)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing blockValue",
|
||||
json: func(t *testing.T) []byte {
|
||||
input, err := json.Marshal(struct {
|
||||
ExecutionPayload *ExecutableData `json:"executionPayload"`
|
||||
}{
|
||||
ExecutionPayload: makeTestPayload(),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("marshal input: %v", err)
|
||||
}
|
||||
return input
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var env ExecutionPayloadEnvelope
|
||||
if err := env.UnmarshalJSON(tt.json(t)); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalJSONNilPayload(t *testing.T) {
|
||||
env := ExecutionPayloadEnvelope{
|
||||
ExecutionPayload: nil,
|
||||
|
|
|
|||
|
|
@ -1,158 +0,0 @@
|
|||
// Copyright 2026 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"slices"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
// marshalHexBytesArray writes an array of hex-encoded byte slices to buf.
|
||||
// A nil slice is written as "null" to match encoding/json semantics.
|
||||
func marshalHexBytesArray(buf []byte, items []hexutil.Bytes) []byte {
|
||||
if items == nil {
|
||||
return append(buf, "null"...)
|
||||
}
|
||||
buf = append(buf, '[')
|
||||
for i, item := range items {
|
||||
if i > 0 {
|
||||
buf = append(buf, ',')
|
||||
}
|
||||
buf = writeHexBytes(buf, item)
|
||||
}
|
||||
buf = append(buf, ']')
|
||||
return buf
|
||||
}
|
||||
|
||||
// writeHexBytes writes a hex-encoded byte slice as a JSON string ("0x...") to buf.
|
||||
func writeHexBytes(buf []byte, data []byte) []byte {
|
||||
buf = append(buf, '"', '0', 'x')
|
||||
buf = slices.Grow(buf, len(data)*2+1)
|
||||
cur := len(buf)
|
||||
buf = buf[:cur+len(data)*2]
|
||||
hex.Encode(buf[cur:], data)
|
||||
buf = append(buf, '"')
|
||||
return buf
|
||||
}
|
||||
|
||||
func decodeJSONObject(input []byte, fn func(key string, value json.RawMessage) error) error {
|
||||
dec := json.NewDecoder(bytes.NewReader(input))
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delim, ok := tok.(json.Delim)
|
||||
if !ok || delim != '{' {
|
||||
return fmt.Errorf("expected JSON object")
|
||||
}
|
||||
for dec.More() {
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, ok := tok.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("expected JSON object key")
|
||||
}
|
||||
var value json.RawMessage
|
||||
if err := dec.Decode(&value); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fn(key, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
tok, err = dec.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delim, ok = tok.(json.Delim)
|
||||
if !ok || delim != '}' {
|
||||
return fmt.Errorf("expected end of JSON object")
|
||||
}
|
||||
if _, err := dec.Token(); err != io.EOF {
|
||||
if err == nil {
|
||||
return fmt.Errorf("unexpected trailing data")
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeJSONArray(input []byte, fn func(value json.RawMessage) error) error {
|
||||
dec := json.NewDecoder(bytes.NewReader(input))
|
||||
tok, err := dec.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delim, ok := tok.(json.Delim)
|
||||
if !ok || delim != '[' {
|
||||
return fmt.Errorf("expected JSON array")
|
||||
}
|
||||
for dec.More() {
|
||||
var value json.RawMessage
|
||||
if err := dec.Decode(&value); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fn(value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
tok, err = dec.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delim, ok = tok.(json.Delim)
|
||||
if !ok || delim != ']' {
|
||||
return fmt.Errorf("expected end of JSON array")
|
||||
}
|
||||
if _, err := dec.Token(); err != io.EOF {
|
||||
if err == nil {
|
||||
return fmt.Errorf("unexpected trailing data")
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isJSONNull(input []byte) bool {
|
||||
return bytes.Equal(bytes.TrimSpace(input), []byte("null"))
|
||||
}
|
||||
|
||||
func unmarshalHexBytesArray(input []byte) ([]hexutil.Bytes, error) {
|
||||
if isJSONNull(input) {
|
||||
return nil, nil
|
||||
}
|
||||
items := make([]hexutil.Bytes, 0)
|
||||
if err := decodeJSONArray(input, func(value json.RawMessage) error {
|
||||
var item hexutil.Bytes
|
||||
if err := item.UnmarshalJSON(value); err != nil {
|
||||
return err
|
||||
}
|
||||
items = append(items, item)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
53
beacon/engine/gen_epe.go
Normal file
53
beacon/engine/gen_epe.go
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
||||
|
||||
package engine
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
var _ = (*executionPayloadEnvelopeMarshaling)(nil)
|
||||
|
||||
// UnmarshalJSON unmarshals from JSON.
|
||||
func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
|
||||
type ExecutionPayloadEnvelope struct {
|
||||
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
|
||||
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
|
||||
BlobsBundle *BlobsBundle `json:"blobsBundle"`
|
||||
Requests []hexutil.Bytes `json:"executionRequests"`
|
||||
Override *bool `json:"shouldOverrideBuilder"`
|
||||
Witness *hexutil.Bytes `json:"witness,omitempty"`
|
||||
}
|
||||
var dec ExecutionPayloadEnvelope
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
return err
|
||||
}
|
||||
if dec.ExecutionPayload == nil {
|
||||
return errors.New("missing required field 'executionPayload' for ExecutionPayloadEnvelope")
|
||||
}
|
||||
e.ExecutionPayload = dec.ExecutionPayload
|
||||
if dec.BlockValue == nil {
|
||||
return errors.New("missing required field 'blockValue' for ExecutionPayloadEnvelope")
|
||||
}
|
||||
e.BlockValue = (*big.Int)(dec.BlockValue)
|
||||
if dec.BlobsBundle != nil {
|
||||
e.BlobsBundle = dec.BlobsBundle
|
||||
}
|
||||
if dec.Requests != nil {
|
||||
e.Requests = make([][]byte, len(dec.Requests))
|
||||
for k, v := range dec.Requests {
|
||||
e.Requests[k] = v
|
||||
}
|
||||
}
|
||||
if dec.Override != nil {
|
||||
e.Override = *dec.Override
|
||||
}
|
||||
if dec.Witness != nil {
|
||||
e.Witness = dec.Witness
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -125,7 +125,7 @@ type StatelessPayloadStatusV1 struct {
|
|||
ValidationError *string `json:"validationError"`
|
||||
}
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type ExecutionPayloadEnvelope -field-override executionPayloadEnvelopeMarshaling -out gen_epe.go
|
||||
//go:generate go run github.com/fjl/gencodec -enc=false -type ExecutionPayloadEnvelope -field-override executionPayloadEnvelopeMarshaling -out gen_epe.go
|
||||
|
||||
type ExecutionPayloadEnvelope struct {
|
||||
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
|
||||
|
|
@ -136,6 +136,12 @@ type ExecutionPayloadEnvelope struct {
|
|||
Witness *hexutil.Bytes `json:"witness,omitempty"`
|
||||
}
|
||||
|
||||
// JSON type overrides for ExecutionPayloadEnvelope.
|
||||
type executionPayloadEnvelopeMarshaling struct {
|
||||
BlockValue *hexutil.Big
|
||||
Requests []hexutil.Bytes
|
||||
}
|
||||
|
||||
// BlobsBundle includes the marshalled sidecar data. Note this structure is
|
||||
// shared by BlobsBundleV1 and BlobsBundleV2 for the sake of simplicity.
|
||||
//
|
||||
|
|
|
|||
3
go.mod
3
go.mod
|
|
@ -83,6 +83,7 @@ require (
|
|||
|
||||
require (
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/fjl/jsonw v0.0.0-20260519133611-b234a3a62a01 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect
|
||||
|
|
@ -121,7 +122,7 @@ require (
|
|||
github.com/deepmap/oapi-codegen v1.6.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.7.0 // indirect
|
||||
github.com/emicklei/dot v1.6.2 // indirect
|
||||
github.com/fjl/gencodec v0.1.0 // indirect
|
||||
github.com/fjl/gencodec v0.1.2 // indirect
|
||||
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect
|
||||
github.com/getsentry/sentry-go v0.27.0 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
|
|
|
|||
6
go.sum
6
go.sum
|
|
@ -125,6 +125,12 @@ github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeD
|
|||
github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg=
|
||||
github.com/fjl/gencodec v0.1.0 h1:B3K0xPfc52cw52BBgUbSPxYo+HlLfAgWMVKRWXUXBcs=
|
||||
github.com/fjl/gencodec v0.1.0/go.mod h1:Um1dFHPONZGTHog1qD1NaWjXJW/SPB38wPv0O8uZ2fI=
|
||||
github.com/fjl/gencodec v0.1.2 h1:nf+MMsmuii5ZQMbS6/xjZoe5LRkN0415FOJOSwmnuW8=
|
||||
github.com/fjl/gencodec v0.1.2/go.mod h1:chDHL3wKXuBgauP8x3XNZkl5EIAR5SoCTmmmDTZRzmw=
|
||||
github.com/fjl/jsonw v0.0.0-20260518201611-f2cd7df7ef66 h1:B+iPMRxXE3dbWXwQX6Un0MLOGGXXjj04gvWYD3pDrQE=
|
||||
github.com/fjl/jsonw v0.0.0-20260518201611-f2cd7df7ef66/go.mod h1:2KMLevM6FXEJnfhtk7naXu9vZdVfOma1GlnGdPRlumU=
|
||||
github.com/fjl/jsonw v0.0.0-20260519133611-b234a3a62a01 h1:2fvSvrrQMWs3l3MY1Ot4cPzv3Iww17ha1KJwjymX+Ks=
|
||||
github.com/fjl/jsonw v0.0.0-20260519133611-b234a3a62a01/go.mod h1:2KMLevM6FXEJnfhtk7naXu9vZdVfOma1GlnGdPRlumU=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
|
|
|
|||
Loading…
Reference in a new issue