Skip to content

Commit e993ff3

Browse files
committed
fix: trienode calculate
Signed-off-by: jsvisa <[email protected]>
1 parent 2c9785e commit e993ff3

File tree

1 file changed

+76
-49
lines changed

1 file changed

+76
-49
lines changed

core/state/statesize.go

Lines changed: 76 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ import (
3131
"golang.org/x/sync/errgroup"
3232
)
3333

34+
var (
35+
accountSnapKeySize = int64(len(rawdb.SnapshotAccountPrefix) + common.HashLength)
36+
storageSnapKeySize = int64(len(rawdb.SnapshotStoragePrefix) + common.HashLength + common.HashLength)
37+
accountTrieKeyPrefixSize = int64(len(rawdb.TrieNodeAccountPrefix))
38+
storageTrieKeyPrefixSize = int64(len(rawdb.TrieNodeStoragePrefix) + common.HashLength)
39+
codeKeySize = int64(len(rawdb.CodePrefix) + common.HashLength)
40+
)
41+
3442
// stateSizeMetrics represents the current state size statistics
3543
type stateSizeMetrics struct {
3644
Root common.Hash // Root hash of the state trie
@@ -180,7 +188,6 @@ func (g *StateSizeGenerator) initialize() chan struct{} {
180188

181189
// handleUpdate processes a single update with proper root continuity checking
182190
func (g *StateSizeGenerator) handleUpdate(update *stateUpdate, initialized bool) {
183-
// Calculate the diff
184191
diff := g.calculateUpdateDiff(update)
185192

186193
var targetMetrics *stateSizeMetrics
@@ -192,12 +199,7 @@ func (g *StateSizeGenerator) handleUpdate(update *stateUpdate, initialized bool)
192199

193200
// Check root continuity - the update should build on our current state
194201
if targetMetrics.Root != (common.Hash{}) && targetMetrics.Root != update.originRoot {
195-
log.Warn("State update root discontinuity detected",
196-
"current", targetMetrics.Root,
197-
"updateOrigin", update.originRoot,
198-
"updateNew", update.root)
199-
// For now, we accept the discontinuity but log it
200-
// In production, you might want to reset metrics or handle differently
202+
log.Warn("State update root discontinuity detected", "current", targetMetrics.Root, "updateOrigin", update.originRoot, "updateNew", update.root)
201203
}
202204

203205
// Update to the new state root
@@ -230,15 +232,20 @@ func (g *StateSizeGenerator) calculateUpdateDiff(update *stateUpdate) stateSizeM
230232
log.Warn("State update missing account", "address", addr)
231233
continue
232234
}
233-
if len(newValue) == 0 {
235+
236+
oldLen, newLen := len(oldValue), len(newValue)
237+
if oldLen > 0 && newLen == 0 {
238+
// Account deletion
234239
diff.AccountCount -= 1
235-
diff.AccountBytes -= common.HashLength
236-
}
237-
if len(oldValue) == 0 {
240+
diff.AccountBytes -= accountSnapKeySize + int64(oldLen)
241+
} else if oldLen == 0 && newLen > 0 {
242+
// Account creation
238243
diff.AccountCount += 1
239-
diff.AccountBytes += common.HashLength
244+
diff.AccountBytes += accountSnapKeySize + int64(newLen)
245+
} else {
246+
// Account update
247+
diff.AccountBytes += int64(newLen - oldLen)
240248
}
241-
diff.AccountBytes += int64(len(newValue) - len(oldValue))
242249
}
243250

244251
// Calculate storage changes
@@ -263,38 +270,58 @@ func (g *StateSizeGenerator) calculateUpdateDiff(update *stateUpdate) stateSizeM
263270
log.Warn("State update missing storage slot", "address", addr, "key", key)
264271
continue
265272
}
266-
if len(newValue) == 0 {
273+
274+
oldLen, newLen := len(oldValue), len(newValue)
275+
if oldLen > 0 && newLen == 0 {
276+
// Storage deletion
267277
diff.StorageCount -= 1
268-
diff.StorageBytes -= common.HashLength
269-
}
270-
if len(oldValue) == 0 {
278+
diff.StorageBytes -= storageSnapKeySize + int64(oldLen)
279+
} else if oldLen == 0 && newLen > 0 {
280+
// Storage creation
271281
diff.StorageCount += 1
272-
diff.StorageBytes += common.HashLength
282+
diff.StorageBytes += storageSnapKeySize + int64(newLen)
283+
} else {
284+
// Storage update
285+
diff.StorageBytes += int64(newLen - oldLen)
273286
}
274-
diff.StorageBytes += int64(len(newValue) - len(oldValue))
275287
}
276288
}
277289

