diff --git a/arbitrum/recordingdb.go b/arbitrum/recordingdb.go index f7fd01752..c7a3f3472 100644 --- a/arbitrum/recordingdb.go +++ b/arbitrum/recordingdb.go @@ -32,17 +32,19 @@ type RecordingKV struct { inner *triedb.Database diskDb ethdb.KeyValueStore readDbEntries map[common.Hash][]byte + mutex sync.Mutex enableBypass bool } func newRecordingKV(inner *triedb.Database, diskDb ethdb.KeyValueStore) *RecordingKV { - return &RecordingKV{inner, diskDb, make(map[common.Hash][]byte), false} + return &RecordingKV{inner, diskDb, make(map[common.Hash][]byte), sync.Mutex{}, false} } func (db *RecordingKV) Has(key []byte) (bool, error) { return false, errors.New("recording KV doesn't support Has") } +// Get may be called concurrently with other Get calls func (db *RecordingKV) Get(key []byte) ([]byte, error) { var hash common.Hash var res []byte @@ -66,6 +68,8 @@ func (db *RecordingKV) Get(key []byte) ([]byte, error) { if crypto.Keccak256Hash(res) != hash { return nil, fmt.Errorf("recording KV attempted to access non-hash key %v", hash) } + db.mutex.Lock() + defer db.mutex.Unlock() db.readDbEntries[hash] = res return res, nil } diff --git a/core/state/statedb.go b/core/state/statedb.go index 6fa69d6d2..e0c8caa9c 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -18,7 +18,6 @@ package state import ( - "bytes" "errors" "fmt" "maps" @@ -898,32 +897,15 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { // later time. workers.SetLimit(1) } - if s.deterministic { - addressesToUpdate := make([]common.Address, 0, len(s.mutations)) - for addr := range s.mutations { - addressesToUpdate = append(addressesToUpdate, addr) - } - sort.Slice(addressesToUpdate, func(i, j int) bool { return bytes.Compare(addressesToUpdate[i][:], addressesToUpdate[j][:]) < 0 }) - for _, addr := range addressesToUpdate { - if obj := s.mutations[addr]; !obj.applied && !obj.isDelete() { - obj := s.stateObjects[addr] // closure for the task runner below - workers.Go(func() error { - obj.updateRoot() - return nil - }) - } - } - } else { - for addr, op := range s.mutations { - if op.applied || op.isDelete() { - continue - } - obj := s.stateObjects[addr] // closure for the task runner below - workers.Go(func() error { - obj.updateRoot() - return nil - }) + for addr, op := range s.mutations { + if op.applied || op.isDelete() { + continue } + obj := s.stateObjects[addr] // closure for the task runner below + workers.Go(func() error { + obj.updateRoot() + return nil + }) } workers.Wait() s.StorageUpdates += time.Since(start) @@ -968,6 +950,9 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { } usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure } + if s.deterministic { + sort.Slice(deletedAddrs, func(i, j int) bool { return deletedAddrs[i].Cmp(deletedAddrs[j]) < 0 }) + } for _, deletedAddr := range deletedAddrs { s.deleteStateObject(deletedAddr) s.AccountDeleted += 1