From cd945a64775a4c78bab47299c72cc35e871bcea2 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Tue, 10 Mar 2026 16:21:01 +0100 Subject: [PATCH] core: verify BAL gas limit --- core/blockchain.go | 5 +++++ core/types/bal/bal_encoding.go | 25 +++++++++++++++++++++++++ params/protocol_params.go | 2 ++ 3 files changed, 32 insertions(+) diff --git a/core/blockchain.go b/core/blockchain.go index d88687c245..6345e05609 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2418,6 +2418,11 @@ func (bc *BlockChain) ProcessBlock(ctx context.Context, parentRoot common.Hash, bc.reportBadBlock(block, res, err) return nil, err } + // EIP-7928: Validate BAL items do not exceed block gas limit + if err := computedAccessList.ValidateGasLimit(block.Header().GasLimit); err != nil { + bc.reportBadBlock(block, res, err) + return nil, err + } if block.AccessList() == nil { // attach the computed access list to the block so it gets persisted // when the block is written to disk diff --git a/core/types/bal/bal_encoding.go b/core/types/bal/bal_encoding.go index 124b7712c9..25d8bedc01 100644 --- a/core/types/bal/bal_encoding.go +++ b/core/types/bal/bal_encoding.go @@ -131,6 +131,31 @@ func (e BlockAccessList) Validate(blockTxCount int) error { return nil } +// ValidateGasLimit checks that the total number of BAL items (addresses + +// unique storage keys) does not exceed block_gas_limit / GasBlockAccessListItem. +// See EIP-7928 validate_block_access_list_gas_limit. +func (e BlockAccessList) ValidateGasLimit(blockGasLimit uint64) error { + var balItems uint64 + for _, account := range e { + // Count each address as one item + balItems++ + // Count unique storage keys across both reads and writes + uniqueSlots := make(map[common.Hash]struct{}) + for _, sc := range account.StorageChanges { + uniqueSlots[sc.Slot.ToHash()] = struct{}{} + } + for _, sr := range account.StorageReads { + uniqueSlots[sr.ToHash()] = struct{}{} + } + balItems += uint64(len(uniqueSlots)) + } + limit := blockGasLimit / params.GasBlockAccessListItem + if balItems > limit { + return fmt.Errorf("block access list exceeds gas limit: %d items exceeds limit of %d", balItems, limit) + } + return nil +} + // Hash computes the keccak256 hash of the access list func (e *BlockAccessList) Hash() common.Hash { var enc bytes.Buffer diff --git a/params/protocol_params.go b/params/protocol_params.go index a729b938f5..f2c6b5f1c9 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -192,6 +192,8 @@ const ( AccountCreationSize = 112 StorageCreationSize = 32 AuthorizationCreationSize = 23 + + GasBlockAccessListItem = 2000 // EIP-7928: gas cost per BAL item for gas limit check ) // Bls12381G1MultiExpDiscountTable is the gas discount table for BLS12-381 G1 multi exponentiation operation