Skip to content

Commit

Permalink
pevm-opt: lock free localstateObjects (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
sunny2022da authored Sep 9, 2024
1 parent 2aa009d commit 1b233e1
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
2 changes: 2 additions & 0 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1956,6 +1956,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
Expand Down
11 changes: 9 additions & 2 deletions core/state/parallel_statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,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)
}
Expand Down Expand Up @@ -224,7 +229,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 {
Expand Down Expand Up @@ -1816,7 +1821,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)
Expand All @@ -1825,6 +1831,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{})
Expand Down
27 changes: 20 additions & 7 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
}
Expand All @@ -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)
Expand All @@ -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.
Expand Down Expand Up @@ -967,9 +975,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
}
Expand Down Expand Up @@ -1265,7 +1277,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{}),
Expand Down

0 comments on commit 1b233e1

Please sign in to comment.