Skip to content

Commit c4ec450

Browse files
jsvisarjl493456442
andauthored
core/state: state size tracking (ethereum#32362)
Add state size tracking and retrieve api, start geth with `--state.size-tracking`, the initial bootstrap is required (around 1h on mainnet), after the bootstrap, use `debug_stateSize()` RPC to retrieve the state size: ``` > debug.stateSize() { accountBytes: "0x39681967b", accountTrienodeBytes: "0xc57939f0c", accountTrienodes: "0x198b36ac", accounts: "0x129da14a", blockNumber: "0x1635e90", contractCodeBytes: "0x2b63ef481", contractCodes: "0x1c7b45", stateRoot: "0x9c36a3ec3745d72eea8700bd27b90dcaa66de0494b187c5600750044151e620a", storageBytes: "0x18a6e7d3f1", storageTrienodeBytes: "0x2e7f53fae6", storageTrienodes: "0x6e49a234", storages: "0x517859c5" } ``` --------- Signed-off-by: jsvisa <[email protected]> Co-authored-by: Gary Rong <[email protected]>
1 parent 8ce2047 commit c4ec450

File tree

16 files changed

+1016
-8
lines changed

16 files changed

+1016
-8
lines changed

cmd/geth/chaincmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +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.StateSizeTrackingFlag,
111112
utils.TxLookupLimitFlag,
112113
utils.VMTraceFlag,
113114
utils.VMTraceJsonConfigFlag,

cmd/geth/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func constructDevModeBanner(ctx *cli.Context, cfg gethConfig) string {
209209
0x%x (10^49 ETH)
210210
`, cfg.Eth.Miner.PendingFeeRecipient)
211211
if cfg.Eth.Miner.PendingFeeRecipient == utils.DeveloperAddr {
212-
devModeBanner += fmt.Sprintf(`
212+
devModeBanner += fmt.Sprintf(`
213213
Private Key
214214
------------------
215215
0x%x

cmd/geth/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ var (
200200
utils.MetricsInfluxDBTokenFlag,
201201
utils.MetricsInfluxDBBucketFlag,
202202
utils.MetricsInfluxDBOrganizationFlag,
203+
utils.StateSizeTrackingFlag,
203204
}
204205
)
205206

cmd/utils/flags.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,12 @@ var (
270270
Usage: "Scheme to use for storing ethereum state ('hash' or 'path')",
271271
Category: flags.StateCategory,
272272
}
273+
StateSizeTrackingFlag = &cli.BoolFlag{
274+
Name: "state.size-tracking",
275+
Usage: "Enable state size tracking, retrieve state size with debug_stateSize.",
276+
Value: ethconfig.Defaults.EnableStateSizeTracking,
277+
Category: flags.StateCategory,
278+
}
273279
StateHistoryFlag = &cli.Uint64Flag{
274280
Name: "history.state",
275281
Usage: "Number of recent blocks to retain state history for, only relevant in state.scheme=path (default = 90,000 blocks, 0 = entire chain)",
@@ -1726,6 +1732,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
17261732
cfg.EthDiscoveryURLs = SplitAndTrim(urls)
17271733
}
17281734
}
1735+
if ctx.Bool(StateSizeTrackingFlag.Name) {
1736+
cfg.EnableStateSizeTracking = true
1737+
}
17291738
// Override any default configs for hard coded networks.
17301739
switch {
17311740
case ctx.Bool(MainnetFlag.Name):
@@ -2208,6 +2217,9 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
22082217
// - DATADIR/triedb/merkle.journal
22092218
// - DATADIR/triedb/verkle.journal
22102219
TrieJournalDirectory: stack.ResolvePath("triedb"),
2220+
2221+
// Enable state size tracking if enabled
2222+
StateSizeTracking: ctx.Bool(StateSizeTrackingFlag.Name),
22112223
}
22122224
if options.ArchiveMode && !options.Preimages {
22132225
options.Preimages = true

core/blockchain.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ type BlockChainConfig struct {
196196
// If the value is zero, all transactions of the entire chain will be indexed.
197197
// If the value is -1, indexing is disabled.
198198
TxLookupLimit int64
199+
200+
// StateSizeTracking indicates whether the state size tracking is enabled.
201+
StateSizeTracking bool
199202
}
200203

201204
// DefaultConfig returns the default config.
@@ -333,6 +336,7 @@ type BlockChain struct {
333336
prefetcher Prefetcher
334337
processor Processor // Block transaction processor interface
335338
logger *tracing.Hooks
339+
stateSizer *state.SizeTracker // State size tracking
336340

337341
lastForkReadyAlert time.Time // Last time there was a fork readiness print out
338342
}
@@ -526,6 +530,17 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine,
526530
if bc.cfg.TxLookupLimit >= 0 {
527531
bc.txIndexer = newTxIndexer(uint64(bc.cfg.TxLookupLimit), bc)
528532
}
533+
534+
// Start state size tracker
535+
if bc.cfg.StateSizeTracking {
536+
stateSizer, err := state.NewSizeTracker(bc.db, bc.triedb)
537+
if err == nil {
538+
bc.stateSizer = stateSizer
539+
log.Info("Enabled state size metrics")
540+
} else {
541+
log.Info("Failed to setup size tracker", "err", err)
542+
}
543+
}
529544
return bc, nil
530545
}
531546

@@ -1252,6 +1267,10 @@ func (bc *BlockChain) stopWithoutSaving() {
12521267
// Signal shutdown to all goroutines.
12531268
bc.InterruptInsert(true)
12541269

1270+
// Stop state size tracker
1271+
if bc.stateSizer != nil {
1272+
bc.stateSizer.Stop()
1273+
}
12551274
// Now wait for all chain modifications to end and persistent goroutines to exit.
12561275
//
12571276
// Note: Close waits for the mutex to become available, i.e. any running chain
@@ -1586,10 +1605,14 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
15861605
log.Crit("Failed to write block into disk", "err", err)
15871606
}
15881607
// Commit all cached state changes into underlying memory database.
1589-
root, err := statedb.Commit(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number()), bc.chainConfig.IsCancun(block.Number(), block.Time()))
1608+
root, stateUpdate, err := statedb.CommitWithUpdate(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number()), bc.chainConfig.IsCancun(block.Number(), block.Time()))
15901609
if err != nil {
15911610
return err
15921611
}
1612+
// Emit the state update to the state sizestats if it's active
1613+
if bc.stateSizer != nil {
1614+
bc.stateSizer.Notify(stateUpdate)
1615+
}
15931616
// If node is running in path mode, skip explicit gc operation
15941617
// which is unnecessary in this mode.
15951618
if bc.triedb.Scheme() == rawdb.PathScheme {
@@ -2791,3 +2814,8 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) {
27912814
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
27922815
return time.Duration(bc.flushInterval.Load())
27932816
}
2817+
2818+
// StateSizer returns the state size tracker, or nil if it's not initialized
2819+
func (bc *BlockChain) StateSizer() *state.SizeTracker {
2820+
return bc.stateSizer
2821+
}

0 commit comments

Comments
 (0)