From decfab7f6f5be856f2516e2945160eaad0007b32 Mon Sep 17 00:00:00 2001 From: rayoo Date: Fri, 24 Apr 2026 23:30:03 +0800 Subject: [PATCH] core/state,core/types/bal: copy stateReadList in StateDB.Copy The stateReadList field introduced by #34776 to track the state access footprint for EIP-7928 was not propagated by StateDB.Copy. Every other per-transaction field that lives alongside it (accessList, transientStorage, journal, witness, accessEvents) is copied explicitly, so this field was simply missed. After Copy the copy's stateReadList is nil while the original keeps its entries, so the nil-safe guards on StateAccessList.AddAccount / AddState silently drop every access recorded on the copy. For any post-Amsterdam code path that copies a prepared state and keeps reading from the copy, the BAL footprint becomes incomplete. Add a Copy method on bal.StateAccessList and invoke it from StateDB.Copy, matching the pattern used for accessList and accessEvents. --------- Co-authored-by: jwasinger --- core/state/statedb.go | 3 +++ core/types/bal/access_list.go | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/core/state/statedb.go b/core/state/statedb.go index 5d94d4806d..1858f4758d 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -716,6 +716,9 @@ func (s *StateDB) Copy() *StateDB { if s.accessEvents != nil { state.accessEvents = s.accessEvents.Copy() } + if s.stateReadList != nil { + state.stateReadList = s.stateReadList.Copy() + } // Deep copy cached state objects. for addr, obj := range s.stateObjects { state.stateObjects[addr] = obj.deepCopy(state) diff --git a/core/types/bal/access_list.go b/core/types/bal/access_list.go index 91da5ebcb7..e563fa22e2 100644 --- a/core/types/bal/access_list.go +++ b/core/types/bal/access_list.go @@ -78,3 +78,17 @@ func (s *StateAccessList) Merge(other *StateAccessList) { maps.Copy(slots, otherSlots) } } + +// Copy returns a deep copy of the StateAccessList. +func (s *StateAccessList) Copy() *StateAccessList { + if s == nil { + return nil + } + cpy := &StateAccessList{ + list: make(map[common.Address]StorageAccessList, len(s.list)), + } + for addr, slots := range s.list { + cpy.list[addr] = maps.Clone(slots) + } + return cpy +}