diff --git a/core/blockchain.go b/core/blockchain.go index 6c87ffc708..cdfe9f5ffc 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2112,10 +2112,10 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er var followupInterrupt uint32 // For diff sync, it may fallback to full sync, so we still do prefetch if len(block.Transactions()) >= prefetchTxNumber { - throwaway := statedb.Copy() + //throwaway := statedb.Copy() go func(start time.Time, followup *types.Block, throwaway *state.StateDB, interrupt *uint32) { bc.prefetcher.Prefetch(followup, throwaway, bc.vmConfig, &followupInterrupt) - }(time.Now(), block, throwaway, &followupInterrupt) + }(time.Now(), block, statedb, &followupInterrupt) } //Process block using the parent state as reference point substart := time.Now() diff --git a/core/state/shared_pool.go b/core/state/shared_pool.go index 1b8ae50f09..ea00a31b8a 100644 --- a/core/state/shared_pool.go +++ b/core/state/shared_pool.go @@ -13,15 +13,15 @@ type SharedStorage struct { shared_map map[common.Address]sync.Map } -func NewSharedStorage() SharedStorage { +func NewSharedStorage() *SharedStorage { sharedMap := make(map[common.Address]sync.Map, 1000) - return SharedStorage{ + return &SharedStorage{ poolLock: &sync.RWMutex{}, shared_map: sharedMap, } } -func (storage *SharedStorage) GetStorage(address common.Address, key common.Hash) (interface{}, bool) { +func (storage *SharedStorage) getStorage(address common.Address, key common.Hash) (interface{}, bool) { storage.poolLock.RLock() storageMap, ok := storage.shared_map[address] storage.poolLock.RUnlock() diff --git a/core/state/state_object.go b/core/state/state_object.go index d5086da8c2..7d8a8fd6ef 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -79,8 +79,6 @@ type StateObject struct { trie Trie // storage trie, which becomes non-nil on first access code Code // contract bytecode, which gets set when code is loaded - //originStorage *sync.Map // Storage cache of original entries to dedup rewrites, reset for every transaction - pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block dirtyStorage Storage // Storage entries that have been modified in the current transaction execution fakeStorage Storage // Fake storage which constructed by caller for debugging purpose. @@ -122,15 +120,13 @@ func newObject(db *StateDB, address common.Address, data Account) *StateObject { data.Root = emptyRoot } // Check whether the storage exist in pool, new originStorage if not exist - db.sharedStorage.checkSharedStorage(address) return &StateObject{ - db: db, - address: address, - addrHash: crypto.Keccak256Hash(address[:]), - data: data, - // originStorage: &storageMap, + db: db, + address: address, + addrHash: crypto.Keccak256Hash(address[:]), + data: data, pendingStorage: make(Storage), dirtyStorage: make(Storage), } @@ -325,8 +321,8 @@ func (s *StateObject) finalise(prefetch bool) { } for key, value := range s.dirtyStorage { - originValue, _ := s.db.getOriginStorage(s.address, key) - if value != originValue.(common.Hash) { + originValue, cached := s.db.getOriginStorage(s.address, key) + if cached && value != originValue.(common.Hash) { slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure } } @@ -362,8 +358,8 @@ func (s *StateObject) updateTrie(db Database) Trie { usedStorage := make([][]byte, 0, len(s.pendingStorage)) for key, value := range s.pendingStorage { // Skip noop changes, persist actual changes - originValue, _ := s.db.getOriginStorage(s.address, key) - if value == originValue.(common.Hash) { + originValue, cached := s.db.getOriginStorage(s.address, key) + if cached && value == originValue.(common.Hash) { continue } s.db.setOriginStorage(s.address, key, value) diff --git a/core/state/statedb.go b/core/state/statedb.go index b8f56c2f7f..a8fbe3233a 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -102,7 +102,7 @@ type StateDB struct { stateObjectsDirty map[common.Address]struct{} // State objects modified in the current execution // shared_pool to store L1 originStorage of stateObjects - sharedStorage SharedStorage + sharedStorage *SharedStorage // DB error. // State objects are used by the consensus core and VM which are @@ -1646,7 +1646,7 @@ func (s *StateDB) GetDirtyAccounts() []common.Address { } func (s *StateDB) getOriginStorage(address common.Address, key common.Hash) (interface{}, bool) { - return s.sharedStorage.GetStorage(address, key) + return s.sharedStorage.getStorage(address, key) } func (s *StateDB) setOriginStorage(address common.Address, key common.Hash, val common.Hash) {