Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ func (s *stateObject) updateTrie() (Trie, error) {
// into a shortnode. This requires `B` to be resolved from disk.
// Whereas if the created node is handled first, then the collapse is avoided, and `B` is not resolved.
var (
keys = make([][]byte, 0, len(s.uncommittedStorage))
values = make([][]byte, 0, len(s.uncommittedStorage))
deletions []common.Hash
used = make([]common.Hash, 0, len(s.uncommittedStorage))
)
Expand All @@ -360,17 +362,23 @@ func (s *stateObject) updateTrie() (Trie, error) {
continue
}
if (value != common.Hash{}) {
if err := tr.UpdateStorage(s.address, key[:], common.TrimLeftZeroes(value[:])); err != nil {
s.db.setError(err)
return nil, err
}
s.db.StorageUpdated.Add(1)
keys = append(keys, key.Bytes())
values = append(values, common.TrimLeftZeroes(value.Bytes()))
} else {
deletions = append(deletions, key)
}
// Cache the items for preloading
used = append(used, key) // Copy needed for closure
}
// Apply the updates in batch mode, allowing the trie nodes on the paths
// to be resolved concurrently.
if len(keys) > 0 {
if err := tr.UpdateStorageBatch(s.address, keys, values); err != nil {
s.db.setError(err)
return nil, err
}
s.db.StorageUpdated.Add(int64(len(keys)))
}
for _, key := range deletions {
if err := tr.DeleteStorage(s.address, key[:]); err != nil {
s.db.setError(err)
Expand Down
44 changes: 26 additions & 18 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,17 +571,6 @@ func (s *StateDB) GetTransientState(addr common.Address, key common.Hash) common
// Setting, updating & deleting state object methods.
//

// updateStateObject writes the given object to the trie.
func (s *StateDB) updateStateObject(obj *stateObject) {
// Encode the account and update the account trie
if err := s.trie.UpdateAccount(obj.Address(), &obj.data, len(obj.code)); err != nil {
s.setError(fmt.Errorf("updateStateObject (%x) error: %v", obj.Address(), err))
}
if obj.dirtyCode {
s.trie.UpdateContractCode(obj.Address(), common.BytesToHash(obj.CodeHash()), obj.code)
}
}

// deleteStateObject removes the given object from the state trie.
func (s *StateDB) deleteStateObject(addr common.Address) {
if err := s.trie.DeleteAccount(addr); err != nil {
Expand Down Expand Up @@ -1072,8 +1061,12 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
// into a shortnode. This requires `B` to be resolved from disk.
// Whereas if the created node is handled first, then the collapse is avoided, and `B` is not resolved.
var (
usedAddrs []common.Address
deletedAddrs []common.Address
usedAddrs = make([]common.Address, 0, len(s.mutations))
updatedAddrs = make([]common.Address, 0, len(s.mutations))
accounts = make([]*types.StateAccount, 0, len(s.mutations))
codeLens = make([]int, 0, len(s.mutations))
dirtyCodeObjs []*stateObject
deletedAddrs []common.Address
)
for addr, op := range s.mutations {
if op.applied {
Expand All @@ -1085,17 +1078,32 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
deletedAddrs = append(deletedAddrs, addr)
} else {
obj := s.stateObjects[addr]
s.updateStateObject(obj)
s.AccountUpdated += 1
updatedAddrs = append(updatedAddrs, addr)
accounts = append(accounts, &obj.data)
codeLens = append(codeLens, len(obj.code))

// Count code writes post-Finalise so reverted CREATEs are excluded.
if obj.dirtyCode {
s.CodeUpdated += 1
s.CodeUpdateBytes += len(obj.code)
dirtyCodeObjs = append(dirtyCodeObjs, obj)
}
}
usedAddrs = append(usedAddrs, addr) // Copy needed for closure
}
// Apply the account updates in batch mode, allowing the trie nodes on the
// paths to be resolved concurrently.
if len(updatedAddrs) > 0 {
if err := s.trie.UpdateAccountBatch(updatedAddrs, accounts, codeLens); err != nil {
s.setError(fmt.Errorf("account update error: %v", err))
}
s.AccountUpdated += len(updatedAddrs)
}
// Apply the code updates after the account updates.
for _, obj := range dirtyCodeObjs {
s.trie.UpdateContractCode(obj.Address(), common.BytesToHash(obj.CodeHash()), obj.code)

// Count code writes post-Finalise so reverted CREATEs are excluded.
s.CodeUpdated += 1
s.CodeUpdateBytes += len(obj.code)
}
for _, deletedAddr := range deletedAddrs {
s.deleteStateObject(deletedAddr)
s.AccountDeleted += 1
Expand Down
Loading