From f59ec20794b37921d0fcfbe6c4566f558c092207 Mon Sep 17 00:00:00 2001 From: MariusVanDerWijden Date: Wed, 29 Apr 2026 12:41:52 +0200 Subject: [PATCH] core: misc fixes (claude) --- core/state/statedb.go | 18 ++++++++++++++++++ miner/worker.go | 12 ++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index cf2b918a9d..e40916c504 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -771,6 +771,24 @@ func (s *StateDB) CloseSnapshot(revid int) { s.journal.closeSnapshot(revid) } +// SnapshotReadList returns a deep copy of the current EIP-7928 state-read list. +// Pair with RestoreReadList: callers that may discard a transaction attempt +// (e.g. the miner reverting a failed tx via RevertToSnapshot) should restore +// the read list as well, since reads are not journaled and would otherwise +// leak into the next BAL emission via engine.Finalize. +func (s *StateDB) SnapshotReadList() *bal.StateAccessList { + if s.stateReadList == nil { + return nil + } + return s.stateReadList.Copy() +} + +// RestoreReadList replaces the current EIP-7928 state-read list with the given +// snapshot. See SnapshotReadList for the motivation. +func (s *StateDB) RestoreReadList(snap *bal.StateAccessList) { + s.stateReadList = snap +} + // GetRefund returns the current value of the refund counter. func (s *StateDB) GetRefund() uint64 { return s.refund diff --git a/miner/worker.go b/miner/worker.go index 0d590e4a3b..8ca9dbfa83 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -444,13 +444,21 @@ func (miner *Miner) commitBlobTransaction(env *environment, tx *types.Transactio // applyTransaction runs the transaction. If execution fails, state and gas pool are reverted. func (miner *Miner) applyTransaction(env *environment, tx *types.Transaction) (*types.Receipt, error) { var ( - snap = env.state.Snapshot() - gp = env.gasPool.Snapshot() + snap = env.state.Snapshot() + gp = env.gasPool.Snapshot() + readSnap = env.state.SnapshotReadList() ) txAccesses, txMutations, receipt, err := core.ApplyTransaction(env.evm, env.gasPool, env.state, env.header, tx) if err != nil { env.state.RevertToSnapshot(snap) env.gasPool.Set(gp) + // EIP-7928 BAL: reads accumulated during a failed-Go-error tx + // (e.g. preCheck reads sender's nonce/balance/code before Prepare resets the + // per-tx read list) are not journaled and survive RevertToSnapshot. If left + // in place they leak into the live state-read list and ultimately into the + // BAL via engine.Finalize, producing a hash mismatch with validators that + // only re-execute the txs sealed in the block. + env.state.RestoreReadList(readSnap) return nil, err } if env.accessList != nil {