From 73944e3299253e3dd1f7ec309412bd2074b8825c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Kov=C3=A1=C5=99?= Date: Fri, 8 May 2026 00:32:49 +0200 Subject: [PATCH] core: record SetParentBeaconRoot beacon-root accesses in BAL (#34897) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `SetParentBeaconRoot`, which is used by hivechain block customization (`modifyBlock` passed to `GenerateChain` as `gen`), runs `ProcessBeaconBlockRoot`, but those accesses are not being recorded in BALs. Later, `GenerateChain` processes beacon root again with BAL tracking, so BAL could miss earlier mutations. This patch keeps current flow but records reads/writes from `SetParentBeaconRoot` into the BAL when enabled. That fixes accounting mismatch without changing execution order. I tried to find a better solution which would avoid double beacon root processing but kept running into PMT root mismatches. This is the minimal working solution, and a temporary workaround to enable correct Amsterdam block generation anyway. Long-term we should move to a single canonical beacon-root processing path (or explicit idempotent handling) so execution and BAL accounting happen exactly once. Used by https://github.com/ethereum/hive/pull/1468 to enable Amsterdam block generation in hivechain. Signed-off-by: Miroslav Kovář --- core/chain_makers.go | 11 ++++++++++- core/chain_makers_test.go | 27 ++++++++++++--------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/core/chain_makers.go b/core/chain_makers.go index 17bdd8ffa8..c2ca5064c6 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -80,6 +80,11 @@ func (b *BlockGen) SetNonce(nonce types.BlockNonce) { b.header.Nonce = nonce } +// SetSlotNumber sets the slot number field of the generated block. +func (b *BlockGen) SetSlotNumber(slot uint64) { + b.header.SlotNumber = &slot +} + // SetDifficulty sets the difficulty field of the generated block. This method is // useful for Clique tests where the difficulty does not depend on time. For the // ethash tests, please use OffsetTime, which implicitly recalculates the diff. @@ -102,7 +107,11 @@ func (b *BlockGen) Difficulty() *big.Int { func (b *BlockGen) SetParentBeaconRoot(root common.Hash) { b.header.ParentBeaconRoot = &root blockContext := NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase) - ProcessBeaconBlockRoot(root, vm.NewEVM(blockContext, b.statedb, b.cm.config, vm.Config{})) + reads, writes := ProcessBeaconBlockRoot(root, vm.NewEVM(blockContext, b.statedb, b.cm.config, vm.Config{})) + if b.accessList != nil { + b.accessList.AddBlockInitMutations(writes) + b.accessList.AddAccesses(reads) + } } // addTx adds a transaction to the generated block. If no coinbase has diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 5bb05653b8..657824c4d7 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -236,7 +236,7 @@ func TestGenerateBALChain(t *testing.T) { // TODO: I think we can remove SetBeaconRoot entirely // and provide a different mechanism to set it? - // gen.SetParentBeaconRoot(common.Hash{byte(i + 1)}) + gen.SetParentBeaconRoot(common.Hash{byte(i + 1)}) if gspec.Config.IsAmsterdam(gen.header.Number, gen.header.Time) { // TODO: parameterize the slot num @@ -333,20 +333,17 @@ func TestGenerateBALChain(t *testing.T) { withdrawalIndex += 1 } - // TODO: can we reinstate the following? - /* - // Verify parent beacon root. - want := common.Hash{byte(blocknum)} - if got := block.BeaconRoot(); *got != want { - t.Fatalf("block %d, wrong parent beacon root: got %s, want %s", i, got, want) - } - state, _ := blockchain.State() - idx := block.Time()%8191 + 8191 - got := state.GetState(params.BeaconRootsAddress, common.BigToHash(new(big.Int).SetUint64(idx))) - if got != want { - t.Fatalf("block %d, wrong parent beacon root in state: got %s, want %s", i, got, want) - } - */ + // Verify parent beacon root. + want := common.Hash{byte(blocknum)} + if got := block.BeaconRoot(); *got != want { + t.Fatalf("block %d, wrong parent beacon root: got %s, want %s", i, got, want) + } + state, _ := blockchain.State() + idx := block.Time()%8191 + 8191 + got := state.GetState(params.BeaconRootsAddress, common.BigToHash(new(big.Int).SetUint64(idx))) + if got != want { + t.Fatalf("block %d, wrong parent beacon root in state: got %s, want %s", i, got, want) + } } }