mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 05:36:46 +00:00
concurrent iterate snapshot
Signed-off-by: jsvisa <delweng@gmail.com>
This commit is contained in:
parent
485d1b136f
commit
cd6b23b3a2
1 changed files with 42 additions and 75 deletions
|
|
@ -17,13 +17,11 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
|
|
@ -136,86 +134,55 @@ func (g *stateSizeGenerator) hasExistingMetrics() bool {
|
||||||
// initializeMetrics performs the actual metrics initialization
|
// initializeMetrics performs the actual metrics initialization
|
||||||
func (g *stateSizeGenerator) initializeMetrics() {
|
func (g *stateSizeGenerator) initializeMetrics() {
|
||||||
var (
|
var (
|
||||||
accountCount, accountBytes uint64
|
wg sync.WaitGroup
|
||||||
storageCount, storageBytes uint64
|
accountCount, accountBytes uint64
|
||||||
trieNodeCount, trieNodeBytes uint64
|
storageCount, storageBytes uint64
|
||||||
contractCount, contractBytes uint64
|
trieAccountNodeCount, trieAccountNodeBytes uint64
|
||||||
|
trieStorageNodeCount, trieStorageNodeBytes uint64
|
||||||
|
contractCount, contractBytes uint64
|
||||||
)
|
)
|
||||||
|
|
||||||
// Process accounts
|
iterate := func(prefix []byte, name string, count, bytes uint64) {
|
||||||
log.Info("Initializing account metrics")
|
defer wg.Done()
|
||||||
accountIter := g.db.NewIterator(rawdb.SnapshotAccountPrefix, nil)
|
|
||||||
defer accountIter.Release()
|
|
||||||
|
|
||||||
for accountIter.Next() {
|
log.Info("Iterating over state size", "table", name)
|
||||||
key := accountIter.Key()
|
defer func(st time.Time) {
|
||||||
value := accountIter.Value()
|
log.Info("Finished iterating over state size", "table", name, "count", count, "bytes", bytes, "elapsed", common.PrettyDuration(time.Since(st)))
|
||||||
|
}(time.Now())
|
||||||
|
|
||||||
// Count account
|
iter := g.db.NewIterator(prefix, nil)
|
||||||
accountCount++
|
defer iter.Release()
|
||||||
accountBytes += uint64(len(key) + len(value))
|
for iter.Next() {
|
||||||
|
count++
|
||||||
|
bytes += uint64(len(iter.Key()) + len(iter.Value()))
|
||||||
|
|
||||||
// Check if account has code (contract)
|
// Check for abort
|
||||||
var account types.StateAccount
|
select {
|
||||||
if err := rlp.DecodeBytes(value, &account); err == nil {
|
case abort := <-g.abort:
|
||||||
if !bytes.Equal(account.CodeHash, types.EmptyCodeHash[:]) {
|
close(abort)
|
||||||
contractCount++
|
default:
|
||||||
// Code size will be counted separately
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process storage for this account
|
|
||||||
storageIter := g.db.NewIterator(append(rawdb.SnapshotStoragePrefix, key[1:]...), nil)
|
|
||||||
for storageIter.Next() {
|
|
||||||
storageKey := storageIter.Key()
|
|
||||||
storageValue := storageIter.Value()
|
|
||||||
storageCount++
|
|
||||||
storageBytes += uint64(len(storageKey) + len(storageValue))
|
|
||||||
}
|
|
||||||
storageIter.Release()
|
|
||||||
|
|
||||||
// Check for abort
|
|
||||||
select {
|
|
||||||
case abort := <-g.abort:
|
|
||||||
close(abort)
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process trie nodes
|
tables := []struct {
|
||||||
log.Info("Initializing trie node metrics")
|
prefix []byte
|
||||||
trieNodeIter := g.db.NewIterator(rawdb.TrieNodeAccountPrefix, nil)
|
name string
|
||||||
defer trieNodeIter.Release()
|
count *uint64
|
||||||
|
bytes *uint64
|
||||||
for trieNodeIter.Next() {
|
}{
|
||||||
key := trieNodeIter.Key()
|
{rawdb.SnapshotAccountPrefix, "account", &accountCount, &accountBytes},
|
||||||
value := trieNodeIter.Value()
|
{rawdb.SnapshotStoragePrefix, "storage", &storageCount, &storageBytes},
|
||||||
trieNodeCount++
|
{rawdb.TrieNodeAccountPrefix, "trie account node", &trieAccountNodeCount, &trieAccountNodeBytes},
|
||||||
trieNodeBytes += uint64(len(key) + len(value))
|
{rawdb.TrieNodeStoragePrefix, "trie storage node", &trieStorageNodeCount, &trieStorageNodeBytes},
|
||||||
|
{rawdb.CodePrefix, "contract code", &contractCount, &contractBytes},
|
||||||
|
}
|
||||||
|
wg.Add(len(tables))
|
||||||
|
for _, table := range tables {
|
||||||
|
go iterate(table.prefix, table.name, *table.count, *table.bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process storage trie nodes
|
wg.Wait()
|
||||||
storageTrieIter := g.db.NewIterator(rawdb.TrieNodeStoragePrefix, nil)
|
|
||||||
defer storageTrieIter.Release()
|
|
||||||
|
|
||||||
for storageTrieIter.Next() {
|
|
||||||
key := storageTrieIter.Key()
|
|
||||||
value := storageTrieIter.Value()
|
|
||||||
trieNodeCount++
|
|
||||||
trieNodeBytes += uint64(len(key) + len(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process contract code
|
|
||||||
log.Info("Initializing contract code metrics")
|
|
||||||
codeIter := g.db.NewIterator(rawdb.CodePrefix, nil)
|
|
||||||
defer codeIter.Release()
|
|
||||||
|
|
||||||
for codeIter.Next() {
|
|
||||||
key := codeIter.Key()
|
|
||||||
value := codeIter.Value()
|
|
||||||
contractBytes += uint64(len(key) + len(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update metrics
|
// Update metrics
|
||||||
g.metricsLock.Lock()
|
g.metricsLock.Lock()
|
||||||
|
|
@ -223,8 +190,8 @@ func (g *stateSizeGenerator) initializeMetrics() {
|
||||||
g.metrics.AccountBytes = accountBytes
|
g.metrics.AccountBytes = accountBytes
|
||||||
g.metrics.StorageCount = storageCount
|
g.metrics.StorageCount = storageCount
|
||||||
g.metrics.StorageBytes = storageBytes
|
g.metrics.StorageBytes = storageBytes
|
||||||
g.metrics.TrieNodeCount = trieNodeCount
|
g.metrics.TrieNodeCount = trieAccountNodeCount + trieStorageNodeCount
|
||||||
g.metrics.TrieNodeBytes = trieNodeBytes
|
g.metrics.TrieNodeBytes = trieAccountNodeBytes + trieStorageNodeBytes
|
||||||
g.metrics.ContractCount = contractCount
|
g.metrics.ContractCount = contractCount
|
||||||
g.metrics.ContractBytes = contractBytes
|
g.metrics.ContractBytes = contractBytes
|
||||||
g.metricsLock.Unlock()
|
g.metricsLock.Unlock()
|
||||||
|
|
@ -237,8 +204,8 @@ func (g *stateSizeGenerator) initializeMetrics() {
|
||||||
stateSizeAccountsBytesMeter.Mark(int64(accountBytes))
|
stateSizeAccountsBytesMeter.Mark(int64(accountBytes))
|
||||||
stateSizeStorageCountMeter.Mark(int64(storageCount))
|
stateSizeStorageCountMeter.Mark(int64(storageCount))
|
||||||
stateSizeStorageBytesMeter.Mark(int64(storageBytes))
|
stateSizeStorageBytesMeter.Mark(int64(storageBytes))
|
||||||
stateSizeTrieNodesCountMeter.Mark(int64(trieNodeCount))
|
stateSizeTrieNodesCountMeter.Mark(int64(trieAccountNodeCount + trieStorageNodeCount))
|
||||||
stateSizeTrieNodesBytesMeter.Mark(int64(trieNodeBytes))
|
stateSizeTrieNodesBytesMeter.Mark(int64(trieStorageNodeBytes + trieStorageNodeBytes))
|
||||||
stateSizeContractsCountMeter.Mark(int64(contractCount))
|
stateSizeContractsCountMeter.Mark(int64(contractCount))
|
||||||
stateSizeContractsBytesMeter.Mark(int64(contractBytes))
|
stateSizeContractsBytesMeter.Mark(int64(contractBytes))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue