From ededc0f2384f2560987e91323ab629d61eaadd71 Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Tue, 19 May 2026 10:50:34 +0800 Subject: [PATCH] core: check nilness before validating bal --- core/block_validator.go | 23 ++++++++++++++--------- core/types/bal/bal_encoding.go | 4 ++-- core/types/bal/bal_test.go | 7 ++++--- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/core/block_validator.go b/core/block_validator.go index e91eadabff..4086a2ead7 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -115,23 +115,22 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { // Amsterdam hard fork. if v.config.IsAmsterdam(block.Number(), block.Time()) { if block.Header().BlockAccessListHash == nil { - return fmt.Errorf("block access list hash not set in header") + return errors.New("block access list hash not set in header") } - // If the block does not come with an access list, we compute the access list - // locally as part of execution and validate against the header's access list - // hash. + // If the block does not include an access list, compute it locally during + // execution and validate it against the access list hash in the header. + // + // If the block includes an attached access list, validate it directly here. if block.AccessList() != nil { computed := block.AccessList().Hash() if *block.Header().BlockAccessListHash != computed { return fmt.Errorf("access list hash mismatch, computed: %x, remote: %x", computed, *block.Header().BlockAccessListHash) - } else if err := block.AccessList().Validate(); err != nil { - return fmt.Errorf("invalid block access list: %v", err) - } else if err := block.AccessList().ValidateSize(block.GasLimit()); err != nil { + } else if err := block.AccessList().Validate(block.GasLimit()); err != nil { return fmt.Errorf("invalid block access list: %v", err) } } } else if block.Header().BlockAccessListHash != nil || block.AccessList() != nil { - return fmt.Errorf("block had access list before Amsterdam") + return errors.New("block had access list before Amsterdam") } // Ancestor block must be known. @@ -185,12 +184,18 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD } // Verify Block-level accessList once Amsterdam is enabled if v.config.IsAmsterdam(block.Number(), block.Time()) { + if res.Bal == nil { + return errors.New("block access list is not available in amsterdam") + } + if block.Header().BlockAccessListHash == nil { + return errors.New("block access list hash not set in header") + } enc := res.Bal.ToEncodingObj() local, remote := enc.Hash(), *block.Header().BlockAccessListHash if local != remote { return fmt.Errorf("access list hash mismatch, local: %x, remote: %x", local, remote) } - if err := enc.ValidateSize(block.GasLimit()); err != nil { + if err := enc.Validate(block.GasLimit()); err != nil { return fmt.Errorf("invalid block access list: %v", err) } } diff --git a/core/types/bal/bal_encoding.go b/core/types/bal/bal_encoding.go index d53ccdc1b0..399f9db7c0 100644 --- a/core/types/bal/bal_encoding.go +++ b/core/types/bal/bal_encoding.go @@ -78,7 +78,7 @@ func (e *BlockAccessList) DecodeRLP(s *rlp.Stream) error { // Validate returns an error if the contents of the access list are not ordered // according to the spec or any code changes are contained which exceed protocol // max code size. -func (e *BlockAccessList) Validate() error { +func (e *BlockAccessList) Validate(blockGasLimit uint64) error { if !slices.IsSortedFunc(*e, func(a, b AccountAccess) int { return bytes.Compare(a.Address[:], b.Address[:]) }) { @@ -89,7 +89,7 @@ func (e *BlockAccessList) Validate() error { return err } } - return nil + return e.ValidateSize(blockGasLimit) } // itemCount returns the number of items in the BAL for EIP-7928 size-constraint diff --git a/core/types/bal/bal_test.go b/core/types/bal/bal_test.go index e65ac6edee..2b6a3c194e 100644 --- a/core/types/bal/bal_test.go +++ b/core/types/bal/bal_test.go @@ -19,6 +19,7 @@ package bal import ( "bytes" "cmp" + "math" "reflect" "slices" "testing" @@ -357,7 +358,7 @@ func TestBlockAccessListValidateSize(t *testing.T) { func TestBlockAccessListValidation(t *testing.T) { // Validate the block access list after RLP decoding enc := makeTestBAL(true) - if err := enc.Validate(); err != nil { + if err := enc.Validate(math.MaxUint64); err != nil { t.Fatalf("Unexpected validation error: %v", err) } var buf bytes.Buffer @@ -369,14 +370,14 @@ func TestBlockAccessListValidation(t *testing.T) { if err := dec.DecodeRLP(rlp.NewStream(bytes.NewReader(buf.Bytes()), 0)); err != nil { t.Fatalf("Unexpected RLP-decode error: %v", err) } - if err := dec.Validate(); err != nil { + if err := dec.Validate(math.MaxUint64); err != nil { t.Fatalf("Unexpected validation error: %v", err) } // Validate the derived block access list cBAL := makeTestConstructionBAL() listB := cBAL.ToEncodingObj() - if err := listB.Validate(); err != nil { + if err := listB.Validate(math.MaxUint64); err != nil { t.Fatalf("Unexpected validation error: %v", err) } }