Merge pull request #74 from barnabasbusa/bbusa/fix-amsterdam-genesis-block-access-list-hash-bal-devnet-4

core, beacon/engine, core/txpool, miner: bring bal-devnet-4 back to life
This commit is contained in:
Marius van der Wijden 2026-04-23 10:32:17 +02:00 committed by GitHub
commit 2f6a1a406a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 68 additions and 41 deletions

View file

@ -10,6 +10,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types/bal"
)
var _ = (*executableDataMarshaling)(nil)
@ -17,24 +18,25 @@ var _ = (*executableDataMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (e ExecutableData) MarshalJSON() ([]byte, error) {
type ExecutableData struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
BlockAccessList *bal.BlockAccessList `json:"blockAccessList"`
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
}
var enc ExecutableData
enc.ParentHash = e.ParentHash
@ -59,6 +61,7 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
enc.Withdrawals = e.Withdrawals
enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed)
enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas)
enc.BlockAccessList = e.BlockAccessList
enc.SlotNumber = (*hexutil.Uint64)(e.SlotNumber)
return json.Marshal(&enc)
}
@ -66,24 +69,25 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
// UnmarshalJSON unmarshals from JSON.
func (e *ExecutableData) UnmarshalJSON(input []byte) error {
type ExecutableData struct {
ParentHash *common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot *common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random *common.Hash `json:"prevRandao" gencodec:"required"`
Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash *common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
ParentHash *common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot *common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"`
Random *common.Hash `json:"prevRandao" gencodec:"required"`
Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"`
GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"`
ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"`
BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"`
BlockHash *common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
BlockAccessList *bal.BlockAccessList `json:"blockAccessList"`
SlotNumber *hexutil.Uint64 `json:"slotNumber,omitempty"`
}
var dec ExecutableData
if err := json.Unmarshal(input, &dec); err != nil {
@ -157,6 +161,9 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
if dec.ExcessBlobGas != nil {
e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas)
}
if dec.BlockAccessList != nil {
e.BlockAccessList = dec.BlockAccessList
}
if dec.SlotNumber != nil {
e.SlotNumber = (*uint64)(dec.SlotNumber)
}

View file

@ -556,6 +556,9 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block {
if head.SlotNumber == nil {
head.SlotNumber = new(uint64)
}
if head.BlockAccessListHash == nil {
head.BlockAccessListHash = &types.EmptyBlockAccessListHash
}
}
}
return types.NewBlock(head, &types.Body{Withdrawals: withdrawals}, nil, trie.NewStackTrie(nil))

View file

@ -134,8 +134,8 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
// We require transactions to pay for 110% of intrinsic gas in order to
// prevent situations where a change in gas limit invalidates a lot
// of transactions in the txpool
if tx.Gas() < (intrGas.RegularGas*10)/9 {
return fmt.Errorf("%w: gas %v, minimum needed %v", core.ErrIntrinsicGas, tx.Gas(), intrGas.RegularGas)
if minGas := (intrGas.RegularGas * 10) / 9; tx.Gas() < minGas {
return fmt.Errorf("%w: gas %v, minimum needed %v", core.ErrIntrinsicGas, tx.Gas(), minGas)
}
}
if tx.Gas() < intrGas.RegularGas {

View file

@ -43,6 +43,10 @@ var (
// EmptyRequestsHash is the known hash of an empty request set, sha256("").
EmptyRequestsHash = common.HexToHash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
// EmptyBlockAccessListHash is the known hash of an empty block access list,
// keccak256(rlp(empty list)) = keccak256(0xc0).
EmptyBlockAccessListHash = common.HexToHash("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
// EmptyBinaryHash is the known hash of an empty binary trie.
EmptyBinaryHash = common.Hash{}
)

View file

@ -151,12 +151,24 @@ func (miner *Miner) getPending() *newPayloadResult {
return cached
}
var (
timestamp = uint64(time.Now().Unix())
withdrawal types.Withdrawals
timestamp = uint64(time.Now().Unix())
childNumber = new(big.Int).Add(header.Number, big.NewInt(1))
withdrawal types.Withdrawals
slotNum *uint64
)
if miner.chainConfig.IsShanghai(new(big.Int).Add(header.Number, big.NewInt(1)), timestamp) {
if miner.chainConfig.IsShanghai(childNumber, timestamp) {
withdrawal = []*types.Withdrawal{}
}
// Post-Amsterdam, prepareWork requires a slot number (EIP-7843). The pending
// block is synthetic and has no canonical slot, so derive one from the parent
// when available and fall back to zero otherwise.
if miner.chainConfig.IsAmsterdam(childNumber, timestamp) {
var n uint64
if header.SlotNumber != nil {
n = *header.SlotNumber + 1
}
slotNum = &n
}
ret := miner.generateWork(context.Background(),
&generateParams{
timestamp: timestamp,
@ -166,6 +178,7 @@ func (miner *Miner) getPending() *newPayloadResult {
random: common.Hash{},
withdrawals: withdrawal,
beaconRoot: nil,
slotNum: slotNum,
noTxs: false,
}, false) // we will never make a witness for a pending block
if ret.err != nil {