mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-11 17:31:35 +00:00
beacon/engin: add unmarshalJSON for epe and bapl structs
This commit is contained in:
parent
47b6d473f3
commit
5f909aa1d1
7 changed files with 526 additions and 84 deletions
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package engine
|
package engine
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
// estimateBlobAndProofV1Size returns a rough estimate of the JSON size for a BlobAndProofV1.
|
// estimateBlobAndProofV1Size returns a rough estimate of the JSON size for a BlobAndProofV1.
|
||||||
func estimateBlobAndProofV1Size(item *BlobAndProofV1) int {
|
func estimateBlobAndProofV1Size(item *BlobAndProofV1) int {
|
||||||
if item == nil {
|
if item == nil {
|
||||||
|
|
@ -87,6 +89,39 @@ func (list BlobAndProofListV1) MarshalJSON() ([]byte, error) {
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements json.Unmarshaler.
|
||||||
|
func (list *BlobAndProofListV1) UnmarshalJSON(input []byte) error {
|
||||||
|
if isJSONNull(input) {
|
||||||
|
*list = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
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.
|
// MarshalJSON implements json.Marshaler.
|
||||||
func (list BlobAndProofListV2) MarshalJSON() ([]byte, error) {
|
func (list BlobAndProofListV2) MarshalJSON() ([]byte, error) {
|
||||||
// Estimate buffer size.
|
// Estimate buffer size.
|
||||||
|
|
@ -107,3 +142,40 @@ func (list BlobAndProofListV2) MarshalJSON() ([]byte, error) {
|
||||||
buf = append(buf, ']')
|
buf = append(buf, ']')
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements json.Unmarshaler.
|
||||||
|
func (list *BlobAndProofListV2) UnmarshalJSON(input []byte) error {
|
||||||
|
if isJSONNull(input) {
|
||||||
|
*list = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -122,6 +122,57 @@ func TestBlobAndProofListV1MarshalJSON(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
func TestBlobAndProofListV2MarshalJSON(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
@ -186,6 +237,57 @@ func TestBlobAndProofListV2MarshalJSON(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
func TestBlobAndProofFieldCoverage(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
@ -17,10 +17,9 @@
|
||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"slices"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
)
|
)
|
||||||
|
|
@ -55,32 +54,26 @@ func marshalBlobsBundle(buf []byte, b *BlobsBundle) []byte {
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshalHexBytesArray writes an array of hex-encoded byte slices to buf.
|
func unmarshalBlobsBundle(input []byte) (*BlobsBundle, error) {
|
||||||
// A nil slice is written as "null" to match encoding/json semantics.
|
if isJSONNull(input) {
|
||||||
func marshalHexBytesArray(buf []byte, items []hexutil.Bytes) []byte {
|
return nil, nil
|
||||||
if items == nil {
|
|
||||||
return append(buf, "null"...)
|
|
||||||
}
|
}
|
||||||
buf = append(buf, '[')
|
var bundle BlobsBundle
|
||||||
for i, item := range items {
|
if err := decodeJSONObject(input, func(key string, value json.RawMessage) error {
|
||||||
if i > 0 {
|
var err error
|
||||||
buf = append(buf, ',')
|
switch key {
|
||||||
|
case "commitments":
|
||||||
|
bundle.Commitments, err = unmarshalHexBytesArray(value)
|
||||||
|
case "proofs":
|
||||||
|
bundle.Proofs, err = unmarshalHexBytesArray(value)
|
||||||
|
case "blobs":
|
||||||
|
bundle.Blobs, err = unmarshalHexBytesArray(value)
|
||||||
}
|
}
|
||||||
buf = writeHexBytes(buf, item)
|
return err
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
buf = append(buf, ']')
|
return &bundle, nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler.
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
|
@ -175,3 +168,85 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
|
||||||
buf = append(buf, '}')
|
buf = append(buf, '}')
|
||||||
return buf, nil
|
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
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -214,6 +214,100 @@ 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) {
|
func TestMarshalJSONNilPayload(t *testing.T) {
|
||||||
env := ExecutionPayloadEnvelope{
|
env := ExecutionPayloadEnvelope{
|
||||||
ExecutionPayload: nil,
|
ExecutionPayload: nil,
|
||||||
158
beacon/engine/codec_helper.go
Normal file
158
beacon/engine/codec_helper.go
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
@ -165,12 +165,6 @@ type BlobAndProofV2 struct {
|
||||||
// that avoids the overhead of encoding/json for large blob payloads.
|
// that avoids the overhead of encoding/json for large blob payloads.
|
||||||
type BlobAndProofListV2 []*BlobAndProofV2
|
type BlobAndProofListV2 []*BlobAndProofV2
|
||||||
|
|
||||||
// JSON type overrides for ExecutionPayloadEnvelope.
|
|
||||||
type executionPayloadEnvelopeMarshaling struct {
|
|
||||||
BlockValue *hexutil.Big
|
|
||||||
Requests []hexutil.Bytes
|
|
||||||
}
|
|
||||||
|
|
||||||
type PayloadStatusV1 struct {
|
type PayloadStatusV1 struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Witness *hexutil.Bytes `json:"witness,omitempty"`
|
Witness *hexutil.Bytes `json:"witness,omitempty"`
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue