diff --git a/core/state/access_list.go b/core/state/access_list.go index 419469134..942829787 100644 --- a/core/state/access_list.go +++ b/core/state/access_list.go @@ -134,3 +134,36 @@ func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) { func (al *accessList) DeleteAddress(address common.Address) { delete(al.addresses, address) } + +// Copy creates an independent copy of an accessList. +func (dest *accessList) Append(src *accessList) *accessList { + for addr, sIdx := range src.addresses { + if i, present := dest.addresses[addr]; present { + // dest already has addr. + if sIdx >= 0 { + // has slot in list + if i == -1 { + dest.addresses[addr] = len(dest.slots) + slotmap := src.slots[sIdx] + dest.slots = append(dest.slots, slotmap) + } else { + slotmap := src.slots[sIdx] + for hash := range slotmap { + if _, ok := dest.slots[i][hash]; !ok { + dest.slots[i][hash] = struct{}{} + } + } + } + } + } else { + // dest doesn't have the address + dest.addresses[addr] = -1 + if sIdx >= 0 { + dest.addresses[addr] = len(dest.slots) + slotmap := src.slots[sIdx] + dest.slots = append(dest.slots, slotmap) + } + } + } + return dest +} diff --git a/core/state/state_object.go b/core/state/state_object.go index d2f988c6c..ac0b95dac 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -1004,7 +1004,7 @@ func (s *stateObject) GetCommittedStateNoUpdate(key common.Hash) common.Hash { func (s *stateObject) fixUpOriginAndResetPendingStorage() { if s.db.isParallel && s.db.parallel.isSlotDB { mainDB := s.db.parallel.baseStateDB - origObj := mainDB.getStateObjectNoUpdate(s.address) + origObj := mainDB.getStateObject(s.address) s.storageRecordsLock.Lock() if origObj != nil && origObj.originStorage.Length() != 0 { // There can be racing issue with CopyForSlot/LightCopy diff --git a/core/state/statedb.go b/core/state/statedb.go index 7b959f444..e814343bf 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -2652,8 +2652,9 @@ func (s *StateDB) MergeSlotDB(slotDb *ParallelStateDB, slotReceipt *types.Receip for hash, preimage := range slotDb.preimages { s.preimages[hash] = preimage } + if s.accessList != nil && slotDb.accessList != nil { - s.accessList = slotDb.accessList.Copy() + s.accessList.Append(slotDb.accessList) } for k := range slotDb.snapDestructs {