@@ -31,6 +31,14 @@ import (
31
31
"golang.org/x/sync/errgroup"
32
32
)
33
33
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
+
34
42
// stateSizeMetrics represents the current state size statistics
35
43
type stateSizeMetrics struct {
36
44
Root common.Hash // Root hash of the state trie
@@ -180,7 +188,6 @@ func (g *StateSizeGenerator) initialize() chan struct{} {
180
188
181
189
// handleUpdate processes a single update with proper root continuity checking
182
190
func (g * StateSizeGenerator ) handleUpdate (update * stateUpdate , initialized bool ) {
183
- // Calculate the diff
184
191
diff := g .calculateUpdateDiff (update )
185
192
186
193
var targetMetrics * stateSizeMetrics
@@ -192,12 +199,7 @@ func (g *StateSizeGenerator) handleUpdate(update *stateUpdate, initialized bool)
192
199
193
200
// Check root continuity - the update should build on our current state
194
201
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 )
201
203
}
202
204
203
205
// Update to the new state root
@@ -230,15 +232,20 @@ func (g *StateSizeGenerator) calculateUpdateDiff(update *stateUpdate) stateSizeM
230
232
log .Warn ("State update missing account" , "address" , addr )
231
233
continue
232
234
}
233
- if len (newValue ) == 0 {
235
+
236
+ oldLen , newLen := len (oldValue ), len (newValue )
237
+ if oldLen > 0 && newLen == 0 {
238
+ // Account deletion
234
239
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
238
243
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 )
240
248
}
241
- diff .AccountBytes += int64 (len (newValue ) - len (oldValue ))
242
249
}
243
250
244
251
// Calculate storage changes
@@ -263,38 +270,58 @@ func (g *StateSizeGenerator) calculateUpdateDiff(update *stateUpdate) stateSizeM
263
270
log .Warn ("State update missing storage slot" , "address" , addr , "key" , key )
264
271
continue
265
272
}
266
- if len (newValue ) == 0 {
273
+
274
+ oldLen , newLen := len (oldValue ), len (newValue )
275
+ if oldLen > 0 && newLen == 0 {
276
+ // Storage deletion
267
277
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
271
281
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 )
273
286
}
274
- diff .StorageBytes += int64 (len (newValue ) - len (oldValue ))
275
287
}
276
288
}
277
289
278
290
// 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
282
308
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
287
312
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 ))
289
317
}
290
- diff .TrieNodeBytes += int64 (len (n .Blob ) - len (prev ))
291
318
}
292
319
}
293
320
294
321
// Calculate code changes
295
322
for _ , code := range update .codes {
296
323
diff .ContractCount += 1
297
- diff .ContractBytes += int64 (len (code .blob ) + common . HashLength )
324
+ diff .ContractBytes += codeKeySize + int64 (len (code .blob ))
298
325
}
299
326
300
327
return diff
@@ -356,52 +383,52 @@ func (g *StateSizeGenerator) initializeMetrics() error {
356
383
357
384
// Metrics will be directly updated by each goroutine
358
385
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
364
391
)
365
392
366
393
// Start all table iterations concurrently with direct metric updates
367
394
group .Go (func () error {
368
- count , bytes , err := g .iterateTable (ctx , rawdb .SnapshotAccountPrefix , "account " )
395
+ count , bytes , err := g .iterateTable (ctx , rawdb .SnapshotAccountPrefix , "accountSnap " )
369
396
if err != nil {
370
397
return err
371
398
}
372
- accountCount , accountBytes = count , bytes
399
+ accountSnapCount , accountSnapBytes = count , bytes
373
400
return nil
374
401
})
375
402
376
403
group .Go (func () error {
377
- count , bytes , err := g .iterateTable (ctx , rawdb .SnapshotStoragePrefix , "storage " )
404
+ count , bytes , err := g .iterateTable (ctx , rawdb .SnapshotStoragePrefix , "storageSnap " )
378
405
if err != nil {
379
406
return err
380
407
}
381
- storageCount , storageBytes = count , bytes
408
+ storageSnapCount , storageSnapBytes = count , bytes
382
409
return nil
383
410
})
384
411
385
412
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 " )
387
414
if err != nil {
388
415
return err
389
416
}
390
- trieAccountNodeCount , trieAccountNodeBytes = count , bytes
417
+ accountTrieCount , accountTrieBytes = count , bytes
391
418
return nil
392
419
})
393
420
394
421
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 " )
396
423
if err != nil {
397
424
return err
398
425
}
399
- trieStorageNodeCount , trieStorageNodeBytes = count , bytes
426
+ storageTrieCount , storageTrieBytes = count , bytes
400
427
return nil
401
428
})
402
429
403
430
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" )
405
432
if err != nil {
406
433
return err
407
434
}
@@ -414,12 +441,12 @@ func (g *StateSizeGenerator) initializeMetrics() error {
414
441
return err
415
442
}
416
443
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
423
450
g .metrics .ContractCount = contractCount
424
451
g .metrics .ContractBytes = contractBytes
425
452
0 commit comments