beacon/engine: correct rlp encoding/decoding (#35348)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Keeper Build (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run

Correctly passes BAL around in engine api

---------

Co-authored-by: Gary Rong <garyrong0905@gmail.com>
This commit is contained in:
Marius van der Wijden 2026-07-13 15:31:10 +02:00 committed by GitHub
parent f9382c2d1b
commit 68f711b9de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 109 additions and 91 deletions

View file

@ -10,7 +10,6 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types/bal"
) )
var _ = (*executableDataMarshaling)(nil) var _ = (*executableDataMarshaling)(nil)
@ -36,7 +35,7 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"` SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
BlockAccessList *bal.BlockAccessList `json:"blockAccessList,omitempty"` BlockAccessList hexutil.Bytes `json:"blockAccessList,omitempty"`
} }
var enc ExecutableData var enc ExecutableData
enc.ParentHash = e.ParentHash enc.ParentHash = e.ParentHash
@ -87,7 +86,7 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"` SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
BlockAccessList *bal.BlockAccessList `json:"blockAccessList,omitempty"` BlockAccessList *hexutil.Bytes `json:"blockAccessList,omitempty"`
} }
var dec ExecutableData var dec ExecutableData
if err := json.Unmarshal(input, &dec); err != nil { if err := json.Unmarshal(input, &dec); err != nil {
@ -165,7 +164,7 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
e.SlotNumber = (*uint64)(dec.SlotNumber) e.SlotNumber = (*uint64)(dec.SlotNumber)
} }
if dec.BlockAccessList != nil { if dec.BlockAccessList != nil {
e.BlockAccessList = dec.BlockAccessList e.BlockAccessList = *dec.BlockAccessList
} }
return nil return nil
} }

View file

@ -17,6 +17,7 @@
package engine package engine
import ( import (
"bytes"
"fmt" "fmt"
"math/big" "math/big"
"slices" "slices"
@ -25,7 +26,9 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types/bal" "github.com/ethereum/go-ethereum/core/types/bal"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
) )
@ -101,7 +104,7 @@ type ExecutableData struct {
BlobGasUsed *uint64 `json:"blobGasUsed"` BlobGasUsed *uint64 `json:"blobGasUsed"`
ExcessBlobGas *uint64 `json:"excessBlobGas"` ExcessBlobGas *uint64 `json:"excessBlobGas"`
SlotNumber *uint64 `json:"slotNumber,omitempty"` SlotNumber *uint64 `json:"slotNumber,omitempty"`
BlockAccessList *bal.BlockAccessList `json:"blockAccessList,omitempty"` BlockAccessList []byte `json:"blockAccessList,omitempty"`
} }
// JSON type overrides for executableData. // JSON type overrides for executableData.
@ -117,6 +120,7 @@ type executableDataMarshaling struct {
BlobGasUsed *hexutil.Uint64 BlobGasUsed *hexutil.Uint64
ExcessBlobGas *hexutil.Uint64 ExcessBlobGas *hexutil.Uint64
SlotNumber *hexutil.Uint64 SlotNumber *hexutil.Uint64
BlockAccessList hexutil.Bytes
} }
// StatelessPayloadStatusV1 is the result of a stateless payload execution. // StatelessPayloadStatusV1 is the result of a stateless payload execution.
@ -320,7 +324,7 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H
// to be nil. // to be nil.
var blockAccessListHash *common.Hash var blockAccessListHash *common.Hash
if data.BlockAccessList != nil { if data.BlockAccessList != nil {
hash := data.BlockAccessList.Hash() hash := crypto.Keccak256Hash(data.BlockAccessList)
blockAccessListHash = &hash blockAccessListHash = &hash
} }
header := &types.Header{ header := &types.Header{
@ -347,7 +351,15 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H
SlotNumber: data.SlotNumber, SlotNumber: data.SlotNumber,
BlockAccessListHash: blockAccessListHash, BlockAccessListHash: blockAccessListHash,
} }
return types.NewBlockWithHeader(header).WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals}), nil body := types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals}
if data.BlockAccessList != nil {
var accessList bal.BlockAccessList
if err := rlp.DecodeBytes(data.BlockAccessList, &accessList); err != nil {
return nil, fmt.Errorf("failed to decode BAL: %w", err)
}
return types.NewBlockWithHeader(header).WithBody(body).WithAccessListUnsafe(&accessList), nil
}
return types.NewBlockWithHeader(header).WithBody(body), nil
} }
// BlockToExecutableData constructs the ExecutableData structure by filling the // BlockToExecutableData constructs the ExecutableData structure by filling the
@ -372,7 +384,12 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
BlobGasUsed: block.BlobGasUsed(), BlobGasUsed: block.BlobGasUsed(),
ExcessBlobGas: block.ExcessBlobGas(), ExcessBlobGas: block.ExcessBlobGas(),
SlotNumber: block.SlotNumber(), SlotNumber: block.SlotNumber(),
BlockAccessList: block.AccessList(), }
if al := block.AccessList(); al != nil {
var buf bytes.Buffer
if err := rlp.Encode(&buf, al); err == nil {
data.BlockAccessList = buf.Bytes()
}
} }
// Add blobs. // Add blobs.

View file

@ -806,6 +806,8 @@ func (api *ConsensusAPI) NewPayloadV5(ctx context.Context, params engine.Executa
return invalidStatus, paramsErr("nil executionRequests post-prague") return invalidStatus, paramsErr("nil executionRequests post-prague")
case params.SlotNumber == nil: case params.SlotNumber == nil:
return invalidStatus, paramsErr("nil slotnumber post-amsterdam") return invalidStatus, paramsErr("nil slotnumber post-amsterdam")
case params.BlockAccessList == nil:
return invalidStatus, paramsErr("nil block access list post-amsterdam")
case !api.checkFork(params.Timestamp, forks.Amsterdam): case !api.checkFork(params.Timestamp, forks.Amsterdam):
return invalidStatus, unsupportedForkErr("newPayloadV5 must only be called for amsterdam payloads") return invalidStatus, unsupportedForkErr("newPayloadV5 must only be called for amsterdam payloads")
} }