diff --git a/core/state/journal.go b/core/state/journal.go index c612aa9853..2f4a9af7d0 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -21,6 +21,7 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" ) // journalEntry is a modification entry in the state change journal that can be @@ -247,11 +248,20 @@ func (ch refundChange) dirtied() *common.Address { } func (ch addLogChange) revert(s *StateDB) { - logs := s.logs[ch.txhash] + logsInterface, ok := s.logs.Load(ch.txhash) + if !ok { + return + } + + logs, ok := logsInterface.([]*types.Log) + if !ok { + return + } + if len(logs) == 1 { - delete(s.logs, ch.txhash) + s.logs.Delete(ch.txhash) } else { - s.logs[ch.txhash] = logs[:len(logs)-1] + s.logs.Store(ch.txhash, logs[:len(logs)-1]) } s.logSize-- } diff --git a/core/state/statedb.go b/core/state/statedb.go index 2bddc39497..a9e775c568 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -98,7 +98,7 @@ type StateDB struct { thash, bhash common.Hash txIndex int - logs map[common.Hash][]*types.Log + logs sync.Map logSize uint preimages map[common.Hash][]byte @@ -142,6 +142,9 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) } // End Quorum - Privacy Enhancements + // Ensure mapping is type of map[common.Hash][]*types.Log + var logs sync.Map + sdb := &StateDB{ db: db, trie: tr, @@ -150,7 +153,7 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) stateObjects: make(map[common.Address]*stateObject), stateObjectsPending: make(map[common.Address]struct{}), stateObjectsDirty: make(map[common.Address]struct{}), - logs: make(map[common.Hash][]*types.Log), + logs: logs, preimages: make(map[common.Hash][]byte), journal: newJournal(), accessList: newAccessList(), @@ -202,25 +205,42 @@ func (s *StateDB) Error() error { } func (s *StateDB) AddLog(log *types.Log) { + s.journalMutex.Lock() s.journal.append(addLogChange{txhash: s.thash}) + s.journalMutex.Unlock() log.TxHash = s.thash log.BlockHash = s.bhash log.TxIndex = uint(s.txIndex) log.Index = s.logSize - s.logs[s.thash] = append(s.logs[s.thash], log) + + var logs []*types.Log + txHashLogs, ok := s.logs.Load(s.thash) + if ok { + logs = txHashLogs.([]*types.Log) + } + s.logs.Store(s.thash, append(logs, log)) + s.logSize++ } func (s *StateDB) GetLogs(hash common.Hash) []*types.Log { - return s.logs[hash] + txLogs, ok := s.logs.Load(hash) + if !ok { + return make([]*types.Log, 0) + } + return txLogs.([]*types.Log) } func (s *StateDB) Logs() []*types.Log { var logs []*types.Log - for _, lgs := range s.logs { - logs = append(logs, lgs...) - } + + s.logs.Range(func(key, value interface{}) bool { + logValue := value.([]*types.Log) + logs = append(logs, logValue...) + return true + }) + return logs } @@ -340,15 +360,20 @@ func (s *StateDB) Reset(root common.Hash) error { s.stateObjects = make(map[common.Address]*stateObject) s.stateObjectsPending = make(map[common.Address]struct{}) s.stateObjectsDirty = make(map[common.Address]struct{}) + s.logSize = 0 s.mutex.Unlock() s.thash = common.Hash{} s.bhash = common.Hash{} s.txIndex = 0 - s.logs = make(map[common.Hash][]*types.Log) - s.logSize = 0 s.preimages = make(map[common.Hash][]byte) s.clearJournalAndRefund() + // Clear all entries + s.logs.Range(func(key, value interface{}) bool { + s.logs.Delete(key) + return true + }) + if s.snaps != nil { s.snapAccounts, s.snapDestructs, s.snapStorage = nil, nil, nil if s.snap = s.snaps.Snapshot(root); s.snap != nil { @@ -816,6 +841,9 @@ func (s *StateDB) Copy() *StateDB { } journal.mutex.Unlock() + // Instantiate new copy of "logs" + var copyOfLogs sync.Map + // Copy all the basic fields, initialize the memory ones state := &StateDB{ db: s.db, @@ -824,7 +852,7 @@ func (s *StateDB) Copy() *StateDB { stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)), stateObjectsDirty: make(map[common.Address]struct{}, size), refund: s.refund, - logs: make(map[common.Hash][]*types.Log, len(s.logs)), + logs: copyOfLogs, logSize: s.logSize, preimages: make(map[common.Hash][]byte, len(s.preimages)), journal: newJournal(), @@ -866,14 +894,12 @@ func (s *StateDB) Copy() *StateDB { state.stateObjectsDirty[addr] = struct{}{} } s.mutex.Unlock() - for hash, logs := range s.logs { - cpy := make([]*types.Log, len(logs)) - for i, l := range logs { - cpy[i] = new(types.Log) - *cpy[i] = *l - } - state.logs[hash] = cpy - } + + s.logs.Range(func(key, value interface{}) bool { + state.logs.Store(key, value) + return true + }) + for hash, preimage := range s.preimages { state.preimages[hash] = preimage }