mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
Update exec_header.go
Improve error handling and optimize JSON decoding for execution headers
This commit is contained in:
parent
80b529ea71
commit
b0d941fef1
1 changed files with 23 additions and 12 deletions
|
|
@ -17,6 +17,7 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
|
@ -28,18 +29,21 @@ import (
|
||||||
"github.com/protolambda/ztyp/tree"
|
"github.com/protolambda/ztyp/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// headerObject is an interface that defines the method to get the HashTreeRoot.
|
||||||
type headerObject interface {
|
type headerObject interface {
|
||||||
HashTreeRoot(hFn tree.HashFn) zrntcommon.Root
|
HashTreeRoot(hFn tree.HashFn) zrntcommon.Root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecutionHeader holds a reference to an object that implements the headerObject interface.
|
||||||
type ExecutionHeader struct {
|
type ExecutionHeader struct {
|
||||||
obj headerObject
|
obj headerObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecutionHeaderFromJSON decodes an execution header from JSON data provided by
|
// ExecutionHeaderFromJSON decodes an execution header from JSON data provided by the beacon chain API.
|
||||||
// the beacon chain API.
|
// It selects the appropriate fork (capella, deneb) and unmarshals the data accordingly.
|
||||||
func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, error) {
|
func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, error) {
|
||||||
var obj headerObject
|
var obj headerObject
|
||||||
|
|
||||||
switch forkName {
|
switch forkName {
|
||||||
case "capella":
|
case "capella":
|
||||||
obj = new(capella.ExecutionPayloadHeader)
|
obj = new(capella.ExecutionPayloadHeader)
|
||||||
|
|
@ -48,33 +52,40 @@ func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, er
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unsupported fork: %s", forkName)
|
return nil, fmt.Errorf("unsupported fork: %s", forkName)
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(data, obj); err != nil {
|
|
||||||
return nil, err
|
// Use a streaming decoder for efficiency, especially with large JSON payloads
|
||||||
|
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||||
|
if err := decoder.Decode(obj); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to unmarshal execution header for fork %s: %w", forkName, err)
|
||||||
}
|
}
|
||||||
return &ExecutionHeader{obj: obj}, nil
|
return &ExecutionHeader{obj: obj}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewExecutionHeader initializes a new ExecutionHeader object with the given headerObject.
|
||||||
|
// It ensures the object type is one of the supported ExecutionPayloadHeaders (capella, deneb).
|
||||||
func NewExecutionHeader(obj headerObject) *ExecutionHeader {
|
func NewExecutionHeader(obj headerObject) *ExecutionHeader {
|
||||||
switch obj.(type) {
|
switch obj.(type) {
|
||||||
case *capella.ExecutionPayloadHeader:
|
case *capella.ExecutionPayloadHeader, *deneb.ExecutionPayloadHeader:
|
||||||
case *deneb.ExecutionPayloadHeader:
|
// Supported types
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unsupported ExecutionPayloadHeader type %T", obj))
|
panic(fmt.Errorf("unsupported ExecutionPayloadHeader type %T", obj))
|
||||||
}
|
}
|
||||||
return &ExecutionHeader{obj: obj}
|
return &ExecutionHeader{obj: obj}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PayloadRoot returns the Merkle root of the execution payload header.
|
||||||
func (eh *ExecutionHeader) PayloadRoot() merkle.Value {
|
func (eh *ExecutionHeader) PayloadRoot() merkle.Value {
|
||||||
return merkle.Value(eh.obj.HashTreeRoot(tree.GetHashFn()))
|
return merkle.Value(eh.obj.HashTreeRoot(tree.GetHashFn()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BlockHash extracts the block hash from the underlying execution payload header.
|
||||||
|
// It checks the type of the object and returns the correct block hash based on the type.
|
||||||
func (eh *ExecutionHeader) BlockHash() common.Hash {
|
func (eh *ExecutionHeader) BlockHash() common.Hash {
|
||||||
switch obj := eh.obj.(type) {
|
if obj, ok := eh.obj.(*capella.ExecutionPayloadHeader); ok {
|
||||||
case *capella.ExecutionPayloadHeader:
|
|
||||||
return common.Hash(obj.BlockHash)
|
return common.Hash(obj.BlockHash)
|
||||||
case *deneb.ExecutionPayloadHeader:
|
}
|
||||||
|
if obj, ok := eh.obj.(*deneb.ExecutionPayloadHeader); ok {
|
||||||
return common.Hash(obj.BlockHash)
|
return common.Hash(obj.BlockHash)
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("unsupported ExecutionPayloadHeader type %T", obj))
|
|
||||||
}
|
}
|
||||||
|
panic(fmt.Errorf("unsupported ExecutionPayloadHeader type %T", eh.obj))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue