Skip to content

Commit

Permalink
core: fix metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
rjl493456442 committed Jul 18, 2024
1 parent ac650a1 commit 783fef1
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 29 deletions.
30 changes: 12 additions & 18 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,8 @@ var (
storageUpdateTimer = metrics.NewRegisteredResettingTimer("chain/storage/updates", nil)
storageCommitTimer = metrics.NewRegisteredResettingTimer("chain/storage/commits", nil)

snapshotAccountReadTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/account/reads", nil)
snapshotStorageReadTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/storage/reads", nil)
snapshotCommitTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/commits", nil)

triedbCommitTimer = metrics.NewRegisteredResettingTimer("chain/triedb/commits", nil)
snapshotCommitTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/commits", nil)
triedbCommitTimer = metrics.NewRegisteredResettingTimer("chain/triedb/commits", nil)

blockInsertTimer = metrics.NewRegisteredResettingTimer("chain/inserts", nil)
blockValidationTimer = metrics.NewRegisteredResettingTimer("chain/validation", nil)
Expand Down Expand Up @@ -1951,19 +1948,16 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s
proctime := time.Since(start) // processing + validation

// Update the metrics touched during block processing and validation
accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing)
storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing)
snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) // Account reads are complete(in processing)
snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) // Storage reads are complete(in processing)
accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation)
storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation)
accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation)
triehash := statedb.AccountHashes // The time spent on tries hashing
trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update
trieRead := statedb.SnapshotAccountReads + statedb.AccountReads // The time spent on account read
trieRead += statedb.SnapshotStorageReads + statedb.StorageReads // The time spent on storage read
blockExecutionTimer.Update(ptime - trieRead) // The time spent on EVM processing
blockValidationTimer.Update(vtime - (triehash + trieUpdate)) // The time spent on block validation
accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing)
storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing)
accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation)
storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation)
accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation)
triehash := statedb.AccountHashes // The time spent on tries hashing
trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update
trieRead := statedb.AccountReads + statedb.StorageReads // The time spent on account read and storage read
blockExecutionTimer.Update(ptime - trieRead) // The time spent on EVM processing
blockValidationTimer.Update(vtime - (triehash + trieUpdate)) // The time spent on block validation

