core/state,core/types/bal: copy stateReadList in StateDB.Copy
Some checks failed
/ Linux Build (push) Has been cancelled
/ Linux Build (arm) (push) Has been cancelled
/ Keeper Build (push) Has been cancelled
/ Windows Build (push) Has been cancelled
/ Docker Image (push) Has been cancelled

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 <j-wasinger@hotmail.com>
This commit is contained in:
rayoo 2026-04-24 23:30:03 +08:00 committed by GitHub
parent 8091994e7b
commit b70d9a4b8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 0 deletions

View file

@ -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)

View file

@ -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
}