Skip to content

Parallel 2.0 dev#1

Open
lunarblock wants to merge 2 commits intolunarblock:larry_2.0_basefrom
setunapo:parallel_2.0_dev
Open

Parallel 2.0 dev#1
lunarblock wants to merge 2 commits intolunarblock:larry_2.0_basefrom
setunapo:parallel_2.0_dev

Conversation

@lunarblock
Copy link
Owner

Description

add a description of your changes here...

Rationale

tell us why we need these changes...

Example

add an example CLI or API response...

Changes

Notable changes:

  • add each change in a bullet point here
  • ...

func (ch suicideChange) revert(s *StateDB) {
obj := s.getStateObject(*ch.account)
var obj *StateObject
if s.parallel.isSlotDB {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should abstract this into one function

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I will try to remove this code.

meter = &s.db.StorageReads
}
if enc, err = s.getTrie(db).TryGet(key.Bytes()); err != nil {
if enc, err = s.getTrie(db).TryGet(key.Bytes()); err != nil { // fixme: handle trie concurrent safe
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that‘s fine , we will disable parallel mode if snap is nil

return common.Hash{}, false
}
s.originStorage[key] = val.(common.Hash)
// s.originStorage[key] = val.(common.Hash)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we comment this

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there will be a concurrent issue.

return common.Hash{}, false
}
s.originStorage[key] = val.(common.Hash)
// s.originStorage[key] = val.(common.Hash)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why delete this

"addr", addr)
// 1.Try to get from dirty
if val, ok := obj.dirtyStorage[hash]; ok {
log.Info("GetState key in dirty", "SlotIndex", s.parallel.SlotIndex, "txIndex", s.txIndex,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't think directly read dirtyStorage and pendingStorage from StateObject is a good idea in StateDB

return val
}
// 2.Try to get from pending, it is for merge to get KV from finalized StateObject.
if val, ok := obj.pendingStorage[hash]; ok {
Copy link

@yutianwu yutianwu Apr 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in which case we will read pendingStorage

func (s *StateDB) unconfirmedLightCopy(obj *StateObject) *StateObject {
newObj := obj.lightCopy(s)
// do balance fixup
if balance := s.getBalanceFromUnconfirmedDB(obj.address); balance != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

		newStateObject := s.unconfirmedLightCopy(stateObject)
		newStateObject.AddBalance(amount)
		s.parallel.dirtiedStateObjectsInSlot[addr] = newStateObject

since we will set dirtiedStateObjectsInSlot after unconfirmedLightCopy, why getBalanceFromUnconfirmedDB since it will always return nil.

if obj, exist := db.parallel.dirtiedStateObjectsInSlot[addr]; exist {

if obj, ok := db.parallel.dirtiedStateObjectsInSlot[addr]; ok { // if deleted on merge, can get from main StateDB, ok but fixme: concurrent safe
if _, ok := db.parallel.stateChangesInSlot[addr]; ok {
// fixme: dirtyStorage will be cleared on StateObject.finalize, to keep the KV in stateChangesInSlot?
if val, exist := obj.dirtyStorage[key]; exist {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also should avoid directly using the dirtyStorage and pendingStorage. we can abstract these to a function like obj.GetDirtiedState()

BalanceChangeReferred map[common.Address]*big.Int
CodeChangeReferred map[common.Address]struct{} // fixme: codehash to compare? it may not necessary
// NonceChangeSet map[common.Address]struct{} // nonce should be reliable, it is not necessary
AddrStateReferred map[common.Address]struct{} // the address of StateObject we refer, or the state change?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any possibility that we add an address to AddrStateReferred and then we get the changed code but not add it to CodeChangeReferred. or do we check it in the conflict check.

}

// for addr state check of: Exist(), Empty() and HasSuicided()
func (s *StateDB) getAddrStateFromUnconfirmedDB(addr common.Address) *StateObject {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any difference between getStateObjectFromUnconfirmedDB and getAddrStateFromUnconfirmedDB

KVChangeReferred: make(map[common.Address]Storage),
}
}
if obj, ok := db.parallel.dirtiedStateObjectsInSlot[addr]; ok {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why check addrStateChangesInSlot here

KVChangeReferred: make(map[common.Address]Storage), // the KV pair should be exist
}
}
if obj, exist := db.parallel.dirtiedStateObjectsInSlot[addr]; exist {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why check addrStateChangesInSlot here

// have been handles via pendingStorage above.
// 2) we don't have new values, and can deliver empty response back
if _, destructed := s.db.snapDestructs[s.address]; destructed {
s.db.snapParallelLock.RLock()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we need to check if we are in a slotdb before adding a lock

// fixme: if s is light copied, access mainStateDB's stateobject's dirty, if lightCopy's dirty missed
val := s.GetCommittedState(db, key)
var mainVal common.Hash
if !s.inMainDB {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as discussed, we can come up with a better way to replace inMainDB

log.Info("StateObject::GetState loadStateObj")
// obj = mainObj
mainVal = mainObj.GetCommittedState(db, key)
if mainVal != val {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit confusing here why we need to check the committed state here

lunarblock added a commit that referenced this pull request Apr 12, 2022
* add sync pool for slotdb and remove deepCopy for mergeSlotDB

* don't panic if there is anything wrong reading state

* use map in sequential mode and sync.map in parallel mode

* fix the comments
@setunapo setunapo deleted the parallel_2.0_dev branch April 13, 2022 00:11
@setunapo setunapo force-pushed the parallel_2.0_dev branch 6 times, most recently from 4a6a8c0 to f3863f3 Compare April 13, 2022 10:18
@setunapo setunapo force-pushed the parallel_2.0_dev branch 6 times, most recently from 9465788 to 2b8f975 Compare April 21, 2022 10:05
@setunapo setunapo force-pushed the parallel_2.0_dev branch 9 times, most recently from 9d2f607 to be5e6eb Compare April 26, 2022 05:44
@setunapo setunapo force-pushed the parallel_2.0_dev branch 16 times, most recently from db72bc5 to 594eac2 Compare May 6, 2022 02:08
@setunapo setunapo force-pushed the parallel_2.0_dev branch from 06561f3 to 8d29534 Compare May 18, 2022 02:16
@setunapo setunapo force-pushed the parallel_2.0_dev branch from d71911a to fcf9572 Compare May 20, 2022 07:02
1.features of 2.0:
  ** Streaming Pipeline
  ** Implement universal unconfirmed state db reference, try best to get account object state.
  ** New conflict detect, check based on what it has read.
  ** Do parallel KV conflict check for large KV read
  ** new Interface StateDBer and ParallelStateDB
  ** shared memory pool for parallel objects
  ** use map in sequential mode and sync.map in parallel mode for concurrent StateObject access
  ** replace DeepCopy by LightCopy to avoid redundant memory copy of StateObject
  ** do trie prefetch in advance
  ** dispatcher 2.0
     Static Dispatch & Dynamic Dispatch
     Stolen mode for TxReq when a slot finished its static dispatched tasks
     RealTime result confirm in Stage2, when most if the tx have been executed at least once
     Make it configurable

2.Handle of corner case:
 ** don't panic if there is anything wrong reading state
 ** handle system address, skip its balance check
 ** handle WBNB contract to reduce conflict rate by balance make up
    WBNB balance makeup by GetBalanceOpCode & depth
    add a lock to fix WBNB make up concurrent crash
    add a new interface GetBalanceOpCode
@setunapo setunapo force-pushed the parallel_2.0_dev branch from fcf9572 to ac492c6 Compare May 20, 2022 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants