diff --git a/core/blockchain.go b/core/blockchain.go index 71ae310e66..c43b7a9f69 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1913,6 +1913,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error) log.Debug("Disable Parallel Tx execution", "block", block.NumberU64(), "transactions", txsCount, "parallelTxNum", bc.vmConfig.ParallelTxNum) } else { bc.UseParallelProcessor() + log.Debug("Enable Parallel Tx execution", "block", block.NumberU64(), "transactions", txsCount, "parallelTxNum", bc.vmConfig.ParallelTxNum) + } } // If we have a followup block, run that against the current state to pre-cache diff --git a/core/state/parallel_statedb.go b/core/state/parallel_statedb.go index 46253d5cec..1d9a7bf0ae 100644 --- a/core/state/parallel_statedb.go +++ b/core/state/parallel_statedb.go @@ -139,6 +139,11 @@ func NewSlotDB(db *StateDB, txIndex int, baseTxIndex int, manager *ParallelDBMan } func (s *ParallelStateDB) PutSyncPool(parallelDBManager *ParallelDBManager) { + for key := range s.parallel.locatStateObjects { + delete(s.parallel.locatStateObjects, key) + } + addressToStateObjectsPool.Put(s.parallel.locatStateObjects) + for key := range s.parallel.codeReadsInSlot { delete(s.parallel.codeReadsInSlot, key) } @@ -266,7 +271,7 @@ func (s *ParallelStateDB) getStateObject(addr common.Address) *stateObject { func (s *ParallelStateDB) storeStateObj(addr common.Address, stateObject *stateObject) { // The object could be created in SlotDB, if it got the object from DB and // update it to the `s.parallel.stateObjects` - s.parallel.stateObjects.Store(addr, stateObject) + s.parallel.locatStateObjects[addr] = stateObject } func (s *ParallelStateDB) getStateObjectNoSlot(addr common.Address) *stateObject { @@ -1860,7 +1865,8 @@ func (s *ParallelStateDB) reset() { s.parallel.isSlotDB = true s.parallel.SlotIndex = -1 - s.parallel.stateObjects = &StateObjectSyncMap{} + s.parallel.stateObjects = nil + s.parallel.locatStateObjects = nil s.parallel.baseStateDB = nil s.parallel.baseTxIndex = -1 s.parallel.dirtiedStateObjectsInSlot = addressToStateObjectsPool.Get().(map[common.Address]*stateObject) @@ -1869,6 +1875,7 @@ func (s *ParallelStateDB) reset() { s.parallel.nonceReadsInSlot = addressToUintPool.Get().(map[common.Address]uint64) s.parallel.balanceChangesInSlot = addressToStructPool.Get().(map[common.Address]struct{}) s.parallel.balanceReadsInSlot = balancePool.Get().(map[common.Address]*big.Int) + s.parallel.locatStateObjects = addressToStateObjectsPool.Get().(map[common.Address]*stateObject) s.parallel.codeReadsInSlot = addressToBytesPool.Get().(map[common.Address][]byte) s.parallel.codeHashReadsInSlot = addressToHashPool.Get().(map[common.Address]common.Hash) s.parallel.codeChangesInSlot = addressToStructPool.Get().(map[common.Address]struct{}) diff --git a/core/state/statedb.go b/core/state/statedb.go index 92439dc361..7b959f4440 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -84,7 +84,7 @@ func (s *StateObjectSyncMap) StoreStateObject(addr common.Address, stateObject * func (s *StateDB) loadStateObj(addr common.Address) (*stateObject, bool) { if s.isParallel { if s.parallel.isSlotDB { - if ret, ok := s.parallel.stateObjects.LoadStateObject(addr); ok { + if ret, ok := s.parallel.locatStateObjects[addr]; ok { return ret, ok } else { ret, ok := s.parallel.baseStateDB.loadStateObj(addr) @@ -102,7 +102,11 @@ func (s *StateDB) loadStateObj(addr common.Address) (*stateObject, bool) { // storeStateObj is the entry for storing state object to stateObjects in StateDB or stateObjects in parallel func (s *StateDB) storeStateObj(addr common.Address, stateObject *stateObject) { if s.isParallel { - s.parallel.stateObjects.StoreStateObject(addr, stateObject) + if s.parallel.isSlotDB { + s.parallel.locatStateObjects[addr] = stateObject + } else { + s.parallel.stateObjects.StoreStateObject(addr, stateObject) + } } else { s.stateObjects[addr] = stateObject } @@ -111,6 +115,9 @@ func (s *StateDB) storeStateObj(addr common.Address, stateObject *stateObject) { // deleteStateObj is the entry for deleting state object to stateObjects in StateDB or stateObjects in parallel func (s *StateDB) deleteStateObj(addr common.Address) { if s.isParallel { + if s.parallel.isSlotDB { + delete(s.parallel.locatStateObjects, addr) + } s.parallel.stateObjects.Delete(addr) } else { delete(s.stateObjects, addr) @@ -122,7 +129,8 @@ type ParallelState struct { isSlotDB bool // denotes StateDB is used in slot, we will try to remove it SlotIndex int // for debug // stateObjects holds the state objects in the base slot db - stateObjects *StateObjectSyncMap + stateObjects *StateObjectSyncMap + locatStateObjects map[common.Address]*stateObject baseStateDB *StateDB // for parallel mode, there will be a base StateDB in dispatcher routine. baseTxIndex int // slotDB is created base on this tx index. @@ -968,9 +976,13 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject { func (s *StateDB) setStateObject(object *stateObject) { if s.isParallel { - // When a state object is stored into s.parallel.stateObjects, - // it belongs to base StateDB, it is confirmed and valid. - s.parallel.stateObjects.Store(object.address, object) + if s.parallel.isSlotDB { + s.parallel.locatStateObjects[object.address] = object + } else { + // When a state object is stored into s.parallel.stateObjects, + // it belongs to base StateDB, it is confirmed and valid. + s.parallel.stateObjects.Store(object.address, object) + } } else { s.stateObjects[object.Address()] = object } @@ -1266,7 +1278,8 @@ func NewEmptySlotDB() *ParallelStateDB { // // We are not do simple copy (lightweight pointer copy) as the stateObject can be accessed by different thread. - stateObjects: &StateObjectSyncMap{}, // s.parallel.stateObjects, + stateObjects: nil, /* The parallel execution will not use this field, except the base DB */ + locatStateObjects: addressToStateObjectsPool.Get().(map[common.Address]*stateObject), codeReadsInSlot: addressToBytesPool.Get().(map[common.Address][]byte), codeHashReadsInSlot: addressToHashPool.Get().(map[common.Address]common.Hash), codeChangesInSlot: addressToStructPool.Get().(map[common.Address]struct{}),