|
|
|
@ -28,7 +28,6 @@ import ( |
|
|
|
|
"github.com/ethereum/go-ethereum/core/types" |
|
|
|
|
"github.com/ethereum/go-ethereum/crypto" |
|
|
|
|
"github.com/ethereum/go-ethereum/log" |
|
|
|
|
"github.com/ethereum/go-ethereum/metrics" |
|
|
|
|
"github.com/ethereum/go-ethereum/params" |
|
|
|
|
"github.com/ethereum/go-ethereum/trie" |
|
|
|
|
"github.com/ethereum/go-ethereum/trie/trienode" |
|
|
|
@ -495,9 +494,8 @@ func (s *StateDB) GetTransientState(addr common.Address, key common.Hash) common |
|
|
|
|
// updateStateObject writes the given object to the trie.
|
|
|
|
|
func (s *StateDB) updateStateObject(obj *stateObject) { |
|
|
|
|
// Track the amount of time wasted on updating the account from the trie
|
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) |
|
|
|
|
} |
|
|
|
|
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) |
|
|
|
|
|
|
|
|
|
// Encode the account and update the account trie
|
|
|
|
|
addr := obj.Address() |
|
|
|
|
if err := s.trie.UpdateAccount(addr, &obj.data); err != nil { |
|
|
|
@ -527,9 +525,8 @@ func (s *StateDB) updateStateObject(obj *stateObject) { |
|
|
|
|
// deleteStateObject removes the given object from the state trie.
|
|
|
|
|
func (s *StateDB) deleteStateObject(obj *stateObject) { |
|
|
|
|
// Track the amount of time wasted on deleting the account from the trie
|
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) |
|
|
|
|
} |
|
|
|
|
defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) |
|
|
|
|
|
|
|
|
|
// Delete the account from the trie
|
|
|
|
|
addr := obj.Address() |
|
|
|
|
if err := s.trie.DeleteAccount(addr); err != nil { |
|
|
|
@ -561,9 +558,8 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject { |
|
|
|
|
if s.snap != nil { |
|
|
|
|
start := time.Now() |
|
|
|
|
acc, err := s.snap.Account(crypto.HashData(s.hasher, addr.Bytes())) |
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
s.SnapshotAccountReads += time.Since(start) |
|
|
|
|
} |
|
|
|
|
s.SnapshotAccountReads += time.Since(start) |
|
|
|
|
|
|
|
|
|
if err == nil { |
|
|
|
|
if acc == nil { |
|
|
|
|
return nil |
|
|
|
@ -587,9 +583,8 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject { |
|
|
|
|
start := time.Now() |
|
|
|
|
var err error |
|
|
|
|
data, err = s.trie.GetAccount(addr) |
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
s.AccountReads += time.Since(start) |
|
|
|
|
} |
|
|
|
|
s.AccountReads += time.Since(start) |
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
s.setError(fmt.Errorf("getDeleteStateObject (%x) error: %w", addr.Bytes(), err)) |
|
|
|
|
return nil |
|
|
|
@ -917,9 +912,8 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { |
|
|
|
|
s.stateObjectsPending = make(map[common.Address]struct{}) |
|
|
|
|
} |
|
|
|
|
// Track the amount of time wasted on hashing the account trie
|
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) |
|
|
|
|
} |
|
|
|
|
defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) |
|
|
|
|
|
|
|
|
|
return s.trie.Hash() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1042,16 +1036,16 @@ func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, nil, err |
|
|
|
|
} |
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
n := int64(len(slots)) |
|
|
|
|
// Report the metrics
|
|
|
|
|
n := int64(len(slots)) |
|
|
|
|
|
|
|
|
|
slotDeletionMaxCount.UpdateIfGt(int64(len(slots))) |
|
|
|
|
slotDeletionMaxSize.UpdateIfGt(int64(size)) |
|
|
|
|
slotDeletionMaxCount.UpdateIfGt(int64(len(slots))) |
|
|
|
|
slotDeletionMaxSize.UpdateIfGt(int64(size)) |
|
|
|
|
|
|
|
|
|
slotDeletionTimer.UpdateSince(start) |
|
|
|
|
slotDeletionCount.Mark(n) |
|
|
|
|
slotDeletionSize.Mark(int64(size)) |
|
|
|
|
|
|
|
|
|
slotDeletionTimer.UpdateSince(start) |
|
|
|
|
slotDeletionCount.Mark(n) |
|
|
|
|
slotDeletionSize.Mark(int64(size)) |
|
|
|
|
} |
|
|
|
|
return slots, nodes, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1190,10 +1184,8 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// Write the account trie changes, measuring the amount of wasted time
|
|
|
|
|
var start time.Time |
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
start = time.Now() |
|
|
|
|
} |
|
|
|
|
start := time.Now() |
|
|
|
|
|
|
|
|
|
root, set, err := s.trie.Commit(true) |
|
|
|
|
if err != nil { |
|
|
|
|
return common.Hash{}, err |
|
|
|
@ -1205,23 +1197,23 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er |
|
|
|
|
} |
|
|
|
|
accountTrieNodesUpdated, accountTrieNodesDeleted = set.Size() |
|
|
|
|
} |
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
s.AccountCommits += time.Since(start) |
|
|
|
|
// Report the commit metrics
|
|
|
|
|
s.AccountCommits += time.Since(start) |
|
|
|
|
|
|
|
|
|
accountUpdatedMeter.Mark(int64(s.AccountUpdated)) |
|
|
|
|
storageUpdatedMeter.Mark(int64(s.StorageUpdated)) |
|
|
|
|
accountDeletedMeter.Mark(int64(s.AccountDeleted)) |
|
|
|
|
storageDeletedMeter.Mark(int64(s.StorageDeleted)) |
|
|
|
|
accountTrieUpdatedMeter.Mark(int64(accountTrieNodesUpdated)) |
|
|
|
|
accountTrieDeletedMeter.Mark(int64(accountTrieNodesDeleted)) |
|
|
|
|
storageTriesUpdatedMeter.Mark(int64(storageTrieNodesUpdated)) |
|
|
|
|
storageTriesDeletedMeter.Mark(int64(storageTrieNodesDeleted)) |
|
|
|
|
s.AccountUpdated, s.AccountDeleted = 0, 0 |
|
|
|
|
s.StorageUpdated, s.StorageDeleted = 0, 0 |
|
|
|
|
|
|
|
|
|
accountUpdatedMeter.Mark(int64(s.AccountUpdated)) |
|
|
|
|
storageUpdatedMeter.Mark(int64(s.StorageUpdated)) |
|
|
|
|
accountDeletedMeter.Mark(int64(s.AccountDeleted)) |
|
|
|
|
storageDeletedMeter.Mark(int64(s.StorageDeleted)) |
|
|
|
|
accountTrieUpdatedMeter.Mark(int64(accountTrieNodesUpdated)) |
|
|
|
|
accountTrieDeletedMeter.Mark(int64(accountTrieNodesDeleted)) |
|
|
|
|
storageTriesUpdatedMeter.Mark(int64(storageTrieNodesUpdated)) |
|
|
|
|
storageTriesDeletedMeter.Mark(int64(storageTrieNodesDeleted)) |
|
|
|
|
s.AccountUpdated, s.AccountDeleted = 0, 0 |
|
|
|
|
s.StorageUpdated, s.StorageDeleted = 0, 0 |
|
|
|
|
} |
|
|
|
|
// If snapshotting is enabled, update the snapshot tree with this new version
|
|
|
|
|
if s.snap != nil { |
|
|
|
|
start := time.Now() |
|
|
|
|
start = time.Now() |
|
|
|
|
// Only update if there's a state transition (skip empty Clique blocks)
|
|
|
|
|
if parent := s.snap.Root(); parent != root { |
|
|
|
|
if err := s.snaps.Update(root, parent, s.convertAccountSet(s.stateObjectsDestruct), s.accounts, s.storages); err != nil { |
|
|
|
@ -1235,9 +1227,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er |
|
|
|
|
log.Warn("Failed to cap snapshot tree", "root", root, "layers", 128, "err", err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
s.SnapshotCommits += time.Since(start) |
|
|
|
|
} |
|
|
|
|
s.SnapshotCommits += time.Since(start) |
|
|
|
|
s.snap = nil |
|
|
|
|
} |
|
|
|
|
if root == (common.Hash{}) { |
|
|
|
@ -1248,15 +1238,14 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er |
|
|
|
|
origin = types.EmptyRootHash |
|
|
|
|
} |
|
|
|
|
if root != origin { |
|
|
|
|
start := time.Now() |
|
|
|
|
start = time.Now() |
|
|
|
|
set := triestate.New(s.accountsOrigin, s.storagesOrigin) |
|
|
|
|
if err := s.db.TrieDB().Update(root, origin, block, nodes, set); err != nil { |
|
|
|
|
return common.Hash{}, err |
|
|
|
|
} |
|
|
|
|
s.originalRoot = root |
|
|
|
|
if metrics.EnabledExpensive { |
|
|
|
|
s.TrieDBCommits += time.Since(start) |
|
|
|
|
} |
|
|
|
|
s.TrieDBCommits += time.Since(start) |
|
|
|
|
|
|
|
|
|
if s.onCommit != nil { |
|
|
|
|
s.onCommit(set) |
|
|
|
|
} |
|
|
|
|