// Write the block to the chain and get the status.
var (
Expand Down
5 changes: 5 additions & 0 deletions core/state/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,9 @@ var (
slotDeletionTimer = metrics.NewRegisteredResettingTimer("state/delete/storage/timer", nil)
slotDeletionCount = metrics.NewRegisteredMeter("state/delete/storage/slot", nil)
slotDeletionSize = metrics.NewRegisteredMeter("state/delete/storage/size", nil)

trieAccountReadTimer = metrics.NewRegisteredResettingTimer("state/trie/account/reads", nil)
trieStorageReadTimer = metrics.NewRegisteredResettingTimer("state/trie/storage/reads", nil)
snapshotAccountReadTimer = metrics.NewRegisteredResettingTimer("state/snapshot/account/reads", nil)
snapshotStorageReadTimer = metrics.NewRegisteredResettingTimer("state/snapshot/storage/reads", nil)
)
64 changes: 64 additions & 0 deletions core/state/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package state
import (
"errors"
"maps"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state/snapshot"
Expand Down Expand Up @@ -48,6 +49,10 @@ type Reader interface {
// - The returned storage slot is safe to modify after the call
Storage(addr common.Address, slot common.Hash) (common.Hash, error)

// Stats returns the statistics of the reader, specifically detailing the time
// spent on account reading and storage reading.
Stats() (time.Duration, time.Duration)

// Copy returns a deep-copied state reader.
Copy() Reader
}
Expand All @@ -57,6 +62,9 @@ type Reader interface {
type stateReader struct {
snap snapshot.Snapshot
buff crypto.KeccakState

accountTime time.Duration
storageTime time.Duration
}

// newStateReader constructs a flat state reader with on the specified state root.
Expand All @@ -78,6 +86,11 @@ func newStateReader(root common.Hash, snaps *snapshot.Tree) (*stateReader, error
//
// The returned account might be nil if it's not existent.
func (r *stateReader) Account(addr common.Address) (*types.StateAccount, error) {
defer func(start time.Time) {
r.accountTime += time.Since(start)
snapshotAccountReadTimer.UpdateSince(start)
}(time.Now())

ret, err := r.snap.Account(crypto.HashData(r.buff, addr.Bytes()))
if err != nil {
return nil, err
Expand Down Expand Up @@ -108,6 +121,11 @@ func (r *stateReader) Account(addr common.Address) (*types.StateAccount, error)
//
// The returned storage slot might be empty if it's not existent.
func (r *stateReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) {
defer func(start time.Time) {
r.storageTime += time.Since(start)
snapshotStorageReadTimer.UpdateSince(start)
}(time.Now())

addrHash := crypto.HashData(r.buff, addr.Bytes())
slotHash := crypto.HashData(r.buff, key.Bytes())
ret, err := r.snap.Storage(addrHash, slotHash)
Expand All @@ -126,11 +144,20 @@ func (r *stateReader) Storage(addr common.Address, key common.Hash) (common.Hash
return value, nil
}

// Stats implements Reader, returning the time spent on account reading and
// storage reading from the snapshot.
func (r *stateReader) Stats() (time.Duration, time.Duration) {
return r.accountTime, r.storageTime
}

// Copy implements Reader, returning a deep-copied snap reader.
func (r *stateReader) Copy() Reader {
return &stateReader{
snap: r.snap,
buff: crypto.NewKeccakState(),

// statistics (accountTime and storageTime) are not copied, as they
// only belong to current reader instance.
}
}

Expand All @@ -143,6 +170,9 @@ type trieReader struct {
mainTrie Trie // Main trie, resolved in constructor
subRoots map[common.Address]common.Hash // Set of storage roots, cached when the account is resolved
subTries map[common.Address]Trie // Group of storage tries, cached when it's resolved

accountTime time.Duration // Time spent on the account reading
storageTime time.Duration // Time spent on the storage reading
}

// trieReader constructs a trie reader of the specific state. An error will be
Expand Down Expand Up @@ -175,6 +205,11 @@ func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCach
// An error will be returned if the trie state is corrupted. An nil account
// will be returned if it's not existent in the trie.
func (r *trieReader) Account(addr common.Address) (*types.StateAccount, error) {
defer func(start time.Time) {
r.accountTime += time.Since(start)
trieAccountReadTimer.UpdateSince(start)
}(time.Now())

account, err := r.mainTrie.GetAccount(addr)
if err != nil {
return nil, err
Expand All @@ -193,6 +228,11 @@ func (r *trieReader) Account(addr common.Address) (*types.StateAccount, error) {
// An error will be returned if the trie state is corrupted. An empty storage
// slot will be returned if it's not existent in the trie.
func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) {
defer func(start time.Time) {
r.storageTime += time.Since(start)
trieStorageReadTimer.UpdateSince(start)
}(time.Now())

var (
tr Trie
found bool
Expand Down Expand Up @@ -230,6 +270,12 @@ func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash,
return value, nil
}

// Stats implements Reader, returning the time spent on account reading and
// storage reading from the trie.
func (r *trieReader) Stats() (time.Duration, time.Duration) {
return r.accountTime, r.storageTime
}

// Copy implements Reader, returning a deep-copied trie reader.
func (r *trieReader) Copy() Reader {
tries := make(map[common.Address]Trie)
Expand All @@ -243,6 +289,9 @@ func (r *trieReader) Copy() Reader {
mainTrie: mustCopyTrie(r.mainTrie),
subRoots: maps.Clone(r.subRoots),
subTries: tries,

// statistics (accountTime and storageTime) are not copied, as they
// only belong to current reader instance.
}
}

Expand Down Expand Up @@ -301,6 +350,21 @@ func (r *multiReader) Storage(addr common.Address, slot common.Hash) (common.Has
return common.Hash{}, errors.Join(errs...)
}

// Stats implements Reader, returning the time spent on account reading and
// storage reading from the reader.
func (r *multiReader) Stats() (time.Duration, time.Duration) {
var (
accountTime time.Duration
storageTime time.Duration
)
for _, reader := range r.readers {
aTime, sTime := reader.Stats()
accountTime += aTime
storageTime += sTime
}
return accountTime, storageTime
}

// Copy implementing Reader interface, returning a deep-copied state reader.
func (r *multiReader) Copy() Reader {
var readers []Reader
Expand Down
26 changes: 15 additions & 11 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,17 +149,16 @@ type StateDB struct {
witness *stateless.Witness

// Measurements gathered during execution for debugging purposes
AccountReads time.Duration
AccountHashes time.Duration
AccountUpdates time.Duration
AccountCommits time.Duration
StorageReads time.Duration
StorageUpdates time.Duration
StorageCommits time.Duration
SnapshotAccountReads time.Duration
SnapshotStorageReads time.Duration
SnapshotCommits time.Duration
TrieDBCommits time.Duration
AccountReads time.Duration
AccountHashes time.Duration
AccountUpdates time.Duration
AccountCommits time.Duration
StorageReads time.Duration
StorageUpdates time.Duration
StorageCommits time.Duration

SnapshotCommits time.Duration
TrieDBCommits time.Duration

AccountUpdated int
StorageUpdated atomic.Int64
Expand Down Expand Up @@ -1308,6 +1307,11 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool) (*stateU
s.TrieDBCommits += time.Since(start)
}
}
// Submit the statistics of reader to metric system and reset it with new root
aTime, sTime := s.reader.Stats()
s.AccountReads += aTime
s.AccountReads += sTime

s.reader, _ = s.db.Reader(s.originalRoot)
return ret, err
}
Expand Down

0 comments on commit 783fef1

Please sign in to comment.