mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 05:36:46 +00:00
fix: trienode calculate
Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
parent
2ddf19a15a
commit
116f327c27
1 changed files with 76 additions and 49 deletions
|
|
@ -31,6 +31,14 @@ import (
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
accountSnapKeySize = int64(len(rawdb.SnapshotAccountPrefix) + common.HashLength)
|
||||||
|
storageSnapKeySize = int64(len(rawdb.SnapshotStoragePrefix) + common.HashLength + common.HashLength)
|
||||||
|
accountTrieKeyPrefixSize = int64(len(rawdb.TrieNodeAccountPrefix))
|
||||||
|
storageTrieKeyPrefixSize = int64(len(rawdb.TrieNodeStoragePrefix) + common.HashLength)
|
||||||
|
codeKeySize = int64(len(rawdb.CodePrefix) + common.HashLength)
|
||||||
|
)
|
||||||
|
|
||||||
// stateSizeMetrics represents the current state size statistics
|
// stateSizeMetrics represents the current state size statistics
|
||||||
type stateSizeMetrics struct {
|
type stateSizeMetrics struct {
|
||||||
Root common.Hash // Root hash of the state trie
|
Root common.Hash // Root hash of the state trie
|
||||||
|
|
@ -180,7 +188,6 @@ func (g *StateSizeGenerator) initialize() chan struct{} {
|
||||||
|
|
||||||
// handleUpdate processes a single update with proper root continuity checking
|
// handleUpdate processes a single update with proper root continuity checking
|
||||||
func (g *StateSizeGenerator) handleUpdate(update *stateUpdate, initialized bool) {
|
func (g *StateSizeGenerator) handleUpdate(update *stateUpdate, initialized bool) {
|
||||||
// Calculate the diff
|
|
||||||
diff := g.calculateUpdateDiff(update)
|
diff := g.calculateUpdateDiff(update)
|
||||||
|
|
||||||
var targetMetrics *stateSizeMetrics
|
var targetMetrics *stateSizeMetrics
|
||||||
|
|
@ -192,12 +199,7 @@ func (g *StateSizeGenerator) handleUpdate(update *stateUpdate, initialized bool)
|
||||||
|
|
||||||
// Check root continuity - the update should build on our current state
|
// Check root continuity - the update should build on our current state
|
||||||
if targetMetrics.Root != (common.Hash{}) && targetMetrics.Root != update.originRoot {
|
if targetMetrics.Root != (common.Hash{}) && targetMetrics.Root != update.originRoot {
|
||||||
log.Warn("State update root discontinuity detected",
|
log.Warn("State update root discontinuity detected", "current", targetMetrics.Root, "updateOrigin", update.originRoot, "updateNew", update.root)
|
||||||
"current", targetMetrics.Root,
|
|
||||||
"updateOrigin", update.originRoot,
|
|
||||||
"updateNew", update.root)
|
|
||||||
// For now, we accept the discontinuity but log it
|
|
||||||
// In production, you might want to reset metrics or handle differently
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update to the new state root
|
// Update to the new state root
|
||||||
|
|
@ -230,15 +232,20 @@ func (g *StateSizeGenerator) calculateUpdateDiff(update *stateUpdate) stateSizeM
|
||||||
log.Warn("State update missing account", "address", addr)
|
log.Warn("State update missing account", "address", addr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(newValue) == 0 {
|
|
||||||
|
oldLen, newLen := len(oldValue), len(newValue)
|
||||||
|
if oldLen > 0 && newLen == 0 {
|
||||||
|
// Account deletion
|
||||||
diff.AccountCount -= 1
|
diff.AccountCount -= 1
|
||||||
diff.AccountBytes -= common.HashLength
|
diff.AccountBytes -= accountSnapKeySize + int64(oldLen)
|
||||||
}
|
} else if oldLen == 0 && newLen > 0 {
|
||||||
if len(oldValue) == 0 {
|
// Account creation
|
||||||
diff.AccountCount += 1
|
diff.AccountCount += 1
|
||||||
diff.AccountBytes += common.HashLength
|
diff.AccountBytes += accountSnapKeySize + int64(newLen)
|
||||||
|
} else {
|
||||||
|
// Account update
|
||||||
|
diff.AccountBytes += int64(newLen - oldLen)
|
||||||
}
|
}
|
||||||
diff.AccountBytes += int64(len(newValue) - len(oldValue))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate storage changes
|
// Calculate storage changes
|
||||||
|
|
@ -263,38 +270,58 @@ func (g *StateSizeGenerator) calculateUpdateDiff(update *stateUpdate) stateSizeM
|
||||||
log.Warn("State update missing storage slot", "address", addr, "key", key)
|
log.Warn("State update missing storage slot", "address", addr, "key", key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(newValue) == 0 {
|
|
||||||
|
oldLen, newLen := len(oldValue), len(newValue)
|
||||||
|
if oldLen > 0 && newLen == 0 {
|
||||||
|
// Storage deletion
|
||||||
diff.StorageCount -= 1
|
diff.StorageCount -= 1
|
||||||
diff.StorageBytes -= common.HashLength
|
diff.StorageBytes -= storageSnapKeySize + int64(oldLen)
|
||||||
}
|
} else if oldLen == 0 && newLen > 0 {
|
||||||
if len(oldValue) == 0 {
|
// Storage creation
|
||||||
diff.StorageCount += 1
|
diff.StorageCount += 1
|
||||||
diff.StorageBytes += common.HashLength
|
diff.StorageBytes += storageSnapKeySize + int64(newLen)
|
||||||
|
} else {
|
||||||
|
// Storage update
|
||||||
|
diff.StorageBytes += int64(newLen - oldLen)
|
||||||
}
|
}
|
||||||
diff.StorageBytes += int64(len(newValue) - len(oldValue))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate trie node changes
|
// Calculate trie node changes
|
||||||
for _, subset := range update.nodes.Sets {
|
for owner, subset := range update.nodes.Sets {
|
||||||
for path, n := range subset.Nodes {
|
isAccountTrie := owner == (common.Hash{})
|
||||||
if len(n.Blob) == 0 {
|
var keyPrefixSize int64
|
||||||
|
if isAccountTrie {
|
||||||
|
keyPrefixSize = accountTrieKeyPrefixSize
|
||||||
|
} else {
|
||||||
|
keyPrefixSize = storageTrieKeyPrefixSize
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over Origins since every modified node has an origin entry
|
||||||
|
for path, oldNode := range subset.Origins {
|
||||||
|
newNode, hasNew := subset.Nodes[path]
|
||||||
|
|
||||||
|
keySize := keyPrefixSize + int64(len(path))
|
||||||
|
|
||||||
|
if len(oldNode) > 0 && (!hasNew || len(newNode.Blob) == 0) {
|
||||||
|
// Node deletion
|
||||||
diff.TrieNodeCount -= 1
|
diff.TrieNodeCount -= 1
|
||||||
diff.TrieNodeBytes -= int64(len(path) + common.HashLength)
|
diff.TrieNodeBytes -= keySize + int64(len(oldNode))
|
||||||
}
|
} else if len(oldNode) == 0 && hasNew && len(newNode.Blob) > 0 {
|
||||||
prev, ok := subset.Origins[path]
|
// Node creation
|
||||||
if ok {
|
|
||||||
diff.TrieNodeCount += 1
|
diff.TrieNodeCount += 1
|
||||||
diff.TrieNodeBytes += int64(len(path) + common.HashLength)
|
diff.TrieNodeBytes += keySize + int64(len(newNode.Blob))
|
||||||
|
} else if len(oldNode) > 0 && hasNew && len(newNode.Blob) > 0 {
|
||||||
|
// Node update
|
||||||
|
diff.TrieNodeBytes += int64(len(newNode.Blob) - len(oldNode))
|
||||||
}
|
}
|
||||||
diff.TrieNodeBytes += int64(len(n.Blob) - len(prev))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate code changes
|
// Calculate code changes
|
||||||
for _, code := range update.codes {
|
for _, code := range update.codes {
|
||||||
diff.ContractCount += 1
|
diff.ContractCount += 1
|
||||||
diff.ContractBytes += int64(len(code.blob) + common.HashLength)
|
diff.ContractBytes += codeKeySize + int64(len(code.blob))
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff
|
return diff
|
||||||
|
|
@ -356,52 +383,52 @@ func (g *StateSizeGenerator) initializeMetrics() error {
|
||||||
|
|
||||||
// Metrics will be directly updated by each goroutine
|
// Metrics will be directly updated by each goroutine
|
||||||
var (
|
var (
|
||||||
accountCount, accountBytes int64
|
accountSnapCount, accountSnapBytes int64
|
||||||
storageCount, storageBytes int64
|
storageSnapCount, storageSnapBytes int64
|
||||||
trieAccountNodeCount, trieAccountNodeBytes int64
|
accountTrieCount, accountTrieBytes int64
|
||||||
trieStorageNodeCount, trieStorageNodeBytes int64
|
storageTrieCount, storageTrieBytes int64
|
||||||
contractCount, contractBytes int64
|
contractCount, contractBytes int64
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start all table iterations concurrently with direct metric updates
|
// Start all table iterations concurrently with direct metric updates
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
count, bytes, err := g.iterateTable(ctx, rawdb.SnapshotAccountPrefix, "account")
|
count, bytes, err := g.iterateTable(ctx, rawdb.SnapshotAccountPrefix, "accountSnap")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
accountCount, accountBytes = count, bytes
|
accountSnapCount, accountSnapBytes = count, bytes
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
count, bytes, err := g.iterateTable(ctx, rawdb.SnapshotStoragePrefix, "storage")
|
count, bytes, err := g.iterateTable(ctx, rawdb.SnapshotStoragePrefix, "storageSnap")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
storageCount, storageBytes = count, bytes
|
storageSnapCount, storageSnapBytes = count, bytes
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
count, bytes, err := g.iterateTable(ctx, rawdb.TrieNodeAccountPrefix, "trie account node")
|
count, bytes, err := g.iterateTable(ctx, rawdb.TrieNodeAccountPrefix, "accountTrie")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
trieAccountNodeCount, trieAccountNodeBytes = count, bytes
|
accountTrieCount, accountTrieBytes = count, bytes
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
count, bytes, err := g.iterateTable(ctx, rawdb.TrieNodeStoragePrefix, "trie storage node")
|
count, bytes, err := g.iterateTable(ctx, rawdb.TrieNodeStoragePrefix, "storageTrie")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
trieStorageNodeCount, trieStorageNodeBytes = count, bytes
|
storageTrieCount, storageTrieBytes = count, bytes
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
count, bytes, err := g.iterateTable(ctx, rawdb.CodePrefix, "contract code")
|
count, bytes, err := g.iterateTable(ctx, rawdb.CodePrefix, "contract")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -414,12 +441,12 @@ func (g *StateSizeGenerator) initializeMetrics() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
g.metrics.AccountCount = accountCount
|
g.metrics.AccountCount = accountSnapCount
|
||||||
g.metrics.AccountBytes = accountBytes
|
g.metrics.AccountBytes = accountSnapBytes
|
||||||
g.metrics.StorageCount = storageCount
|
g.metrics.StorageCount = storageSnapCount
|
||||||
g.metrics.StorageBytes = storageBytes
|
g.metrics.StorageBytes = storageSnapBytes
|
||||||
g.metrics.TrieNodeCount = trieAccountNodeCount + trieStorageNodeCount
|
g.metrics.TrieNodeCount = accountTrieCount + storageTrieCount
|
||||||
g.metrics.TrieNodeBytes = trieAccountNodeBytes + trieStorageNodeBytes
|
g.metrics.TrieNodeBytes = accountTrieBytes + storageTrieBytes
|
||||||
g.metrics.ContractCount = contractCount
|
g.metrics.ContractCount = contractCount
|
||||||
g.metrics.ContractBytes = contractBytes
|
g.metrics.ContractBytes = contractBytes
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue