diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index 95b0ec274e..143c0a6e74 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -115,7 +115,7 @@ if one is set. Otherwise it prints the genesis from the datadir.`,
utils.MetricsInfluxDBTokenFlag,
utils.MetricsInfluxDBBucketFlag,
utils.MetricsInfluxDBOrganizationFlag,
- utils.StateSizeTrackingFlag,
+ utils.StateSizeTrackingFlag, // deprecated
utils.VMTraceFlag,
utils.VMTraceJsonConfigFlag,
utils.TransactionHistoryFlag,
diff --git a/cmd/geth/config.go b/cmd/geth/config.go
index 8ac9e7f6bd..a2c4327c2e 100644
--- a/cmd/geth/config.go
+++ b/cmd/geth/config.go
@@ -100,6 +100,7 @@ var deprecatedConfigFields = map[string]bool{
"ethconfig.Config.LightPeers": true,
"ethconfig.Config.LightNoPrune": true,
"ethconfig.Config.LightNoSyncServe": true,
+ "ethconfig.Config.EnableStateSizeTracking": true,
}
type ethstatsConfig struct {
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index 48a9ae583f..6bf9c3a587 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -209,8 +209,8 @@ var (
utils.MetricsInfluxDBTokenFlag,
utils.MetricsInfluxDBBucketFlag,
utils.MetricsInfluxDBOrganizationFlag,
- utils.StateSizeTrackingFlag,
utils.SnapV2Flag,
+ utils.StateSizeTrackingFlag, // deprecated
}
)
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 9b64742808..9ecd487ff9 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -297,12 +297,6 @@ var (
Usage: "Scheme to use for storing ethereum state ('hash' or 'path')",
Category: flags.StateCategory,
}
- StateSizeTrackingFlag = &cli.BoolFlag{
- Name: "state.size-tracking",
- Usage: "Enable state size tracking, retrieve state size with debug_stateSize.",
- Value: ethconfig.Defaults.EnableStateSizeTracking,
- Category: flags.StateCategory,
- }
SnapV2Flag = &cli.BoolFlag{
Name: "snap.v2",
Usage: "Enable the experimental snap/2 (EIP-8189, BAL-based) sync protocol (advertises and syncs via snap/2; not safe on public networks)",
@@ -1975,9 +1969,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.EthDiscoveryURLs = SplitAndTrim(urls)
}
}
- if ctx.IsSet(StateSizeTrackingFlag.Name) {
- cfg.EnableStateSizeTracking = ctx.Bool(StateSizeTrackingFlag.Name)
- }
if ctx.IsSet(SnapV2Flag.Name) {
cfg.SnapV2 = ctx.Bool(SnapV2Flag.Name)
}
@@ -2495,9 +2486,6 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
// - DATADIR/triedb/verkle.journal
TrieJournalDirectory: stack.ResolvePath("triedb"),
- // Enable state size tracking if enabled
- StateSizeTracking: ctx.Bool(StateSizeTrackingFlag.Name),
-
// Configure the slow block statistic logger (disabled by default)
SlowBlockThreshold: ethconfig.Defaults.SlowBlockThreshold,
}
diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go
index 2a3e417993..7b2afd6df5 100644
--- a/cmd/utils/flags_legacy.go
+++ b/cmd/utils/flags_legacy.go
@@ -19,6 +19,7 @@ package utils
import (
"fmt"
+ "github.com/ethereum/go-ethereum/internal/flags"
"github.com/urfave/cli/v2"
)
@@ -30,7 +31,21 @@ var ShowDeprecated = &cli.Command{
Description: "Show flags that have been deprecated and will soon be removed",
}
-var DeprecatedFlags = []cli.Flag{}
+var DeprecatedFlags = []cli.Flag{
+ StateSizeTrackingFlag,
+}
+
+var (
+ // Deprecated August 2026, state size tracking was removed along with the
+ // debug_stateSize endpoint it fed. Kept registered so that nodes carrying
+ // the flag in their startup scripts do not fail to boot.
+ StateSizeTrackingFlag = &cli.BoolFlag{
+ Name: "state.size-tracking",
+ Hidden: true,
+ Usage: "Enable state size tracking (deprecated)",
+ Category: flags.DeprecatedCategory,
+ }
+)
// showDeprecated displays deprecated flags that will be soon removed from the codebase.
func showDeprecated(*cli.Context) error {
diff --git a/core/blockchain.go b/core/blockchain.go
index 5cb8349b10..1bcdaa071b 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -215,9 +215,6 @@ type BlockChainConfig struct {
// If the value is -1, indexing is disabled.
TxLookupLimit int64
- // StateSizeTracking indicates whether the state size tracking is enabled.
- StateSizeTracking bool
-
// SlowBlockThreshold is the block execution time threshold beyond which
// detailed statistics will be logged. Negative value means disabled (default),
// zero logs all blocks, positive value filters blocks by execution time.
@@ -372,7 +369,6 @@ type BlockChain struct {
prefetcher Prefetcher
processor Processor // Block transaction processor interface
logger *tracing.Hooks
- stateSizer *state.SizeTracker // State size tracking
lastForkReadyAlert time.Time // Last time there was a fork readiness print out
slowBlockThreshold time.Duration // Block execution time threshold beyond which detailed statistics will be logged
@@ -570,17 +566,6 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine,
if bc.cfg.TxLookupLimit >= 0 {
bc.txIndexer = newTxIndexer(uint64(bc.cfg.TxLookupLimit), bc)
}
-
- // Start state size tracker
- if bc.cfg.StateSizeTracking {
- stateSizer, err := state.NewSizeTracker(bc.db, bc.triedb)
- if err == nil {
- bc.stateSizer = stateSizer
- log.Info("Enabled state size metrics")
- } else {
- log.Info("Failed to setup size tracker", "err", err)
- }
- }
return bc, nil
}
@@ -1355,10 +1340,6 @@ func (bc *BlockChain) stopWithoutSaving() {
// Signal shutdown to all goroutines.
bc.InterruptInsert(true)
- // Stop state size tracker
- if bc.stateSizer != nil {
- bc.stateSizer.Stop()
- }
// Now wait for all chain modifications to end and persistent goroutines to exit.
//
// Note: Close waits for the mutex to become available, i.e. any running chain
@@ -1682,28 +1663,22 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
log.Debug("Committed block data", "size", common.StorageSize(batch.ValueSize()), "elapsed", common.PrettyDuration(time.Since(start)))
var (
- err error
- root common.Hash
- isEIP158 = bc.chainConfig.IsEIP158(block.Number())
- isCancun = bc.chainConfig.IsCancun(block.Number(), block.Time())
- hasStateHook = bc.logger != nil && bc.logger.OnStateUpdate != nil
- hasStateSizer = bc.stateSizer != nil
+ err error
+ root common.Hash
+ isEIP158 = bc.chainConfig.IsEIP158(block.Number())
+ isCancun = bc.chainConfig.IsCancun(block.Number(), block.Time())
+ hasStateHook = bc.logger != nil && bc.logger.OnStateUpdate != nil
)
- if hasStateHook || hasStateSizer {
+ if hasStateHook {
r, update, err := statedb.CommitWithUpdate(block.NumberU64(), isEIP158, isCancun)
if err != nil {
return err
}
- if hasStateHook {
- trUpdate, err := update.ToTracingUpdate()
- if err != nil {
- return err
- }
- bc.logger.OnStateUpdate(trUpdate)
- }
- if hasStateSizer {
- bc.stateSizer.Notify(update)
+ trUpdate, err := update.ToTracingUpdate()
+ if err != nil {
+ return err
}
+ bc.logger.OnStateUpdate(trUpdate)
root = r
} else {
root, err = statedb.Commit(block.NumberU64(), isEIP158, isCancun)
@@ -3062,8 +3037,3 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) {
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
return time.Duration(bc.flushInterval.Load())
}
-
-// StateSizer returns the state size tracker, or nil if it's not initialized
-func (bc *BlockChain) StateSizer() *state.SizeTracker {
- return bc.stateSizer
-}
diff --git a/core/state/state_sizer.go b/core/state/state_sizer.go
deleted file mode 100644
index 3293d7e950..0000000000
--- a/core/state/state_sizer.go
+++ /dev/null
@@ -1,675 +0,0 @@
-// Copyright 2025 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package state
-
-import (
- "container/heap"
- "errors"
- "fmt"
- "maps"
- "runtime"
- "slices"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/triedb"
- "golang.org/x/sync/errgroup"
-)
-
-const (
- statEvictThreshold = 128 // the depth of statistic to be preserved
-)
-
-// Database key scheme for states.
-var (
- accountKeySize = int64(len(rawdb.SnapshotAccountPrefix) + common.HashLength)
- storageKeySize = int64(len(rawdb.SnapshotStoragePrefix) + common.HashLength*2)
- accountTrienodePrefixSize = int64(len(rawdb.TrieNodeAccountPrefix))
- storageTrienodePrefixSize = int64(len(rawdb.TrieNodeStoragePrefix) + common.HashLength)
- codeKeySize = int64(len(rawdb.CodePrefix) + common.HashLength)
-)
-
-// State size metrics
-var (
- stateSizeChainHeightGauge = metrics.NewRegisteredGauge("state/height", nil)
- stateSizeAccountsCountGauge = metrics.NewRegisteredGauge("state/accounts/count", nil)
- stateSizeAccountsBytesGauge = metrics.NewRegisteredGauge("state/accounts/bytes", nil)
- stateSizeStoragesCountGauge = metrics.NewRegisteredGauge("state/storages/count", nil)
- stateSizeStoragesBytesGauge = metrics.NewRegisteredGauge("state/storages/bytes", nil)
- stateSizeAccountTrieNodesCountGauge = metrics.NewRegisteredGauge("state/trienodes/account/count", nil)
- stateSizeAccountTrieNodesBytesGauge = metrics.NewRegisteredGauge("state/trienodes/account/bytes", nil)
- stateSizeStorageTrieNodesCountGauge = metrics.NewRegisteredGauge("state/trienodes/storage/count", nil)
- stateSizeStorageTrieNodesBytesGauge = metrics.NewRegisteredGauge("state/trienodes/storage/bytes", nil)
- stateSizeContractsCountGauge = metrics.NewRegisteredGauge("state/contracts/count", nil)
- stateSizeContractsBytesGauge = metrics.NewRegisteredGauge("state/contracts/bytes", nil)
-)
-
-// SizeStats represents either the current state size statistics or the size
-// differences resulting from a state transition.
-type SizeStats struct {
- StateRoot common.Hash // State root hash at the time of measurement
- BlockNumber uint64 // Associated block number at the time of measurement
-
- Accounts int64 // Total number of accounts in the state
- AccountBytes int64 // Total storage size used by all account data (in bytes)
- Storages int64 // Total number of storage slots across all accounts
- StorageBytes int64 // Total storage size used by all storage slot data (in bytes)
- AccountTrienodes int64 // Total number of account trie nodes in the state
- AccountTrienodeBytes int64 // Total storage size occupied by account trie nodes (in bytes)
- StorageTrienodes int64 // Total number of storage trie nodes in the state
- StorageTrienodeBytes int64 // Total storage size occupied by storage trie nodes (in bytes)
- ContractCodes int64 // Total number of contract codes in the state
- ContractCodeBytes int64 // Total size of all contract code (in bytes)
-}
-
-func (s SizeStats) String() string {
- return fmt.Sprintf("Accounts: %d(%s), Storages: %d(%s), AccountTrienodes: %d(%s), StorageTrienodes: %d(%s), Codes: %d(%s)",
- s.Accounts, common.StorageSize(s.AccountBytes),
- s.Storages, common.StorageSize(s.StorageBytes),
- s.AccountTrienodes, common.StorageSize(s.AccountTrienodeBytes),
- s.StorageTrienodes, common.StorageSize(s.StorageTrienodeBytes),
- s.ContractCodes, common.StorageSize(s.ContractCodeBytes),
- )
-}
-
-func (s SizeStats) publish() {
- stateSizeChainHeightGauge.Update(int64(s.BlockNumber))
- stateSizeAccountsCountGauge.Update(s.Accounts)
- stateSizeAccountsBytesGauge.Update(s.AccountBytes)
- stateSizeStoragesCountGauge.Update(s.Storages)
- stateSizeStoragesBytesGauge.Update(s.StorageBytes)
- stateSizeAccountTrieNodesCountGauge.Update(s.AccountTrienodes)
- stateSizeAccountTrieNodesBytesGauge.Update(s.AccountTrienodeBytes)
- stateSizeStorageTrieNodesCountGauge.Update(s.StorageTrienodes)
- stateSizeStorageTrieNodesBytesGauge.Update(s.StorageTrienodeBytes)
- stateSizeContractsCountGauge.Update(s.ContractCodes)
- stateSizeContractsBytesGauge.Update(s.ContractCodeBytes)
-}
-
-// add applies the given state diffs and produces a new version of the statistics.
-func (s SizeStats) add(diff SizeStats) SizeStats {
- s.StateRoot = diff.StateRoot
- s.BlockNumber = diff.BlockNumber
-
- s.Accounts += diff.Accounts
- s.AccountBytes += diff.AccountBytes
- s.Storages += diff.Storages
- s.StorageBytes += diff.StorageBytes
- s.AccountTrienodes += diff.AccountTrienodes
- s.AccountTrienodeBytes += diff.AccountTrienodeBytes
- s.StorageTrienodes += diff.StorageTrienodes
- s.StorageTrienodeBytes += diff.StorageTrienodeBytes
- s.ContractCodes += diff.ContractCodes
- s.ContractCodeBytes += diff.ContractCodeBytes
- return s
-}
-
-// calSizeStats measures the state size changes of the provided state update.
-func calSizeStats(update *StateUpdate) (SizeStats, error) {
- stats := SizeStats{
- BlockNumber: update.BlockNumber,
- StateRoot: update.Root,
- }
- accounts, accountOrigin, storages, storageOrigin := update.EncodeMPTState()
-
- // Measure the account changes
- for addr, oldValue := range accountOrigin {
- addrHash := crypto.Keccak256Hash(addr.Bytes())
- newValue, exists := accounts[addrHash]
- if !exists {
- return SizeStats{}, fmt.Errorf("account %x not found", addr)
- }
- oldLen, newLen := len(oldValue), len(newValue)
-
- switch {
- case oldLen > 0 && newLen == 0:
- // Account deletion
- stats.Accounts -= 1
- stats.AccountBytes -= accountKeySize + int64(oldLen)
- case oldLen == 0 && newLen > 0:
- // Account creation
- stats.Accounts += 1
- stats.AccountBytes += accountKeySize + int64(newLen)
- default:
- // Account update
- stats.AccountBytes += int64(newLen - oldLen)
- }
- }
-
- // Measure storage changes
- for addr, slots := range storageOrigin {
- addrHash := crypto.Keccak256Hash(addr.Bytes())
- subset, exists := storages[addrHash]
- if !exists {
- return SizeStats{}, fmt.Errorf("storage %x not found", addr)
- }
- for key, oldValue := range slots {
- var (
- exists bool
- newValue []byte
- )
- if update.StorageKeyType == StorageKeyPlain {
- newValue, exists = subset[crypto.Keccak256Hash(key.Bytes())]
- } else {
- newValue, exists = subset[key]
- }
- if !exists {
- return SizeStats{}, fmt.Errorf("storage slot %x-%x not found", addr, key)
- }
- oldLen, newLen := len(oldValue), len(newValue)
-
- switch {
- case oldLen > 0 && newLen == 0:
- // Storage deletion
- stats.Storages -= 1
- stats.StorageBytes -= storageKeySize + int64(oldLen)
- case oldLen == 0 && newLen > 0:
- // Storage creation
- stats.Storages += 1
- stats.StorageBytes += storageKeySize + int64(newLen)
- default:
- // Storage update
- stats.StorageBytes += int64(newLen - oldLen)
- }
- }
- }
-
- // Measure trienode changes
- for owner, subset := range update.Nodes.Sets {
- var (
- keyPrefix int64
- isAccount = owner == (common.Hash{})
- )
- if isAccount {
- keyPrefix = accountTrienodePrefixSize
- } else {
- keyPrefix = storageTrienodePrefixSize
- }
-
- // Iterate over Origins since every modified node has an origin entry
- for path, oldNode := range subset.Origins {
- newNode, exists := subset.Nodes[path]
- if !exists {
- return SizeStats{}, fmt.Errorf("node %x-%v not found", owner, path)
- }
- keySize := keyPrefix + int64(len(path))
-
- switch {
- case len(oldNode) > 0 && len(newNode.Blob) == 0:
- // Node deletion
- if isAccount {
- stats.AccountTrienodes -= 1
- stats.AccountTrienodeBytes -= keySize + int64(len(oldNode))
- } else {
- stats.StorageTrienodes -= 1
- stats.StorageTrienodeBytes -= keySize + int64(len(oldNode))
- }
- case len(oldNode) == 0 && len(newNode.Blob) > 0:
- // Node creation
- if isAccount {
- stats.AccountTrienodes += 1
- stats.AccountTrienodeBytes += keySize + int64(len(newNode.Blob))
- } else {
- stats.StorageTrienodes += 1
- stats.StorageTrienodeBytes += keySize + int64(len(newNode.Blob))
- }
- default:
- // Node update
- if isAccount {
- stats.AccountTrienodeBytes += int64(len(newNode.Blob) - len(oldNode))
- } else {
- stats.StorageTrienodeBytes += int64(len(newNode.Blob) - len(oldNode))
- }
- }
- }
- }
-
- codeExists := make(map[common.Hash]struct{})
- for _, code := range update.Codes {
- if _, ok := codeExists[code.Hash]; ok || code.Duplicate {
- continue
- }
- stats.ContractCodes += 1
- stats.ContractCodeBytes += codeKeySize + int64(len(code.Blob))
- codeExists[code.Hash] = struct{}{}
- }
- return stats, nil
-}
-
-type stateSizeQuery struct {
- root *common.Hash // nil means latest
- err error // non-nil if the state size is not yet initialized
- result chan *SizeStats // nil means the state is unknown
-}
-
-// SizeTracker handles the state size initialization and tracks of state size metrics.
-type SizeTracker struct {
- db ethdb.KeyValueStore
- triedb *triedb.Database
- abort chan struct{}
- aborted chan struct{}
- updateCh chan *StateUpdate
- queryCh chan *stateSizeQuery
-}
-
-// NewSizeTracker creates a new state size tracker and starts it automatically
-func NewSizeTracker(db ethdb.KeyValueStore, triedb *triedb.Database) (*SizeTracker, error) {
- if triedb.Scheme() != rawdb.PathScheme {
- return nil, errors.New("state size tracker is not compatible with hash mode")
- }
- t := &SizeTracker{
- db: db,
- triedb: triedb,
- abort: make(chan struct{}),
- aborted: make(chan struct{}),
- updateCh: make(chan *StateUpdate),
- queryCh: make(chan *stateSizeQuery),
- }
- go t.run()
- return t, nil
-}
-
-func (t *SizeTracker) Stop() {
- close(t.abort)
- <-t.aborted
-}
-
-// sizeStatsHeap is a heap.Interface implementation over statesize statistics for
-// retrieving the oldest statistics for eviction.
-type sizeStatsHeap []SizeStats
-
-func (h sizeStatsHeap) Len() int { return len(h) }
-func (h sizeStatsHeap) Less(i, j int) bool { return h[i].BlockNumber < h[j].BlockNumber }
-func (h sizeStatsHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
-
-func (h *sizeStatsHeap) Push(x any) {
- *h = append(*h, x.(SizeStats))
-}
-
-func (h *sizeStatsHeap) Pop() any {
- old := *h
- n := len(old)
- x := old[n-1]
- *h = old[0 : n-1]
- return x
-}
-
-// run performs the state size initialization and handles updates
-func (t *SizeTracker) run() {
- defer close(t.aborted)
-
- var last common.Hash
- stats, err := t.init() // launch background thread for state size init
- if err != nil {
- return
- }
- h := sizeStatsHeap(slices.Collect(maps.Values(stats)))
- heap.Init(&h)
-
- for {
- select {
- case u := <-t.updateCh:
- base, found := stats[u.OriginRoot]
- if !found {
- log.Debug("Ignored the state size without parent", "parent", u.OriginRoot, "root", u.Root, "number", u.BlockNumber)
- continue
- }
- diff, err := calSizeStats(u)
- if err != nil {
- continue
- }
- stat := base.add(diff)
- stats[u.Root] = stat
- last = u.Root
-
- // Publish statistics to metric system
- stat.publish()
-
- // Evict the stale statistics
- heap.Push(&h, stats[u.Root])
- for len(h) > 0 && u.BlockNumber-h[0].BlockNumber > statEvictThreshold {
- delete(stats, h[0].StateRoot)
- heap.Pop(&h)
- }
- log.Debug("Update state size", "number", stat.BlockNumber, "root", stat.StateRoot, "stat", stat)
-
- case r := <-t.queryCh:
- var root common.Hash
- if r.root != nil {
- root = *r.root
- } else {
- root = last
- }
- if s, ok := stats[root]; ok {
- r.result <- &s
- } else {
- r.result <- nil
- }
-
- case <-t.abort:
- return
- }
- }
-}
-
-type buildResult struct {
- stat SizeStats
- root common.Hash
- blockNumber uint64
- elapsed time.Duration
- err error
-}
-
-func (t *SizeTracker) init() (map[common.Hash]SizeStats, error) {
- // Wait for snapshot completion and then init
- ticker := time.NewTicker(10 * time.Second)
- defer ticker.Stop()
-
-wait:
- for {
- select {
- case <-ticker.C:
- if t.triedb.SnapshotCompleted() {
- break wait
- }
- case <-t.updateCh:
- continue
- case r := <-t.queryCh:
- r.err = errors.New("state size is not initialized yet")
- r.result <- nil
- case <-t.abort:
- return nil, errors.New("size tracker closed")
- }
- }
-
- var (
- updates = make(map[common.Hash]*StateUpdate)
- children = make(map[common.Hash][]common.Hash)
- done chan buildResult
- )
-
- for {
- select {
- case u := <-t.updateCh:
- updates[u.Root] = u
- children[u.OriginRoot] = append(children[u.OriginRoot], u.Root)
- log.Debug("Received state update", "root", u.Root, "blockNumber", u.BlockNumber)
-
- case r := <-t.queryCh:
- r.err = errors.New("state size is not initialized yet")
- r.result <- nil
-
- case <-ticker.C:
- // Only check timer if build hasn't started yet
- if done != nil {
- continue
- }
- root := rawdb.ReadSnapshotRoot(t.db)
- if root == (common.Hash{}) {
- continue
- }
- entry, exists := updates[root]
- if !exists {
- continue
- }
- done = make(chan buildResult)
- go t.build(entry.Root, entry.BlockNumber, done)
- log.Info("Measuring persistent state size", "root", root.Hex(), "number", entry.BlockNumber)
-
- case result := <-done:
- if result.err != nil {
- return nil, result.err
- }
- var (
- stats = make(map[common.Hash]SizeStats)
- apply func(root common.Hash, stat SizeStats) error
- )
- apply = func(root common.Hash, base SizeStats) error {
- for _, child := range children[root] {
- entry, ok := updates[child]
- if !ok {
- return fmt.Errorf("the state update is not found, %x", child)
- }
- diff, err := calSizeStats(entry)
- if err != nil {
- return err
- }
- stats[child] = base.add(diff)
- if err := apply(child, stats[child]); err != nil {
- return err
- }
- }
- return nil
- }
- if err := apply(result.root, result.stat); err != nil {
- return nil, err
- }
-
- // Set initial latest stats
- stats[result.root] = result.stat
- log.Info("Measured persistent state size", "root", result.root, "number", result.blockNumber, "stat", result.stat, "elapsed", common.PrettyDuration(result.elapsed))
- return stats, nil
-
- case <-t.abort:
- return nil, errors.New("size tracker closed")
- }
- }
-}
-
-func (t *SizeTracker) build(root common.Hash, blockNumber uint64, done chan buildResult) {
- // Metrics will be directly updated by each goroutine
- var (
- accounts, accountBytes int64
- storages, storageBytes int64
- codes, codeBytes int64
-
- accountTrienodes, accountTrienodeBytes int64
- storageTrienodes, storageTrienodeBytes int64
-
- group errgroup.Group
- start = time.Now()
- )
-
- // Start all table iterations concurrently with direct metric updates
- group.Go(func() error {
- count, bytes, err := t.iterateTableParallel(t.abort, rawdb.SnapshotAccountPrefix, "account")
- if err != nil {
- return err
- }
- accounts, accountBytes = count, bytes
- return nil
- })
-
- group.Go(func() error {
- count, bytes, err := t.iterateTableParallel(t.abort, rawdb.SnapshotStoragePrefix, "storage")
- if err != nil {
- return err
- }
- storages, storageBytes = count, bytes
- return nil
- })
-
- group.Go(func() error {
- count, bytes, err := t.iterateTableParallel(t.abort, rawdb.TrieNodeAccountPrefix, "accountnode")
- if err != nil {
- return err
- }
- accountTrienodes, accountTrienodeBytes = count, bytes
- return nil
- })
-
- group.Go(func() error {
- count, bytes, err := t.iterateTableParallel(t.abort, rawdb.TrieNodeStoragePrefix, "storagenode")
- if err != nil {
- return err
- }
- storageTrienodes, storageTrienodeBytes = count, bytes
- return nil
- })
-
- group.Go(func() error {
- count, bytes, err := t.iterateTable(t.abort, rawdb.CodePrefix, "contractcode")
- if err != nil {
- return err
- }
- codes, codeBytes = count, bytes
- return nil
- })
-
- // Wait for all goroutines to complete
- if err := group.Wait(); err != nil {
- done <- buildResult{err: err}
- } else {
- stat := SizeStats{
- StateRoot: root,
- BlockNumber: blockNumber,
- Accounts: accounts,
- AccountBytes: accountBytes,
- Storages: storages,
- StorageBytes: storageBytes,
- AccountTrienodes: accountTrienodes,
- AccountTrienodeBytes: accountTrienodeBytes,
- StorageTrienodes: storageTrienodes,
- StorageTrienodeBytes: storageTrienodeBytes,
- ContractCodes: codes,
- ContractCodeBytes: codeBytes,
- }
- done <- buildResult{
- root: root,
- blockNumber: blockNumber,
- stat: stat,
- elapsed: time.Since(start),
- }
- }
-}
-
-// iterateTable performs iteration over a specific table and returns the results.
-func (t *SizeTracker) iterateTable(closed chan struct{}, prefix []byte, name string) (int64, int64, error) {
- var (
- start = time.Now()
- logged = time.Now()
- count, bytes int64
- )
-
- iter := t.db.NewIterator(prefix, nil)
- defer iter.Release()
-
- log.Debug("Iterating state", "category", name)
- for iter.Next() {
- count++
- bytes += int64(len(iter.Key()) + len(iter.Value()))
-
- if time.Since(logged) > time.Second*8 {
- logged = time.Now()
-
- select {
- case <-closed:
- log.Debug("State iteration cancelled", "category", name)
- return 0, 0, errors.New("size tracker closed")
- default:
- log.Debug("Iterating state", "category", name, "count", count, "size", common.StorageSize(bytes))
- }
- }
- }
- // Check for iterator errors
- if err := iter.Error(); err != nil {
- log.Error("Iterator error", "category", name, "err", err)
- return 0, 0, err
- }
- log.Debug("Finished state iteration", "category", name, "count", count, "size", common.StorageSize(bytes), "elapsed", common.PrettyDuration(time.Since(start)))
- return count, bytes, nil
-}
-
-// iterateTableParallel performs parallel iteration over a table by splitting into
-// hex ranges. For storage tables, it splits on the first byte of the account hash
-// (after the prefix).
-func (t *SizeTracker) iterateTableParallel(closed chan struct{}, prefix []byte, name string) (int64, int64, error) {
- var (
- totalCount int64
- totalBytes int64
-
- start = time.Now()
- workers = runtime.NumCPU()
- group errgroup.Group
- mu sync.Mutex
- )
- group.SetLimit(workers)
- log.Debug("Starting parallel state iteration", "category", name, "workers", workers)
-
- if len(prefix) > 0 {
- if blob, err := t.db.Get(prefix); err == nil && len(blob) > 0 {
- // If there's a direct hit on the prefix, include it in the stats
- totalCount = 1
- totalBytes = int64(len(prefix) + len(blob))
- }
- }
- for i := 0; i < 256; i++ {
- h := byte(i)
- group.Go(func() error {
- count, bytes, err := t.iterateTable(closed, slices.Concat(prefix, []byte{h}), fmt.Sprintf("%s-%02x", name, h))
- if err != nil {
- return err
- }
- mu.Lock()
- totalCount += count
- totalBytes += bytes
- mu.Unlock()
- return nil
- })
- }
- if err := group.Wait(); err != nil {
- return 0, 0, err
- }
- log.Debug("Finished parallel state iteration", "category", name, "count", totalCount, "size", common.StorageSize(totalBytes), "elapsed", common.PrettyDuration(time.Since(start)))
- return totalCount, totalBytes, nil
-}
-
-// Notify is an async method used to send the state update to the size tracker.
-// It ignores empty updates (where no state changes occurred).
-// If the channel is full, it drops the update to avoid blocking.
-func (t *SizeTracker) Notify(update *StateUpdate) {
- if update == nil || update.Empty() {
- return
- }
- select {
- case t.updateCh <- update:
- case <-t.abort:
- return
- }
-}
-
-// Query returns the state size specified by the root, or nil if not available.
-// If the root is nil, query the size of latest chain head;
-// If the root is non-nil, query the size of the specified state;
-func (t *SizeTracker) Query(root *common.Hash) (*SizeStats, error) {
- r := &stateSizeQuery{
- root: root,
- result: make(chan *SizeStats, 1),
- }
- select {
- case <-t.aborted:
- return nil, errors.New("state sizer has been closed")
- case t.queryCh <- r:
- return <-r.result, r.err
- }
-}
diff --git a/core/state/state_sizer_test.go b/core/state/state_sizer_test.go
deleted file mode 100644
index 539f160985..0000000000
--- a/core/state/state_sizer_test.go
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2025 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package state
-
-import (
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/tracing"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/triedb"
- "github.com/ethereum/go-ethereum/triedb/pathdb"
- "github.com/holiman/uint256"
-)
-
-func TestSizeTracker(t *testing.T) {
- db := rawdb.NewMemoryDatabase()
- defer db.Close()
-
- tdb := triedb.NewDatabase(db, &triedb.Config{PathDB: pathdb.Defaults})
- sdb := NewDatabase(tdb, nil)
-
- // Generate 50 blocks to establish a baseline
- baselineBlockNum := uint64(50)
- currentRoot := types.EmptyRootHash
-
- addr1 := common.BytesToAddress([]byte{1, 0, 0, 1})
- addr2 := common.BytesToAddress([]byte{1, 0, 0, 2})
- addr3 := common.BytesToAddress([]byte{1, 0, 0, 3})
-
- // Create initial state with fixed accounts
- state, _ := New(currentRoot, sdb)
- state.AddBalance(addr1, uint256.NewInt(1000), tracing.BalanceChangeUnspecified)
- state.SetNonce(addr1, 1, tracing.NonceChangeUnspecified)
- state.SetState(addr1, common.HexToHash("0x1111"), common.HexToHash("0xaaaa"))
- state.SetState(addr1, common.HexToHash("0x2222"), common.HexToHash("0xbbbb"))
-
- state.AddBalance(addr2, uint256.NewInt(2000), tracing.BalanceChangeUnspecified)
- state.SetNonce(addr2, 2, tracing.NonceChangeUnspecified)
- state.SetCode(addr2, []byte{0x60, 0x80, 0x60, 0x40, 0x52}, tracing.CodeChangeUnspecified)
-
- state.AddBalance(addr3, uint256.NewInt(3000), tracing.BalanceChangeUnspecified)
- state.SetNonce(addr3, 3, tracing.NonceChangeUnspecified)
-
- currentRoot, err := state.Commit(1, true, false)
- if err != nil {
- t.Fatalf("Failed to commit initial state: %v", err)
- }
- if err := tdb.Commit(currentRoot, false); err != nil {
- t.Fatalf("Failed to commit initial trie: %v", err)
- }
-
- for i := 1; i < 50; i++ { // blocks 2-50
- blockNum := uint64(i + 1)
-
- newState, err := New(currentRoot, sdb)
- if err != nil {
- t.Fatalf("Failed to create new state at block %d: %v", blockNum, err)
- }
- testAddr := common.BigToAddress(uint256.NewInt(uint64(i + 100)).ToBig())
- newState.AddBalance(testAddr, uint256.NewInt(uint64((i+1)*1000)), tracing.BalanceChangeUnspecified)
- newState.SetNonce(testAddr, uint64(i+10), tracing.NonceChangeUnspecified)
-
- if i%2 == 0 {
- newState.SetState(addr1, common.BigToHash(uint256.NewInt(uint64(i+0x1000)).ToBig()), common.BigToHash(uint256.NewInt(uint64(i+0x2000)).ToBig()))
- }
- if i%3 == 0 {
- newState.SetCode(testAddr, []byte{byte(i), 0x60, 0x80, byte(i + 1), 0x52}, tracing.CodeChangeUnspecified)
- }
- root, err := newState.Commit(blockNum, true, false)
- if err != nil {
- t.Fatalf("Failed to commit state at block %d: %v", blockNum, err)
- }
- if err := tdb.Commit(root, false); err != nil {
- t.Fatalf("Failed to commit trie at block %d: %v", blockNum, err)
- }
- currentRoot = root
- }
- baselineRoot := currentRoot
-
- // Close and reopen the trie database so all async flushes triggered by the
- // baseline commits are written before we measure the baseline snapshot.
- if err := tdb.Close(); err != nil {
- t.Fatalf("Failed to close triedb before baseline measurement: %v", err)
- }
- tdb = triedb.NewDatabase(db, &triedb.Config{PathDB: pathdb.Defaults})
- sdb = NewDatabase(tdb, nil)
-
- // Wait for snapshot completion
- for !tdb.SnapshotCompleted() {
- time.Sleep(100 * time.Millisecond)
- }
-
- // Calculate baseline from the intermediate persisted state
- baselineTracker := &SizeTracker{
- db: db,
- triedb: tdb,
- abort: make(chan struct{}),
- }
- done := make(chan buildResult)
-
- go baselineTracker.build(baselineRoot, baselineBlockNum, done)
- var baselineResult buildResult
- select {
- case baselineResult = <-done:
- if baselineResult.err != nil {
- t.Fatalf("Failed to get baseline stats: %v", baselineResult.err)
- }
- case <-time.After(30 * time.Second):
- t.Fatal("Timeout waiting for baseline stats")
- }
- baseline := baselineResult.stat
-
- // Now start the tracker and notify it of updates that happen AFTER the baseline
- tracker, err := NewSizeTracker(db, tdb)
- if err != nil {
- t.Fatalf("Failed to create size tracker: %v", err)
- }
- defer tracker.Stop()
-
- var trackedUpdates []SizeStats
- currentRoot = baselineRoot
-
- // Generate additional blocks beyond the baseline and track them
- for i := 49; i < 130; i++ { // blocks 51-132
- blockNum := uint64(i + 2)
- newState, err := New(currentRoot, sdb)
- if err != nil {
- t.Fatalf("Failed to create new state at block %d: %v", blockNum, err)
- }
- testAddr := common.BigToAddress(uint256.NewInt(uint64(i + 100)).ToBig())
- newState.AddBalance(testAddr, uint256.NewInt(uint64((i+1)*1000)), tracing.BalanceChangeUnspecified)
- newState.SetNonce(testAddr, uint64(i+10), tracing.NonceChangeUnspecified)
-
- if i%2 == 0 {
- newState.SetState(addr1, common.BigToHash(uint256.NewInt(uint64(i+0x1000)).ToBig()), common.BigToHash(uint256.NewInt(uint64(i+0x2000)).ToBig()))
- }
- if i%3 == 0 {
- newState.SetCode(testAddr, []byte{byte(i), 0x60, 0x80, byte(i + 1), 0x52}, tracing.CodeChangeUnspecified)
- }
- ret, err := newState.commitAndFlush(blockNum, true, false, true)
- if err != nil {
- t.Fatalf("Failed to commit state at block %d: %v", blockNum, err)
- }
- tracker.Notify(ret)
-
- if err := tdb.Commit(ret.Root, false); err != nil {
- t.Fatalf("Failed to commit trie at block %d: %v", blockNum, err)
- }
-
- diff, err := calSizeStats(ret)
- if err != nil {
- t.Fatalf("Failed to calculate size stats for block %d: %v", blockNum, err)
- }
- trackedUpdates = append(trackedUpdates, diff)
- currentRoot = ret.Root
- }
- finalRoot := rawdb.ReadSnapshotRoot(db)
-
- // Ensure all commits are flushed to disk
- if err := tdb.Close(); err != nil {
- t.Fatalf("Failed to close triedb: %v", err)
- }
- // Reopen the database to simulate a restart
- tdb = triedb.NewDatabase(db, &triedb.Config{PathDB: pathdb.Defaults})
- defer tdb.Close()
-
- finalTracker := &SizeTracker{
- db: db,
- triedb: tdb,
- abort: make(chan struct{}),
- }
- finalDone := make(chan buildResult)
-
- go finalTracker.build(finalRoot, uint64(132), finalDone)
- var result buildResult
- select {
- case result = <-finalDone:
- if result.err != nil {
- t.Fatalf("Failed to build final stats: %v", result.err)
- }
- case <-time.After(30 * time.Second):
- t.Fatal("Timeout waiting for final stats")
- }
- actualStats := result.stat
-
- expectedStats := baseline
- for _, diff := range trackedUpdates {
- expectedStats = expectedStats.add(diff)
- }
-
- // The final measured stats should match our calculated expected stats exactly
- if actualStats.Accounts != expectedStats.Accounts {
- t.Errorf("Account count mismatch: baseline(%d) + tracked_changes = %d, but final_measurement = %d", baseline.Accounts, expectedStats.Accounts, actualStats.Accounts)
- }
- if actualStats.AccountBytes != expectedStats.AccountBytes {
- t.Errorf("Account bytes mismatch: expected %d, got %d", expectedStats.AccountBytes, actualStats.AccountBytes)
- }
- if actualStats.Storages != expectedStats.Storages {
- t.Errorf("Storage count mismatch: baseline(%d) + tracked_changes = %d, but final_measurement = %d", baseline.Storages, expectedStats.Storages, actualStats.Storages)
- }
- if actualStats.StorageBytes != expectedStats.StorageBytes {
- t.Errorf("Storage bytes mismatch: expected %d, got %d", expectedStats.StorageBytes, actualStats.StorageBytes)
- }
- if actualStats.ContractCodes != expectedStats.ContractCodes {
- t.Errorf("Contract code count mismatch: baseline(%d) + tracked_changes = %d, but final_measurement = %d", baseline.ContractCodes, expectedStats.ContractCodes, actualStats.ContractCodes)
- }
- if actualStats.ContractCodeBytes != expectedStats.ContractCodeBytes {
- t.Errorf("Contract code bytes mismatch: expected %d, got %d", expectedStats.ContractCodeBytes, actualStats.ContractCodeBytes)
- }
- if actualStats.AccountTrienodes != expectedStats.AccountTrienodes {
- t.Errorf("Account trie nodes mismatch: expected %d, got %d", expectedStats.AccountTrienodes, actualStats.AccountTrienodes)
- }
- if actualStats.AccountTrienodeBytes != expectedStats.AccountTrienodeBytes {
- t.Errorf("Account trie node bytes mismatch: expected %d, got %d", expectedStats.AccountTrienodeBytes, actualStats.AccountTrienodeBytes)
- }
- if actualStats.StorageTrienodes != expectedStats.StorageTrienodes {
- t.Errorf("Storage trie nodes mismatch: expected %d, got %d", expectedStats.StorageTrienodes, actualStats.StorageTrienodes)
- }
- if actualStats.StorageTrienodeBytes != expectedStats.StorageTrienodeBytes {
- t.Errorf("Storage trie node bytes mismatch: expected %d, got %d", expectedStats.StorageTrienodeBytes, actualStats.StorageTrienodeBytes)
- }
-}
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 3994489833..3cc67cebee 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -1459,7 +1459,7 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool, noStorageWiping
}
// CommitWithUpdate writes the state mutations and returns the state update for
-// external processing (e.g., live tracing hooks or size tracker).
+// external processing (e.g., live tracing hooks).
func (s *StateDB) CommitWithUpdate(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, *StateUpdate, error) {
ret, err := s.commitAndFlush(block, deleteEmptyObjects, noStorageWiping, true)
if err != nil {
diff --git a/eth/api_debug.go b/eth/api_debug.go
index 7d512d9d57..fa211ec1ff 100644
--- a/eth/api_debug.go
+++ b/eth/api_debug.go
@@ -494,54 +494,6 @@ func (api *DebugAPI) GetTrieFlushInterval() (string, error) {
return api.eth.blockchain.GetTrieFlushInterval().String(), nil
}
-// StateSize returns the current state size statistics from the state size tracker.
-// Returns an error if the state size tracker is not initialized or if stats are not ready.
-func (api *DebugAPI) StateSize(blockHashOrNumber *rpc.BlockNumberOrHash) (interface{}, error) {
- sizer := api.eth.blockchain.StateSizer()
- if sizer == nil {
- return nil, errors.New("state size tracker is not enabled")
- }
- var (
- err error
- stats *state.SizeStats
- )
- if blockHashOrNumber == nil {
- stats, err = sizer.Query(nil)
- } else {
- header, herr := api.eth.APIBackend.HeaderByNumberOrHash(context.Background(), *blockHashOrNumber)
- if herr != nil || header == nil {
- return nil, fmt.Errorf("block %s is unknown", blockHashOrNumber)
- }
- stats, err = sizer.Query(&header.Root)
- }
- if err != nil {
- return nil, err
- }
- if stats == nil {
- var s string
- if blockHashOrNumber == nil {
- s = "chain head"
- } else {
- s = blockHashOrNumber.String()
- }
- return nil, fmt.Errorf("state size of %s is not available", s)
- }
- return map[string]interface{}{
- "stateRoot": stats.StateRoot,
- "blockNumber": hexutil.Uint64(stats.BlockNumber),
- "accounts": hexutil.Uint64(stats.Accounts),
- "accountBytes": hexutil.Uint64(stats.AccountBytes),
- "storages": hexutil.Uint64(stats.Storages),
- "storageBytes": hexutil.Uint64(stats.StorageBytes),
- "accountTrienodes": hexutil.Uint64(stats.AccountTrienodes),
- "accountTrienodeBytes": hexutil.Uint64(stats.AccountTrienodeBytes),
- "storageTrienodes": hexutil.Uint64(stats.StorageTrienodes),
- "storageTrienodeBytes": hexutil.Uint64(stats.StorageTrienodeBytes),
- "contractCodes": hexutil.Uint64(stats.ContractCodes),
- "contractCodeBytes": hexutil.Uint64(stats.ContractCodeBytes),
- }, nil
-}
-
func (api *DebugAPI) ExecutionWitness(bn rpc.BlockNumberOrHash) (*stateless.ExtWitness, error) {
bc := api.eth.blockchain
block, err := api.eth.APIBackend.BlockByNumberOrHash(context.Background(), bn)
diff --git a/eth/backend.go b/eth/backend.go
index ba9b4d4459..99a358af2a 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -258,7 +258,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
// - DATADIR/triedb/merkle.journal
// - DATADIR/triedb/verkle.journal
TrieJournalDirectory: stack.ResolvePath("triedb"),
- StateSizeTracking: config.EnableStateSizeTracking,
SlowBlockThreshold: config.SlowBlockThreshold,
StatelessSelfValidation: config.StatelessSelfValidation,
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index 8e27a66419..e09f14499e 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -182,9 +182,6 @@ type Config struct {
// Generate execution witnesses and self-check against them (testing purpose)
StatelessSelfValidation bool
- // Enables tracking of state size
- EnableStateSizeTracking bool
-
// SnapV2 enables the experimental snap/2 (EIP-8189, BAL-based) sync protocol:
// the node advertises snap/2 on the wire and uses the snap/2 state syncer.
// It is not safe to enable on public networks yet.
diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go
index 4e61b1cccb..2787b7f354 100644
--- a/eth/ethconfig/gen_config.go
+++ b/eth/ethconfig/gen_config.go
@@ -56,7 +56,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
EnablePreimageRecording bool
EnableWitnessStats bool
StatelessSelfValidation bool
- EnableStateSizeTracking bool
SnapV2 bool
VMTrace string
VMTraceJsonConfig string
@@ -113,7 +112,6 @@ func (c Config) MarshalTOML() (interface{}, error) {
enc.EnablePreimageRecording = c.EnablePreimageRecording
enc.EnableWitnessStats = c.EnableWitnessStats
enc.StatelessSelfValidation = c.StatelessSelfValidation
- enc.EnableStateSizeTracking = c.EnableStateSizeTracking
enc.SnapV2 = c.SnapV2
enc.VMTrace = c.VMTrace
enc.VMTraceJsonConfig = c.VMTraceJsonConfig
@@ -174,7 +172,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
EnablePreimageRecording *bool
EnableWitnessStats *bool
StatelessSelfValidation *bool
- EnableStateSizeTracking *bool
SnapV2 *bool
VMTrace *string
VMTraceJsonConfig *string
@@ -312,9 +309,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
if dec.StatelessSelfValidation != nil {
c.StatelessSelfValidation = *dec.StatelessSelfValidation
}
- if dec.EnableStateSizeTracking != nil {
- c.EnableStateSizeTracking = *dec.EnableStateSizeTracking
- }
if dec.SnapV2 != nil {
c.SnapV2 = *dec.SnapV2
}
diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go
index 85138e9a2c..92e2ec3512 100644
--- a/internal/web3ext/web3ext.go
+++ b/internal/web3ext/web3ext.go
@@ -475,12 +475,6 @@ web3._extend({
call: 'debug_sync',
params: 1
}),
- new web3._extend.Method({
- name: 'stateSize',
- call: 'debug_stateSize',
- params: 1,
- inputFormatter: [null],
- }),
new web3._extend.Method({
name: 'executionWitness',
call: 'debug_executionWitness',