core/state: export statistics to metrics (#33254)
Some checks are pending
/ Keeper Build (push) Waiting to run
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run

This PR exposes the state size statistics to the metrics, making them
easier to demonstrate.

Note that the contract code included in the metrics is not
de-duplicated, so the reported size
will appear larger than the actual storage footprint.
This commit is contained in:
rjl493456442 2025-12-02 23:28:51 +08:00 committed by GitHub
parent 212967d0e1
commit d3679c2f2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -31,6 +31,7 @@ import (
"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"
)
@ -48,6 +49,21 @@ var (
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 {
@ -76,6 +92,20 @@ func (s SizeStats) String() string {
)
}
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
@ -309,6 +339,10 @@ func (t *SizeTracker) run() {
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 u.blockNumber-h[0].BlockNumber > statEvictThreshold {
delete(stats, h[0].StateRoot)