278290
// Calculate trie node changes
279-
for _, subset := range update.nodes.Sets {
280-
for path, n := range subset.Nodes {
281-
if len(n.Blob) == 0 {
291+
for owner, subset := range update.nodes.Sets {
292+
isAccountTrie := owner == (common.Hash{})
293+
var keyPrefixSize int64
294+
if isAccountTrie {
295+
keyPrefixSize = accountTrieKeyPrefixSize
296+
} else {
297+
keyPrefixSize = storageTrieKeyPrefixSize
298+
}
299+
300+
// Iterate over Origins since every modified node has an origin entry
301+
for path, oldNode := range subset.Origins {
302+
newNode, hasNew := subset.Nodes[path]
303+
304+
keySize := keyPrefixSize + int64(len(path))
305+
306+
if len(oldNode) > 0 && (!hasNew || len(newNode.Blob) == 0) {
307+
// Node deletion
282308
diff.TrieNodeCount -= 1
283-
diff.TrieNodeBytes -= int64(len(path) + common.HashLength)
284-
}
285-
prev, ok := subset.Origins[path]
286-
if ok {
309+
diff.TrieNodeBytes -= keySize + int64(len(oldNode))
310+
} else if len(oldNode) == 0 && hasNew && len(newNode.Blob) > 0 {
311+
// Node creation
287312
diff.TrieNodeCount += 1
288-
diff.TrieNodeBytes += int64(len(path) + common.HashLength)
313+
diff.TrieNodeBytes += keySize + int64(len(newNode.Blob))
314+
} else if len(oldNode) > 0 && hasNew && len(newNode.Blob) > 0 {
315+
// Node update
316+
diff.TrieNodeBytes += int64(len(newNode.Blob) - len(oldNode))
289317
}
290-
diff.TrieNodeBytes += int64(len(n.Blob) - len(prev))
291318
}
292319
}
293320

294321
// Calculate code changes
295322
for _, code := range update.codes {
296323
diff.ContractCount += 1
297-
diff.ContractBytes += int64(len(code.blob) + common.HashLength)
324+
diff.ContractBytes += codeKeySize + int64(len(code.blob))
298325
}
299326

300327
return diff
@@ -356,52 +383,52 @@ func (g *StateSizeGenerator) initializeMetrics() error {
356383

357384
// Metrics will be directly updated by each goroutine
358385
var (
359-
accountCount, accountBytes int64
360-
storageCount, storageBytes int64
361-
trieAccountNodeCount, trieAccountNodeBytes int64
362-
trieStorageNodeCount, trieStorageNodeBytes int64
363-
contractCount, contractBytes int64
386+
accountSnapCount, accountSnapBytes int64
387+
storageSnapCount, storageSnapBytes int64
388+
accountTrieCount, accountTrieBytes int64
389+
storageTrieCount, storageTrieBytes int64
390+
contractCount, contractBytes int64
364391
)
365392

366393
// Start all table iterations concurrently with direct metric updates
367394
group.Go(func() error {
368-
count, bytes, err := g.iterateTable(ctx, rawdb.SnapshotAccountPrefix, "account")
395+
count, bytes, err := g.iterateTable(ctx, rawdb.SnapshotAccountPrefix, "accountSnap")
369396
if err != nil {
370397
return err
371398
}
372-
accountCount, accountBytes = count, bytes
399+
accountSnapCount, accountSnapBytes = count, bytes
373400
return nil
374401
})
375402

376403
group.Go(func() error {
377-
count, bytes, err := g.iterateTable(ctx, rawdb.SnapshotStoragePrefix, "storage")
404+
count, bytes, err := g.iterateTable(ctx, rawdb.SnapshotStoragePrefix, "storageSnap")
378405
if err != nil {
379406
return err
380407
}
381-
storageCount, storageBytes = count, bytes
408+
storageSnapCount, storageSnapBytes = count, bytes
382409
return nil
383410
})
384411

385412
group.Go(func() error {
386-
count, bytes, err := g.iterateTable(ctx, rawdb.TrieNodeAccountPrefix, "trie account node")
413+
count, bytes, err := g.iterateTable(ctx, rawdb.TrieNodeAccountPrefix, "accountTrie")
387414
if err != nil {
388415
return err
389416
}
390-
trieAccountNodeCount, trieAccountNodeBytes = count, bytes
417+
accountTrieCount, accountTrieBytes = count, bytes
391418
return nil
392419
})
393420

394421
group.Go(func() error {
395-
count, bytes, err := g.iterateTable(ctx, rawdb.TrieNodeStoragePrefix, "trie storage node")
422+
count, bytes, err := g.iterateTable(ctx, rawdb.TrieNodeStoragePrefix, "storageTrie")
396423
if err != nil {
397424
return err
398425
}
399-
trieStorageNodeCount, trieStorageNodeBytes = count, bytes
426+
storageTrieCount, storageTrieBytes = count, bytes
400427
return nil
401428
})
402429

403430
group.Go(func() error {
404-
count, bytes, err := g.iterateTable(ctx, rawdb.CodePrefix, "contract code")
431+
count, bytes, err := g.iterateTable(ctx, rawdb.CodePrefix, "contract")
405432
if err != nil {
406433
return err
407434
}
@@ -414,12 +441,12 @@ func (g *StateSizeGenerator) initializeMetrics() error {
414441
return err
415442
}
416443

417-
g.metrics.AccountCount = accountCount
418-
g.metrics.AccountBytes = accountBytes
419-
g.metrics.StorageCount = storageCount
420-
g.metrics.StorageBytes = storageBytes
421-
g.metrics.TrieNodeCount = trieAccountNodeCount + trieStorageNodeCount
422-
g.metrics.TrieNodeBytes = trieAccountNodeBytes + trieStorageNodeBytes
444+
g.metrics.AccountCount = accountSnapCount
445+
g.metrics.AccountBytes = accountSnapBytes
446+
g.metrics.StorageCount = storageSnapCount
447+
g.metrics.StorageBytes = storageSnapBytes
448+
g.metrics.TrieNodeCount = accountTrieCount + storageTrieCount
449+
g.metrics.TrieNodeBytes = accountTrieBytes + storageTrieBytes
423450
g.metrics.ContractCount = contractCount
424451
g.metrics.ContractBytes = contractBytes
425452

0 commit comments

Comments
 (0)