Conversation
core/state/journal.go
Outdated
| func (ch suicideChange) revert(s *StateDB) { | ||
| obj := s.getStateObject(*ch.account) | ||
| var obj *StateObject | ||
| if s.parallel.isSlotDB { |
There was a problem hiding this comment.
we should abstract this into one function
core/state/state_object.go
Outdated
| 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 |
There was a problem hiding this comment.
that‘s fine , we will disable parallel mode if snap is nil
core/state/state_object.go
Outdated
| return common.Hash{}, false | ||
| } | ||
| s.originStorage[key] = val.(common.Hash) | ||
| // s.originStorage[key] = val.(common.Hash) |
core/state/state_object.go
Outdated
| return common.Hash{}, false | ||
| } | ||
| s.originStorage[key] = val.(common.Hash) | ||
| // s.originStorage[key] = val.(common.Hash) |
core/state/statedb.go
Outdated
| "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, |
There was a problem hiding this comment.
don't think directly read dirtyStorage and pendingStorage from StateObject is a good idea in StateDB
core/state/statedb.go
Outdated
| 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 { |
There was a problem hiding this comment.
in which case we will read pendingStorage
core/state/statedb.go
Outdated
| func (s *StateDB) unconfirmedLightCopy(obj *StateObject) *StateObject { | ||
| newObj := obj.lightCopy(s) | ||
| // do balance fixup | ||
| if balance := s.getBalanceFromUnconfirmedDB(obj.address); balance != nil { |
There was a problem hiding this comment.
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 {
core/state/statedb.go
Outdated
| 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 { |
There was a problem hiding this comment.
we also should avoid directly using the dirtyStorage and pendingStorage. we can abstract these to a function like obj.GetDirtiedState()
core/state/statedb.go
Outdated
| 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? |
There was a problem hiding this comment.
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.
core/state/statedb.go
Outdated
| } | ||
|
|
||
| // for addr state check of: Exist(), Empty() and HasSuicided() | ||
| func (s *StateDB) getAddrStateFromUnconfirmedDB(addr common.Address) *StateObject { |
There was a problem hiding this comment.
is there any difference between getStateObjectFromUnconfirmedDB and getAddrStateFromUnconfirmedDB
core/state/statedb.go
Outdated
| KVChangeReferred: make(map[common.Address]Storage), | ||
| } | ||
| } | ||
| if obj, ok := db.parallel.dirtiedStateObjectsInSlot[addr]; ok { |
There was a problem hiding this comment.
why check addrStateChangesInSlot here
core/state/statedb.go
Outdated
| KVChangeReferred: make(map[common.Address]Storage), // the KV pair should be exist | ||
| } | ||
| } | ||
| if obj, exist := db.parallel.dirtiedStateObjectsInSlot[addr]; exist { |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
maybe we need to check if we are in a slotdb before adding a lock
core/state/state_object.go
Outdated
| // 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 { |
There was a problem hiding this comment.
as discussed, we can come up with a better way to replace inMainDB
core/state/state_object.go
Outdated
| log.Info("StateObject::GetState loadStateObj") | ||
| // obj = mainObj | ||
| mainVal = mainObj.GetCommittedState(db, key) | ||
| if mainVal != val { |
There was a problem hiding this comment.
a bit confusing here why we need to check the committed state here
e495214 to
fdd2e52
Compare
* 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
4a6a8c0 to
f3863f3
Compare
9465788 to
2b8f975
Compare
9d2f607 to
be5e6eb
Compare
db72bc5 to
594eac2
Compare
06561f3 to
8d29534
Compare
d71911a to
fcf9572
Compare
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
fcf9572 to
ac492c6
Compare
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: