core/state: address comments

This commit is contained in:
Gary Rong 2024-06-03 10:30:44 +08:00
parent 21f97521aa
commit 8f5446246c

View file

@ -59,8 +59,8 @@ type stateObject struct {
dirtyStorage Storage // Storage entries that have been modified within the current transaction dirtyStorage Storage // Storage entries that have been modified within the current transaction
pendingStorage Storage // Storage entries that have been modified within the current block pendingStorage Storage // Storage entries that have been modified within the current block
// needCommit tracks a set of storage entries that have been modified but // uncommittedStorage tracks a set of storage entries that have been modified
// not yet committed since the "last commit operation", along with their // but not yet committed since the "last commit operation", along with their
// original values before mutation. // original values before mutation.
// //
// Specifically, the commit will be performed after each transaction before // Specifically, the commit will be performed after each transaction before
@ -68,7 +68,7 @@ type stateObject struct {
// boundary; however post the byzantium fork, the commit will only be performed // boundary; however post the byzantium fork, the commit will only be performed
// at the end of block, this set essentially tracks all the modifications // at the end of block, this set essentially tracks all the modifications
// made within the block. // made within the block.
needCommit Storage uncommittedStorage Storage
// Cache flags. // Cache flags.
dirtyCode bool // true if the code was updated dirtyCode bool // true if the code was updated
@ -97,15 +97,15 @@ func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *s
acct = types.NewEmptyStateAccount() acct = types.NewEmptyStateAccount()
} }
return &stateObject{ return &stateObject{
db: db, db: db,
address: address, address: address,
addrHash: crypto.Keccak256Hash(address[:]), addrHash: crypto.Keccak256Hash(address[:]),
origin: origin, origin: origin,
data: *acct, data: *acct,
originStorage: make(Storage), originStorage: make(Storage),
dirtyStorage: make(Storage), dirtyStorage: make(Storage),
pendingStorage: make(Storage), pendingStorage: make(Storage),
needCommit: make(Storage), uncommittedStorage: make(Storage),
} }
} }
@ -271,17 +271,17 @@ func (s *stateObject) setState(key common.Hash, value common.Hash, origin common
func (s *stateObject) finalise() { func (s *stateObject) finalise() {
slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage)) slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage))
for key, value := range s.dirtyStorage { for key, value := range s.dirtyStorage {
if origin, exist := s.needCommit[key]; exist && origin == value { if origin, exist := s.uncommittedStorage[key]; exist && origin == value {
// The slot is reverted to its original value, delete the entry // The slot is reverted to its original value, delete the entry
// to avoid thrashing the data structures. // to avoid thrashing the data structures.
delete(s.needCommit, key) delete(s.uncommittedStorage, key)
} else if exist { } else if exist {
// The slot is modified to another value and the slot has been // The slot is modified to another value and the slot has been
// tracked for commit, do nothing here. // tracked for commit, do nothing here.
} else { } else {
// The slot is different from its original value and hasn't been // The slot is different from its original value and hasn't been
// tracked for commit yet. // tracked for commit yet.
s.needCommit[key] = s.GetCommittedState(key) s.uncommittedStorage[key] = s.GetCommittedState(key)
slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure
} }
// Aggregate the dirty storage slots into the pending area. It might // Aggregate the dirty storage slots into the pending area. It might
@ -316,7 +316,7 @@ func (s *stateObject) finalise() {
// It assumes all the dirty storage slots have been finalized before. // It assumes all the dirty storage slots have been finalized before.
func (s *stateObject) updateTrie() (Trie, error) { func (s *stateObject) updateTrie() (Trie, error) {
// Short circuit if nothing changed, don't bother with hashing anything // Short circuit if nothing changed, don't bother with hashing anything
if len(s.needCommit) == 0 { if len(s.uncommittedStorage) == 0 {
return s.trie, nil return s.trie, nil
} }
// Retrieve a pretecher populated trie, or fall back to the database // Retrieve a pretecher populated trie, or fall back to the database
@ -345,9 +345,9 @@ func (s *stateObject) updateTrie() (Trie, error) {
// Whereas if the created node is handled first, then the collapse is avoided, and `B` is not resolved. // Whereas if the created node is handled first, then the collapse is avoided, and `B` is not resolved.
var ( var (
deletions []common.Hash deletions []common.Hash
used = make([][]byte, 0, len(s.needCommit)) used = make([][]byte, 0, len(s.uncommittedStorage))
) )
for key, origin := range s.needCommit { for key, origin := range s.uncommittedStorage {
// Skip noop changes, persist actual changes // Skip noop changes, persist actual changes
value, exist := s.pendingStorage[key] value, exist := s.pendingStorage[key]
if value == origin { if value == origin {
@ -380,7 +380,7 @@ func (s *stateObject) updateTrie() (Trie, error) {
if s.db.prefetcher != nil { if s.db.prefetcher != nil {
s.db.prefetcher.used(s.addrHash, s.data.Root, used) s.db.prefetcher.used(s.addrHash, s.data.Root, used)
} }
s.needCommit = make(Storage) // empties the commit markers s.uncommittedStorage = make(Storage) // empties the commit markers
return tr, nil return tr, nil
} }
@ -401,34 +401,34 @@ func (s *stateObject) updateRoot() {
func (s *stateObject) commitStorage(op *accountUpdate) { func (s *stateObject) commitStorage(op *accountUpdate) {
var ( var (
buf = crypto.NewKeccakState() buf = crypto.NewKeccakState()
encode = func(slot common.Hash) []byte { encode = func(val common.Hash) []byte {
if slot == (common.Hash{}) { if val == (common.Hash{}) {
return nil return nil
} }
blob, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(slot[:])) blob, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(val[:]))
return blob return blob
} }
) )
for key, slot := range s.pendingStorage { for key, val := range s.pendingStorage {
// Skip the noop storage changes, it might be possible the value // Skip the noop storage changes, it might be possible the value
// of tracked slot is same in originStorage and pendingStorage // of tracked slot is same in originStorage and pendingStorage
// map, e.g. the storage slot is modified in tx_a and then reset // map, e.g. the storage slot is modified in tx_a and then reset
// back in tx_b. // back in tx_b.
if slot == s.originStorage[key] { if val == s.originStorage[key] {
continue continue
} }
hash := crypto.HashData(buf, key[:]) hash := crypto.HashData(buf, key[:])
if op.storages == nil { if op.storages == nil {
op.storages = make(map[common.Hash][]byte) op.storages = make(map[common.Hash][]byte)
} }
op.storages[hash] = encode(slot) op.storages[hash] = encode(val)
if op.storagesOrigin == nil { if op.storagesOrigin == nil {
op.storagesOrigin = make(map[common.Hash][]byte) op.storagesOrigin = make(map[common.Hash][]byte)
} }
op.storagesOrigin[hash] = encode(s.originStorage[key]) op.storagesOrigin[hash] = encode(s.originStorage[key])
// Overwrite the clean value of storage slots // Overwrite the clean value of storage slots
s.originStorage[key] = slot s.originStorage[key] = val
} }
s.pendingStorage = make(Storage) s.pendingStorage = make(Storage)
} }
@ -444,9 +444,7 @@ func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) {
address: s.address, address: s.address,
data: types.SlimAccountRLP(s.data), data: types.SlimAccountRLP(s.data),
} }
if s.origin == nil { if s.origin != nil {
op.origin = nil // the account was not present
} else {
op.origin = types.SlimAccountRLP(*s.origin) op.origin = types.SlimAccountRLP(*s.origin)
} }
// commit the contract code if it's modified // commit the contract code if it's modified
@ -513,19 +511,19 @@ func (s *stateObject) setBalance(amount *uint256.Int) {
func (s *stateObject) deepCopy(db *StateDB) *stateObject { func (s *stateObject) deepCopy(db *StateDB) *stateObject {
obj := &stateObject{ obj := &stateObject{
db: db, db: db,
address: s.address, address: s.address,
addrHash: s.addrHash, addrHash: s.addrHash,
origin: s.origin, origin: s.origin,
data: s.data, data: s.data,
code: s.code, code: s.code,
originStorage: s.originStorage.Copy(), originStorage: s.originStorage.Copy(),
pendingStorage: s.pendingStorage.Copy(), pendingStorage: s.pendingStorage.Copy(),
dirtyStorage: s.dirtyStorage.Copy(), dirtyStorage: s.dirtyStorage.Copy(),
needCommit: s.needCommit.Copy(), uncommittedStorage: s.uncommittedStorage.Copy(),
dirtyCode: s.dirtyCode, dirtyCode: s.dirtyCode,
selfDestructed: s.selfDestructed, selfDestructed: s.selfDestructed,
newContract: s.newContract, newContract: s.newContract,
} }
if s.trie != nil { if s.trie != nil {
obj.trie = db.db.CopyTrie(s.trie) obj.trie = db.db.CopyTrie(s.trie)