Skip to content

Commit 6ecc311

Browse files
committed
state: debug_stateSize to retrieve the latest state size
1 parent 40f10d4 commit 6ecc311

File tree

7 files changed

+59
-47
lines changed

7 files changed

+59
-47
lines changed

cmd/geth/chaincmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ if one is set. Otherwise it prints the genesis from the datadir.`,
108108
utils.MetricsInfluxDBTokenFlag,
109109
utils.MetricsInfluxDBBucketFlag,
110110
utils.MetricsInfluxDBOrganizationFlag,
111-
utils.MetricsStateSizeFlag,
111+
utils.StateSizeTrackingFlag,
112112
utils.TxLookupLimitFlag,
113113
utils.VMTraceFlag,
114114
utils.VMTraceJsonConfigFlag,

cmd/geth/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ var (
200200
utils.MetricsInfluxDBTokenFlag,
201201
utils.MetricsInfluxDBBucketFlag,
202202
utils.MetricsInfluxDBOrganizationFlag,
203-
utils.MetricsStateSizeFlag,
203+
utils.StateSizeTrackingFlag,
204204
}
205205
)
206206

cmd/utils/flags.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,12 @@ var (
628628
TakesFile: true,
629629
Category: flags.MiscCategory,
630630
}
631+
StateSizeTrackingFlag = &cli.BoolFlag{
632+
Name: "state-size-tracking",
633+
Usage: "Enable state size tracking",
634+
Value: ethconfig.Defaults.EnableStateSizeTracking,
635+
Category: flags.MiscCategory,
636+
}
631637

632638
// RPC settings
633639
IPCDisabledFlag = &cli.BoolFlag{
@@ -966,13 +972,6 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
966972
Value: metrics.DefaultConfig.InfluxDBOrganization,
967973
Category: flags.MetricsCategory,
968974
}
969-
970-
MetricsStateSizeFlag = &cli.BoolFlag{
971-
Name: "metrics.statesize",
972-
Usage: "Enable state size tracking for metrics collection",
973-
Value: ethconfig.Defaults.EnableStateSizeTracking,
974-
Category: flags.MetricsCategory,
975-
}
976975
)
977976

978977
var (
@@ -1734,7 +1733,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
17341733
}
17351734
}
17361735

1737-
if ctx.Bool(MetricsEnabledFlag.Name) && ctx.Bool(MetricsStateSizeFlag.Name) {
1736+
if ctx.Bool(StateSizeTrackingFlag.Name) {
17381737
log.Info("Enabling state size metrics")
17391738
cfg.EnableStateSizeTracking = true
17401739
}
@@ -2221,8 +2220,8 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
22212220
// - DATADIR/triedb/verkle.journal
22222221
TrieJournalDirectory: stack.ResolvePath("triedb"),
22232222

2224-
// Enable state size tracking if metrics and state size metrics are both enabled
2225-
EnableStateSizeTracking: ctx.Bool(MetricsEnabledFlag.Name) && ctx.Bool(MetricsStateSizeFlag.Name),
2223+
// Enable state size tracking if enabled
2224+
EnableStateSizeTracking: ctx.Bool(StateSizeTrackingFlag.Name),
22262225
}
22272226
if options.ArchiveMode && !options.Preimages {
22282227
options.Preimages = true

core/blockchain.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2811,3 +2811,8 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) {
28112811
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
28122812
return time.Duration(bc.flushInterval.Load())
28132813
}
2814+
2815+
// StateSizer returns the state size tracker, or nil if it's not initialized
2816+
func (bc *BlockChain) StateSizer() *state.SizeTracker {
2817+
return bc.stateSizer
2818+
}

core/state/state_sizer.go

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,10 @@ import (
2626
"time"
2727

2828
"github.com/ethereum/go-ethereum/common"
29-
"github.com/ethereum/go-ethereum/common/hexutil"
3029
"github.com/ethereum/go-ethereum/core/rawdb"
3130
"github.com/ethereum/go-ethereum/crypto"
3231
"github.com/ethereum/go-ethereum/ethdb"
3332
"github.com/ethereum/go-ethereum/log"
34-
"github.com/ethereum/go-ethereum/metrics"
3533
"github.com/ethereum/go-ethereum/triedb"
3634
"golang.org/x/sync/errgroup"
3735
)
@@ -40,25 +38,10 @@ const (
4038
statEvictThreshold = 128 // the depth of statistic to be preserved
4139
)
4240

43-
// Metrics for uploading the state statistics.
44-
var (
45-
blockInfoGauge = metrics.NewRegisteredGaugeInfo("state/size/block", nil)
46-
accountsGauge = metrics.NewRegisteredGauge("state/size/account/count", nil)
47-
accountBytesGauge = metrics.NewRegisteredGauge("state/size/account/bytes", nil)
48-
storagesGauge = metrics.NewRegisteredGauge("state/size/storage/count", nil)
49-
storageBytesGauge = metrics.NewRegisteredGauge("state/size/storage/bytes", nil)
50-
accountTrienodesGauge = metrics.NewRegisteredGauge("state/size/trienode/account/count", nil)
51-
accountTrienodeBytesGauge = metrics.NewRegisteredGauge("state/size/trienode/account/bytes", nil)
52-
storageTrienodesGauge = metrics.NewRegisteredGauge("state/size/trienode/storage/count", nil)
53-
storageTrienodeBytesGauge = metrics.NewRegisteredGauge("state/size/trienode/storage/bytes", nil)
54-
contractCodesGauge = metrics.NewRegisteredGauge("state/size/contractcode/count", nil)
55-
contractCodeBytesGauge = metrics.NewRegisteredGauge("state/size/contractcode/bytes", nil)
56-
)
57-
5841
// Database key scheme for states.
5942
var (
6043
accountKeySize = int64(len(rawdb.SnapshotAccountPrefix) + common.HashLength)
61-
storageKeySize = int64(len(rawdb.SnapshotStoragePrefix) + common.HashLength + common.HashLength)
44+
storageKeySize = int64(len(rawdb.SnapshotStoragePrefix) + common.HashLength*2)
6245
accountTrienodePrefixSize = int64(len(rawdb.TrieNodeAccountPrefix))
6346
storageTrienodePrefixSize = int64(len(rawdb.TrieNodeStoragePrefix) + common.HashLength)
6447
codeKeySize = int64(len(rawdb.CodePrefix) + common.HashLength)
@@ -246,6 +229,9 @@ type SizeTracker struct {
246229
abort chan struct{}
247230
aborted chan struct{}
248231
updateCh chan *stateUpdate
232+
233+
mu sync.RWMutex
234+
latestStats *SizeStats
249235
}
250236

251237
// NewSizeTracker creates a new state size tracker and starts it automatically
@@ -313,7 +299,12 @@ func (t *SizeTracker) run() {
313299
}
314300
stat := base.add(diff)
315301
stats[u.root] = stat
316-
t.upload(stat)
302+
log.Info("Update state size", "number", stat.BlockNumber, "root", stat.StateRoot, "stat", stat)
303+
304+
// Update latest stats
305+
t.mu.Lock()
306+
t.latestStats = &stat
307+
t.mu.Unlock()
317308

318309
heap.Push(&h, stats[u.root])
319310
for u.blockNumber-h[0].BlockNumber > statEvictThreshold {
@@ -415,6 +406,13 @@ wait:
415406
if err := apply(result.root, result.stat); err != nil {
416407
return nil, err
417408
}
409+
410+
// Set initial latest stats
411+
stats[result.root] = result.stat
412+
t.mu.Lock()
413+
t.latestStats = &result.stat
414+
t.mu.Unlock()
415+
418416
log.Info("Measured persistent state size", "root", result.root, "number", result.blockNumber, "stat", result.stat, "elapsed", common.PrettyDuration(result.elapsed))
419417
return stats, nil
420418

@@ -600,20 +598,9 @@ func (t *SizeTracker) iterateTableParallel(closed chan struct{}, prefix []byte,
600598
return totalCount, totalBytes, nil
601599
}
602600

603-
func (t *SizeTracker) upload(stats SizeStats) {
604-
log.Debug("Uploading state size", "number", stats.BlockNumber, "root", stats.StateRoot, "stat", stats)
605-
blockInfoGauge.Update(metrics.GaugeInfoValue{
606-
"number": hexutil.Uint64(stats.BlockNumber).String(),
607-
"hash": stats.StateRoot.Hex(),
608-
})
609-
accountsGauge.Update(stats.Accounts)
610-
accountBytesGauge.Update(stats.AccountBytes)
611-
storagesGauge.Update(stats.Storages)
612-
storageBytesGauge.Update(stats.StorageBytes)
613-
accountTrienodesGauge.Update(stats.AccountTrienodes)
614-
accountTrienodeBytesGauge.Update(stats.AccountTrienodeBytes)
615-
storageTrienodesGauge.Update(stats.StorageTrienodes)
616-
storageTrienodeBytesGauge.Update(stats.StorageTrienodeBytes)
617-
contractCodesGauge.Update(stats.ContractCodes)
618-
contractCodeBytesGauge.Update(stats.ContractCodeBytes)
601+
// GetLatestStats returns the latest state size statistics, or nil if not available
602+
func (t *SizeTracker) GetLatestStats() *SizeStats {
603+
t.mu.RLock()
604+
defer t.mu.RUnlock()
605+
return t.latestStats
619606
}

eth/api_debug.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,3 +443,19 @@ func (api *DebugAPI) GetTrieFlushInterval() (string, error) {
443443
}
444444
return api.eth.blockchain.GetTrieFlushInterval().String(), nil
445445
}
446+
447+
// StateSize returns the current state size statistics from the state size tracker.
448+
// Returns an error if the state size tracker is not initialized or if stats are not ready.
449+
func (api *DebugAPI) StateSize() (*state.SizeStats, error) {
450+
sizer := api.eth.blockchain.StateSizer()
451+
if sizer == nil {
452+
return nil, errors.New("state size tracker is not enabled")
453+
}
454+
455+
stats := sizer.GetLatestStats()
456+
if stats == nil {
457+
return nil, errors.New("state size statistics are not ready yet")
458+
}
459+
460+
return stats, nil
461+
}

internal/web3ext/web3ext.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,11 @@ web3._extend({
468468
call: 'debug_sync',
469469
params: 1
470470
}),
471+
new web3._extend.Method({
472+
name: 'stateSize',
473+
call: 'debug_stateSize',
474+
params: 0,
475+
}),
471476
],
472477
properties: []
473478
});

0 commit comments

Comments
 (0)