From d11ef8b62472edc6574a64798c849465a75cbe85 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Mon, 9 Jun 2025 13:41:48 +0200 Subject: [PATCH] core,miner,params: implement EIP-7934 - RLP Execution Block Size Limit --- core/block_validator.go | 3 +++ core/error.go | 4 ++++ miner/worker.go | 12 ++++++++++++ params/protocol_params.go | 2 ++ 4 files changed, 21 insertions(+) diff --git a/core/block_validator.go b/core/block_validator.go index 591e472bc1..a25fb7e69e 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -49,6 +49,9 @@ func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain) *Bloc // header's transaction and uncle roots. The headers are assumed to be already // validated at this point. func (v *BlockValidator) ValidateBody(block *types.Block) error { + if v.config.IsOsaka(block.Number(), block.Time()) && block.Size() > params.BlockRLPSizeCap { + return ErrBlockOversized + } // Check whether the block is already imported. if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) { return ErrKnownBlock diff --git a/core/error.go b/core/error.go index de95e64636..e50780bf1b 100644 --- a/core/error.go +++ b/core/error.go @@ -28,6 +28,10 @@ var ( // ErrNoGenesis is returned when there is no Genesis Block. ErrNoGenesis = errors.New("genesis not found in chain") + + // ErrBlockOversized is returned if the size of the RLP-encoded block + // exceeds the cap established by EIP 7934 + ErrBlockOversized = errors.New("block RLP-encoded size exceeds maximum") ) // List of evm-call-message pre-checking errors. All state transition messages will diff --git a/miner/worker.go b/miner/worker.go index 198745ad27..09cd94aa46 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -19,6 +19,7 @@ package miner import ( "errors" "fmt" + "github.com/ethereum/go-ethereum/trie" "math/big" "sync/atomic" "time" @@ -94,6 +95,13 @@ type generateParams struct { noTxs bool // Flag whether an empty block without any transaction is expected } +func (env *environment) encodedSizeWithTxAndReceipt(tx *types.Transaction) uint64 { + body := types.Body{Transactions: append(env.txs, tx), Withdrawals: make([]*types.Withdrawal, 0)} + env.header.RequestsHash = &common.Hash{} + block := types.NewBlock(env.header, &body, env.receipts, trie.NewStackTrie(nil)) + return block.Size() +} + // generateWork generates a sealing block based on the given parameters. func (miner *Miner) generateWork(params *generateParams, witness bool) *newPayloadResult { work, err := miner.prepareWork(params, witness) @@ -391,6 +399,10 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran continue } + if miner.chainConfig.IsOsaka(env.header.Number, env.header.Time) && env.encodedSizeWithTxAndReceipt(tx) > params.BlockRLPSizeCap { + break + } + // Make sure all transactions after osaka have cell proofs if miner.chainConfig.IsOsaka(env.header.Number, env.header.Time) { if sidecar := tx.BlobTxSidecar(); sidecar != nil { diff --git a/params/protocol_params.go b/params/protocol_params.go index 3676a7bdf1..029a52c5f3 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -178,6 +178,8 @@ const ( BlobBaseCost = 1 << 13 // Base execution gas cost for a blob. HistoryServeWindow = 8192 // Number of blocks to serve historical block hashes for, EIP-2935. + + BlockRLPSizeCap = 9_961_472 // maximum size of an RLP-encoded block ) // Bls12381G1MultiExpDiscountTable is the gas discount table for BLS12-381 G1 multi exponentiation operation