Compare commits

..

10 Commits

Author SHA1 Message Date
will-2012
f5b5805359 Merge pull request #2705 from will-2012/perf-pbssbsc
perf: add db metrics
2024-09-19 11:16:10 +08:00
will@2012
34bc9e02aa Merge remote-tracking branch 'bsc/versa_base' into perf-pbssbsc 2024-09-14 10:09:16 +08:00
will@2012
8a3d62e756 perf: add db metrics 2024-09-14 10:06:38 +08:00
joeycli
d4879836c0 chore: add statedb get metrices 2024-09-06 14:06:12 +08:00
joeycli
4b00174821 chore: add snapshot metrices 2024-09-06 11:04:37 +08:00
joeycli
3082da4e86 chore: add validate metrics 2024-09-04 10:20:47 +08:00
joeycli
d334f520be chore: add state trie metrics 2024-09-04 09:39:08 +08:00
joeycli
cef6acec23 chore: add execute, verify and commit total metrics 2024-09-02 09:08:55 +08:00
joeycli
092fbafa3c chore: delete share mem pool 2024-09-01 12:20:05 +08:00
joeycli
c4e8ec7fea chore: add mgasps metrics 2024-08-29 16:43:04 +08:00
28 changed files with 203 additions and 42 deletions

View File

@@ -349,7 +349,6 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
} }
// Re-create statedb instance with new root upon the updated database // Re-create statedb instance with new root upon the updated database
// for accessing latest states. // for accessing latest states.
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, err = state.New(root, statedb.Database(), nil) statedb, err = state.New(root, statedb.Database(), nil)
if err != nil { if err != nil {
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err)) return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
@@ -359,9 +358,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
} }
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB { func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
sdb := state.NewDatabaseWithConfig(db, &triedb.Config{Preimages: true}) sdb := state.NewDatabaseWithConfig(db, &triedb.Config{Preimages: true})
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, _ := state.New(types.EmptyRootHash, sdb, nil) statedb, _ := state.New(types.EmptyRootHash, sdb, nil)
for addr, a := range accounts { for addr, a := range accounts {
statedb.SetCode(addr, a.Code) statedb.SetCode(addr, a.Code)
@@ -375,7 +372,6 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB
statedb.Finalise(false) statedb.Finalise(false)
statedb.AccountsIntermediateRoot() statedb.AccountsIntermediateRoot()
root, _, _ := statedb.Commit(0, nil) root, _, _ := statedb.Commit(0, nil)
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, _ = state.New(root, sdb, nil) statedb, _ = state.New(root, sdb, nil)
return statedb return statedb
} }

View File

@@ -148,14 +148,12 @@ func runCmd(ctx *cli.Context) error {
} }
db := rawdb.NewMemoryDatabase() db := rawdb.NewMemoryDatabase()
// TODO:: ignore cmd, if use versa if should be nil, if triedb is not used later in this func
triedb := triedb.NewDatabase(db, &triedb.Config{ triedb := triedb.NewDatabase(db, &triedb.Config{
Preimages: preimages, Preimages: preimages,
HashDB: hashdb.Defaults, HashDB: hashdb.Defaults,
}) })
defer triedb.Close() defer triedb.Close()
genesis := genesisConfig.MustCommit(db, triedb) genesis := genesisConfig.MustCommit(db, triedb)
// TODO:: ignore cmd, internally compatible with versa is sufficient.
sdb := state.NewDatabaseWithNodeDB(db, triedb) sdb := state.NewDatabaseWithNodeDB(db, triedb)
statedb, _ = state.New(genesis.Root(), sdb, nil) statedb, _ = state.New(genesis.Root(), sdb, nil)
chainConfig = genesisConfig.Config chainConfig = genesisConfig.Config

View File

@@ -109,7 +109,6 @@ func runStateTest(fname string, cfg vm.Config, jsonOut, dump bool) error {
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root) fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
} }
if dump { // Dump any state to aid debugging if dump { // Dump any state to aid debugging
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
cpy, _ := state.New(root, tstate.StateDB.Database(), nil) cpy, _ := state.New(root, tstate.StateDB.Database(), nil)
dump := cpy.RawDump(nil) dump := cpy.RawDump(nil)
result.State = &dump result.State = &dump

View File

@@ -778,7 +778,6 @@ func parseDumpConfig(ctx *cli.Context, stack *node.Node) (*state.DumpConfig, eth
} }
} else { } else {
// Use latest // Use latest
// TODO:: if versa, scheme = VersaScheme
if scheme == rawdb.PathScheme { if scheme == rawdb.PathScheme {
triedb := triedb.NewDatabase(db, &triedb.Config{PathDB: utils.PathDBConfigAddJournalFilePath(stack, pathdb.ReadOnly)}) triedb := triedb.NewDatabase(db, &triedb.Config{PathDB: utils.PathDBConfigAddJournalFilePath(stack, pathdb.ReadOnly)})
defer triedb.Close() defer triedb.Close()
@@ -834,7 +833,6 @@ func dump(ctx *cli.Context) error {
triedb := utils.MakeTrieDatabase(ctx, stack, db, true, true, false) // always enable preimage lookup triedb := utils.MakeTrieDatabase(ctx, stack, db, true, true, false) // always enable preimage lookup
defer triedb.Close() defer triedb.Close()
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
state, err := state.New(root, state.NewDatabaseWithNodeDB(db, triedb), nil) state, err := state.New(root, state.NewDatabaseWithNodeDB(db, triedb), nil)
if err != nil { if err != nil {
return err return err
@@ -852,7 +850,6 @@ func dumpAllRootHashInPath(ctx *cli.Context) error {
defer stack.Close() defer stack.Close()
db := utils.MakeChainDatabase(ctx, stack, true, false) db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close() defer db.Close()
// TODO:: ignore cmd
triedb := triedb.NewDatabase(db, &triedb.Config{PathDB: utils.PathDBConfigAddJournalFilePath(stack, pathdb.ReadOnly)}) triedb := triedb.NewDatabase(db, &triedb.Config{PathDB: utils.PathDBConfigAddJournalFilePath(stack, pathdb.ReadOnly)})
defer triedb.Close() defer triedb.Close()

View File

@@ -457,7 +457,6 @@ func inspectTrie(ctx *cli.Context) error {
config = triedb.HashDefaults config = triedb.HashDefaults
} }
// TODO:: ignore cmd
triedb := triedb.NewDatabase(db, config) triedb := triedb.NewDatabase(db, config)
theTrie, err := trie.New(trie.TrieID(trieRootHash), triedb) theTrie, err := trie.New(trie.TrieID(trieRootHash), triedb)
if err != nil { if err != nil {
@@ -1269,7 +1268,6 @@ func hbss2pbss(ctx *cli.Context) error {
} }
if lastStateID == 0 || force { if lastStateID == 0 || force {
config := triedb.HashDefaults config := triedb.HashDefaults
// TODO:: ignore cmd
triedb := triedb.NewDatabase(db, config) triedb := triedb.NewDatabase(db, config)
triedb.Cap(0) triedb.Cap(0)
log.Info("hbss2pbss triedb", "scheme", triedb.Scheme()) log.Info("hbss2pbss triedb", "scheme", triedb.Scheme())

View File

@@ -256,7 +256,6 @@ func accessDb(ctx *cli.Context, stack *node.Node) (ethdb.Database, error) {
} else if dbScheme == rawdb.HashScheme { } else if dbScheme == rawdb.HashScheme {
config = triedb.HashDefaults config = triedb.HashDefaults
} }
// TODO:: ignore snapshot
snaptree, err := snapshot.New(snapconfig, chaindb, triedb.NewDatabase(chaindb, config), headBlock.Root(), TriesInMemory, false) snaptree, err := snapshot.New(snapconfig, chaindb, triedb.NewDatabase(chaindb, config), headBlock.Root(), TriesInMemory, false)
if err != nil { if err != nil {
log.Error("snaptree error", "err", err) log.Error("snaptree error", "err", err)

View File

@@ -2589,7 +2589,6 @@ func MakeTrieDatabase(ctx *cli.Context, stack *node.Node, disk ethdb.Database, p
// ignore the parameter silently. TODO(rjl493456442) // ignore the parameter silently. TODO(rjl493456442)
// please config it if read mode is implemented. // please config it if read mode is implemented.
config.HashDB = hashdb.Defaults config.HashDB = hashdb.Defaults
// TODO::skip MakeTrieDatabase
return triedb.NewDatabase(disk, config) return triedb.NewDatabase(disk, config)
} }
if readOnly { if readOnly {
@@ -2598,7 +2597,6 @@ func MakeTrieDatabase(ctx *cli.Context, stack *node.Node, disk ethdb.Database, p
config.PathDB = pathdb.Defaults config.PathDB = pathdb.Defaults
} }
config.PathDB.JournalFilePath = fmt.Sprintf("%s/%s", stack.ResolvePath("chaindata"), eth.JournalFileName) config.PathDB.JournalFilePath = fmt.Sprintf("%s/%s", stack.ResolvePath("chaindata"), eth.JournalFileName)
// TODO::skip MakeTrieDatabase
return triedb.NewDatabase(disk, config) return triedb.NewDatabase(disk, config)
} }

View File

@@ -25,6 +25,7 @@ import (
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
) )
@@ -40,6 +41,12 @@ func EnableRemoteVerifyManager(remoteValidator *remoteVerifyManager) BlockValida
} }
} }
var (
validateBloomTimer = metrics.NewRegisteredTimer("validate/bloom/time", nil)
validateReceiptTimer = metrics.NewRegisteredTimer("validate/receipt/time", nil)
validateRootTimer = metrics.NewRegisteredTimer("validate/root/time", nil)
)
// BlockValidator is responsible for validating block headers, uncles and // BlockValidator is responsible for validating block headers, uncles and
// processed state. // processed state.
// //
@@ -184,6 +191,10 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
// For valid blocks this should always validate to true. // For valid blocks this should always validate to true.
validateFuns := []func() error{ validateFuns := []func() error{
func() error { func() error {
defer func(start time.Time) {
validateBloomTimer.UpdateSince(start)
}(time.Now())
rbloom := types.CreateBloom(receipts) rbloom := types.CreateBloom(receipts)
if rbloom != header.Bloom { if rbloom != header.Bloom {
return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom) return fmt.Errorf("invalid bloom (remote: %x local: %x)", header.Bloom, rbloom)
@@ -191,6 +202,9 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
return nil return nil
}, },
func() error { func() error {
defer func(start time.Time) {
validateReceiptTimer.UpdateSince(start)
}(time.Now())
receiptSha := types.DeriveSha(receipts, trie.NewStackTrie(nil)) receiptSha := types.DeriveSha(receipts, trie.NewStackTrie(nil))
if receiptSha != header.ReceiptHash { if receiptSha != header.ReceiptHash {
return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha) return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha)
@@ -209,6 +223,9 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
}) })
} else { } else {
validateFuns = append(validateFuns, func() error { validateFuns = append(validateFuns, func() error {
defer func(start time.Time) {
validateRootTimer.UpdateSince(start)
}(time.Now())
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root { if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error()) return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error())
} }

View File

@@ -74,6 +74,7 @@ var (
blockInsertMgaspsGauge = metrics.NewRegisteredGauge("chain/insert/mgasps", nil) blockInsertMgaspsGauge = metrics.NewRegisteredGauge("chain/insert/mgasps", nil)
chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil) chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil)
mGasPsGauge = metrics.NewRegisteredGauge("chain/process/gas", nil)
accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil) accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil)
accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil) accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil)
@@ -91,10 +92,13 @@ var (
triedbCommitTimer = metrics.NewRegisteredTimer("chain/triedb/commits", nil) triedbCommitTimer = metrics.NewRegisteredTimer("chain/triedb/commits", nil)
blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil) blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil)
blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil) blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil)
blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil) blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil)
blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil) blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil)
blockValidationTotalTimer = metrics.NewRegisteredTimer("chain/total/validation", nil)
blockExecutionTotalTimer = metrics.NewRegisteredTimer("chain/total/execution", nil)
blockWriteTotalTimer = metrics.NewRegisteredTimer("chain/total/write", nil)
blockReorgMeter = metrics.NewRegisteredMeter("chain/reorg/executes", nil) blockReorgMeter = metrics.NewRegisteredMeter("chain/reorg/executes", nil)
blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil) blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil)
@@ -336,7 +340,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
diffLayerChanCache, _ := exlru.New(diffLayerCacheLimit) diffLayerChanCache, _ := exlru.New(diffLayerCacheLimit)
// Open trie database with provided config // Open trie database with provided config
// TODO:: if versa , have its owen init genesis logic
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig()) triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig())
// Setup the genesis block, commit the provided genesis specification // Setup the genesis block, commit the provided genesis specification
@@ -385,7 +388,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
} }
bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit)) bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit))
bc.forker = NewForkChoice(bc, shouldPreserve) bc.forker = NewForkChoice(bc, shouldPreserve)
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb) bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb)
bc.validator = NewBlockValidator(chainConfig, bc, engine) bc.validator = NewBlockValidator(chainConfig, bc, engine)
bc.prefetcher = NewStatePrefetcher(chainConfig, bc, engine) bc.prefetcher = NewStatePrefetcher(chainConfig, bc, engine)
@@ -2234,7 +2236,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1) parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
} }
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, err := state.NewWithSharedPool(parent.Root, bc.stateCache, bc.snaps) statedb, err := state.NewWithSharedPool(parent.Root, bc.stateCache, bc.snaps)
if err != nil { if err != nil {
return it.index, err return it.index, err
@@ -2271,6 +2272,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
statedb.StopPrefetcher() statedb.StopPrefetcher()
return it.index, err return it.index, err
} }
blockExecutionTotalTimer.UpdateSince(pstart)
ptime := time.Since(pstart) ptime := time.Since(pstart)
// Validate the state using the default validator // Validate the state using the default validator
@@ -2281,6 +2284,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
statedb.StopPrefetcher() statedb.StopPrefetcher()
return it.index, err return it.index, err
} }
blockValidationTotalTimer.UpdateSince(vstart)
vtime := time.Since(vstart) vtime := time.Since(vstart)
proctime := time.Since(start) // processing + validation proctime := time.Since(start) // processing + validation
@@ -2314,6 +2319,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
if err != nil { if err != nil {
return it.index, err return it.index, err
} }
blockWriteTotalTimer.UpdateSince(wstart)
bc.cacheReceipts(block.Hash(), receipts, block) bc.cacheReceipts(block.Hash(), receipts, block)

View File

@@ -64,6 +64,7 @@ func (st *insertStats) report(chain []*types.Block, index int, snapDiffItems, sn
"blocks", st.processed, "txs", txs, "blobs", blobs, "mgas", float64(st.usedGas) / 1000000, "blocks", st.processed, "txs", txs, "blobs", blobs, "mgas", float64(st.usedGas) / 1000000,
"elapsed", common.PrettyDuration(elapsed), "mgasps", mgasps, "elapsed", common.PrettyDuration(elapsed), "mgasps", mgasps,
} }
mGasPsGauge.Update(int64(mgasps))
blockInsertMgaspsGauge.Update(int64(mgasps)) blockInsertMgaspsGauge.Update(int64(mgasps))
if timestamp := time.Unix(int64(end.Time()), 0); time.Since(timestamp) > time.Minute { if timestamp := time.Unix(int64(end.Time()), 0); time.Since(timestamp) > time.Minute {
context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...) context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)

View File

@@ -396,7 +396,6 @@ func (bc *BlockChain) State() (*state.StateDB, error) {
// StateAt returns a new mutable state based on a particular point in time. // StateAt returns a new mutable state based on a particular point in time.
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) { func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
stateDb, err := state.New(root, bc.stateCache, bc.snaps) stateDb, err := state.New(root, bc.stateCache, bc.snaps)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -397,12 +397,10 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
} }
// Forcibly use hash-based state scheme for retaining all nodes in disk. // Forcibly use hash-based state scheme for retaining all nodes in disk.
// TODO:: ignore, only use to UT
triedb := triedb.NewDatabase(db, triedb.HashDefaults) triedb := triedb.NewDatabase(db, triedb.HashDefaults)
defer triedb.Close() defer triedb.Close()
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
// @TODO:: ignore, it used to UT, state.NewDatabase internally compatible with versa is sufficient.
statedb, err := state.New(parent.Root(), state.NewDatabaseWithNodeDB(db, triedb), nil) statedb, err := state.New(parent.Root(), state.NewDatabaseWithNodeDB(db, triedb), nil)
if err != nil { if err != nil {
panic(err) panic(err)

View File

@@ -126,9 +126,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
} }
// Create an ephemeral in-memory database for computing hash, // Create an ephemeral in-memory database for computing hash,
// all the derived states will be discarded to not pollute disk. // all the derived states will be discarded to not pollute disk.
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
db := state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), config) db := state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), config)
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, err := state.New(types.EmptyRootHash, db, nil) statedb, err := state.New(types.EmptyRootHash, db, nil)
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
@@ -156,7 +154,6 @@ func flushAlloc(ga *types.GenesisAlloc, db ethdb.Database, triedb *triedb.Databa
if triedbConfig != nil { if triedbConfig != nil {
triedbConfig.NoTries = false triedbConfig.NoTries = false
} }
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil) statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil)
if err != nil { if err != nil {
return err return err

View File

@@ -34,4 +34,7 @@ var (
slotDeletionCount = metrics.NewRegisteredMeter("state/delete/storage/slot", nil) slotDeletionCount = metrics.NewRegisteredMeter("state/delete/storage/slot", nil)
slotDeletionSize = metrics.NewRegisteredMeter("state/delete/storage/size", nil) slotDeletionSize = metrics.NewRegisteredMeter("state/delete/storage/size", nil)
slotDeletionSkip = metrics.NewRegisteredGauge("state/delete/storage/skip", nil) slotDeletionSkip = metrics.NewRegisteredGauge("state/delete/storage/skip", nil)
accountIntermediateRootTimer = metrics.NewRegisteredTimer("state/account/intermediate/root/time", nil)
storageIntermediateRootTimer = metrics.NewRegisteredTimer("state/storage/intermediate/root/time", nil)
) )

View File

@@ -232,7 +232,6 @@ func pruneAll(maindb ethdb.Database, g *core.Genesis) error {
} }
log.Info("Database compaction finished", "elapsed", common.PrettyDuration(time.Since(cstart))) log.Info("Database compaction finished", "elapsed", common.PrettyDuration(time.Since(cstart)))
} }
// TODO:: ignore, versa has its own prunner
statedb, _ := state.New(common.Hash{}, state.NewDatabase(maindb), nil) statedb, _ := state.New(common.Hash{}, state.NewDatabase(maindb), nil)
for addr, account := range g.Alloc { for addr, account := range g.Alloc {
statedb.AddBalance(addr, uint256.MustFromBig(account.Balance)) statedb.AddBalance(addr, uint256.MustFromBig(account.Balance))

View File

@@ -286,6 +286,13 @@ func (dl *diffLayer) Stale() bool {
// Account directly retrieves the account associated with a particular hash in // Account directly retrieves the account associated with a particular hash in
// the snapshot slim data format. // the snapshot slim data format.
func (dl *diffLayer) Account(hash common.Hash) (*types.SlimAccount, error) { func (dl *diffLayer) Account(hash common.Hash) (*types.SlimAccount, error) {
defer func(start time.Time) {
snapGetTimer.UpdateSince(start)
snapGetQPS.Mark(1)
snapGetAccountTimer.UpdateSince(start)
snapGetAccountQPS.Mark(1)
}(time.Now())
data, err := dl.AccountRLP(hash) data, err := dl.AccountRLP(hash)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -394,6 +401,13 @@ func (dl *diffLayer) accountRLP(hash common.Hash, depth int) ([]byte, error) {
// //
// Note the returned slot is not a copy, please don't modify it. // Note the returned slot is not a copy, please don't modify it.
func (dl *diffLayer) Storage(accountHash, storageHash common.Hash) ([]byte, error) { func (dl *diffLayer) Storage(accountHash, storageHash common.Hash) ([]byte, error) {
defer func(start time.Time) {
snapGetTimer.UpdateSince(start)
snapGetQPS.Mark(1)
snapGetStorageTimer.UpdateSince(start)
snapGetStorageQPS.Mark(1)
}(time.Now())
// Check the bloom filter first whether there's even a point in reaching into // Check the bloom filter first whether there's even a point in reaching into
// all the maps in all the layers below // all the maps in all the layers below
dl.lock.RLock() dl.lock.RLock()

View File

@@ -19,6 +19,7 @@ package snapshot
import ( import (
"bytes" "bytes"
"sync" "sync"
"time"
"github.com/VictoriaMetrics/fastcache" "github.com/VictoriaMetrics/fastcache"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@@ -136,7 +137,12 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
return blob, nil return blob, nil
} }
// Cache doesn't contain account, pull from disk and cache for later // Cache doesn't contain account, pull from disk and cache for later
// TODO:
snapNodeQPS.Mark(1)
startLoadSnapNode := time.Now()
blob := rawdb.ReadAccountSnapshot(dl.diskdb, hash) blob := rawdb.ReadAccountSnapshot(dl.diskdb, hash)
snapNodeTime.Mark(time.Since(startLoadSnapNode).Nanoseconds())
dl.cache.Set(hash[:], blob) dl.cache.Set(hash[:], blob)
snapshotCleanAccountMissMeter.Mark(1) snapshotCleanAccountMissMeter.Mark(1)
@@ -176,7 +182,11 @@ func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
return blob, nil return blob, nil
} }
// Cache doesn't contain storage slot, pull from disk and cache for later // Cache doesn't contain storage slot, pull from disk and cache for later
// TODO:
snapNodeQPS.Mark(1)
startLoadSnapNode := time.Now()
blob := rawdb.ReadStorageSnapshot(dl.diskdb, accountHash, storageHash) blob := rawdb.ReadStorageSnapshot(dl.diskdb, accountHash, storageHash)
snapNodeTime.Mark(time.Since(startLoadSnapNode).Nanoseconds())
dl.cache.Set(key, blob) dl.cache.Set(key, blob)
snapshotCleanStorageMissMeter.Mark(1) snapshotCleanStorageMissMeter.Mark(1)

View File

@@ -50,4 +50,15 @@ var (
snapStorageWriteCounter = metrics.NewRegisteredCounter("state/snapshot/generation/duration/storage/write", nil) snapStorageWriteCounter = metrics.NewRegisteredCounter("state/snapshot/generation/duration/storage/write", nil)
// snapStorageCleanCounter measures time spent on deleting storages // snapStorageCleanCounter measures time spent on deleting storages
snapStorageCleanCounter = metrics.NewRegisteredCounter("state/snapshot/generation/duration/storage/clean", nil) snapStorageCleanCounter = metrics.NewRegisteredCounter("state/snapshot/generation/duration/storage/clean", nil)
snapNodeQPS = metrics.NewRegisteredMeter("pbss/snap/node/qps", nil)
snapNodeTime = metrics.NewRegisteredMeter("pbss/snap/node/time", nil)
snapGetTimer = metrics.NewRegisteredTimer("snap/get/time", nil)
snapGetQPS = metrics.NewRegisteredMeter("snap/get/qps", nil)
snapGetAccountTimer = metrics.NewRegisteredTimer("snap/account/get/time", nil)
snapGetAccountQPS = metrics.NewRegisteredMeter("snap/account/get/qps", nil)
snapGetStorageTimer = metrics.NewRegisteredTimer("snap/storage/get/time", nil)
snapGetStorageQPS = metrics.NewRegisteredMeter("snap/storage/get/qps", nil)
) )

View File

@@ -205,8 +205,6 @@ type Tree struct {
// state trie. // state trie.
// - otherwise, the entire snapshot is considered invalid and will be recreated on // - otherwise, the entire snapshot is considered invalid and will be recreated on
// a background thread. // a background thread.
//
// TODO:: if use versa, set SnapshotLimit == 0, will forbidden to use
func New(config Config, diskdb ethdb.KeyValueStore, triedb *triedb.Database, root common.Hash, cap int, withoutTrie bool) (*Tree, error) { func New(config Config, diskdb ethdb.KeyValueStore, triedb *triedb.Database, root common.Hash, cap int, withoutTrie bool) (*Tree, error) {
snap := &Tree{ snap := &Tree{
config: config, config: config,

View File

@@ -223,6 +223,14 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
return common.Hash{} return common.Hash{}
} }
// If no live objects are available, attempt to use snapshots // If no live objects are available, attempt to use snapshots
defer func(start time.Time) {
stateDBGetTimer.UpdateSince(start)
stateDBGetQPS.Mark(1)
stateDBGetStorageTimer.UpdateSince(start)
stateDBGetStorageQPS.Mark(1)
}(time.Now())
var ( var (
enc []byte enc []byte
err error err error

View File

@@ -54,6 +54,16 @@ type revision struct {
journalIndex int journalIndex int
} }
var (
stateDBGetTimer = metrics.NewRegisteredTimer("statedb/get/time", nil)
stateDBGetQPS = metrics.NewRegisteredMeter("statedb/get/qps", nil)
stateDBGetAccountTimer = metrics.NewRegisteredTimer("statedb/account/get/time", nil)
stateDBGetAccountQPS = metrics.NewRegisteredMeter("statedb/account/get/qps", nil)
stateDBGetStorageTimer = metrics.NewRegisteredTimer("statedb/storage/get/time", nil)
stateDBGetStorageQPS = metrics.NewRegisteredMeter("statedb/storage/get/qps", nil)
)
// StateDB structs within the ethereum protocol are used to store anything // StateDB structs within the ethereum protocol are used to store anything
// within the merkle trie. StateDBs take care of caching and storing // within the merkle trie. StateDBs take care of caching and storing
// nested states. It's the general query interface to retrieve: // nested states. It's the general query interface to retrieve:
@@ -166,7 +176,7 @@ func NewWithSharedPool(root common.Hash, db Database, snaps *snapshot.Tree) (*St
if err != nil { if err != nil {
return nil, err return nil, err
} }
statedb.storagePool = NewStoragePool() //statedb.storagePool = NewStoragePool()
return statedb, nil return statedb, nil
} }
@@ -716,6 +726,14 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
if obj := s.stateObjects[addr]; obj != nil { if obj := s.stateObjects[addr]; obj != nil {
return obj return obj
} }
defer func(start time.Time) {
stateDBGetTimer.UpdateSince(start)
stateDBGetQPS.Mark(1)
stateDBGetAccountTimer.UpdateSince(start)
stateDBGetAccountQPS.Mark(1)
}(time.Now())
// If no live objects are available, attempt to use snapshots // If no live objects are available, attempt to use snapshots
var data *types.StateAccount var data *types.StateAccount
if s.snap != nil { if s.snap != nil {
@@ -1147,6 +1165,10 @@ func (s *StateDB) populateSnapStorage(obj *stateObject) bool {
} }
func (s *StateDB) AccountsIntermediateRoot() { func (s *StateDB) AccountsIntermediateRoot() {
defer func(start time.Time) {
storageIntermediateRootTimer.UpdateSince(start)
}(time.Now())
tasks := make(chan func()) tasks := make(chan func())
finishCh := make(chan struct{}) finishCh := make(chan struct{})
defer close(finishCh) defer close(finishCh)
@@ -1191,6 +1213,9 @@ func (s *StateDB) AccountsIntermediateRoot() {
} }
func (s *StateDB) StateIntermediateRoot() common.Hash { func (s *StateDB) StateIntermediateRoot() common.Hash {
defer func(start time.Time) {
accountIntermediateRootTimer.UpdateSince(start)
}(time.Now())
// If there was a trie prefetcher operating, it gets aborted and irrevocably // If there was a trie prefetcher operating, it gets aborted and irrevocably
// modified after we start retrieving tries. Remove it from the statedb after // modified after we start retrieving tries. Remove it from the statedb after
// this round of use. // this round of use.

View File

@@ -115,7 +115,6 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
setDefaults(cfg) setDefaults(cfg)
if cfg.State == nil { if cfg.State == nil {
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
} }
var ( var (
@@ -150,7 +149,6 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
setDefaults(cfg) setDefaults(cfg)
if cfg.State == nil { if cfg.State == nil {
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
} }
var ( var (

View File

@@ -71,9 +71,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
// the internal junks created by tracing will be persisted into the disk. // the internal junks created by tracing will be persisted into the disk.
// TODO(rjl493456442), clean cache is disabled to prevent memory leak, // TODO(rjl493456442), clean cache is disabled to prevent memory leak,
// please re-enable it for better performance. // please re-enable it for better performance.
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
database = state.NewDatabaseWithConfig(eth.chainDb, triedb.HashDefaults) database = state.NewDatabaseWithConfig(eth.chainDb, triedb.HashDefaults)
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
if statedb, err = state.New(block.Root(), database, nil); err == nil { if statedb, err = state.New(block.Root(), database, nil); err == nil {
log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number()) log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number())
return statedb, noopReleaser, nil return statedb, noopReleaser, nil
@@ -93,16 +91,13 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
// the internal junks created by tracing will be persisted into the disk. // the internal junks created by tracing will be persisted into the disk.
// TODO(rjl493456442), clean cache is disabled to prevent memory leak, // TODO(rjl493456442), clean cache is disabled to prevent memory leak,
// please re-enable it for better performance. // please re-enable it for better performance.
// TODO:: if use versa, tdb == nil
tdb = triedb.NewDatabase(eth.chainDb, triedb.HashDefaults) tdb = triedb.NewDatabase(eth.chainDb, triedb.HashDefaults)
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
database = state.NewDatabaseWithNodeDB(eth.chainDb, tdb) database = state.NewDatabaseWithNodeDB(eth.chainDb, tdb)
// If we didn't check the live database, do check state over ephemeral database, // If we didn't check the live database, do check state over ephemeral database,
// otherwise we would rewind past a persisted block (specific corner case is // otherwise we would rewind past a persisted block (specific corner case is
// chain tracing from the genesis). // chain tracing from the genesis).
if !readOnly { if !readOnly {
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, err = state.New(current.Root(), database, nil) statedb, err = state.New(current.Root(), database, nil)
if err == nil { if err == nil {
return statedb, noopReleaser, nil return statedb, noopReleaser, nil
@@ -121,7 +116,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
return nil, nil, fmt.Errorf("missing block %v %d", current.ParentHash(), current.NumberU64()-1) return nil, nil, fmt.Errorf("missing block %v %d", current.ParentHash(), current.NumberU64()-1)
} }
current = parent current = parent
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, err = state.New(current.Root(), database, nil) statedb, err = state.New(current.Root(), database, nil)
if err == nil { if err == nil {
break break
@@ -169,7 +164,6 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w", return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w",
current.NumberU64(), current.Root().Hex(), err) current.NumberU64(), current.Root().Hex(), err)
} }
// TODO:: state.NewDatabase internally compatible with versa is sufficient.
statedb, err = state.New(root, database, nil) // nolint:staticcheck statedb, err = state.New(root, database, nil) // nolint:staticcheck
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("state reset after block %d failed: %v", current.NumberU64(), err) return nil, nil, fmt.Errorf("state reset after block %d failed: %v", current.NumberU64(), err)

View File

@@ -245,7 +245,6 @@ type BlockStore interface {
HasSeparateBlockStore() bool HasSeparateBlockStore() bool
} }
// @TODO:: add VersaDB() method
// Database contains all the methods required by the high level database to not // Database contains all the methods required by the high level database to not
// only access the key-value data store but also the chain freezer. // only access the key-value data store but also the chain freezer.
type Database interface { type Database interface {

View File

@@ -17,13 +17,48 @@
package trie package trie
import ( import (
"time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/trie/trienode"
"github.com/ethereum/go-ethereum/triedb/database" "github.com/ethereum/go-ethereum/triedb/database"
) )
var (
StateTreeOpenQPS = metrics.NewRegisteredMeter("state/tree/open/qps", nil)
StateTreeOpenTime = metrics.NewRegisteredTimer("state/tree/open/time", nil)
StateTreeGetQPS = metrics.NewRegisteredMeter("state/tree/get/qps", nil)
StateTreeGetTime = metrics.NewRegisteredTimer("state/tree/get/time", nil)
StateAccountTreeGetQPS = metrics.NewRegisteredMeter("state/tree/account/get/qps", nil)
StateAccountTreeGetTime = metrics.NewRegisteredTimer("state/tree/account/get/time", nil)
StateStorageTreeGetQPS = metrics.NewRegisteredMeter("state/tree/storage/get/qps", nil)
StateStorageTreeGetTime = metrics.NewRegisteredTimer("state/tree/storage/get/time", nil)
StateTreePutQPS = metrics.NewRegisteredMeter("state/tree/put/qps", nil)
StateTreePutTime = metrics.NewRegisteredTimer("state/tree/put/time", nil)
StateAccountTreePutQPS = metrics.NewRegisteredMeter("state/tree/account/put/qps", nil)
StateAccountTreePutTime = metrics.NewRegisteredTimer("state/tree/account/put/time", nil)
StateStorageTreePutQPS = metrics.NewRegisteredMeter("state/tree/storage/put/qps", nil)
StateStorageTreePutTime = metrics.NewRegisteredTimer("state/tree/storage/put/time", nil)
StateTreeDelQPS = metrics.NewRegisteredMeter("state/tree/del/qps", nil)
StateTreeDelTime = metrics.NewRegisteredTimer("state/tree/del/time", nil)
StateAccountTreeDelQPS = metrics.NewRegisteredMeter("state/tree/account/del/qps", nil)
StateAccountTreeDelTime = metrics.NewRegisteredTimer("state/tree/account/del/time", nil)
StateStorageTreeDelQPS = metrics.NewRegisteredMeter("state/tree/storage/del/qps", nil)
StateStorageTreeDelTime = metrics.NewRegisteredTimer("state/tree/storage/del/time", nil)
StateTreeCommitQPS = metrics.NewRegisteredMeter("state/tree/commit/qps", nil)
StateTreeCommitTime = metrics.NewRegisteredTimer("state/tree/commit/time", nil)
StateTreeCalcQPS = metrics.NewRegisteredMeter("state/tree/calc/qps", nil)
StateTreeCalcTime = metrics.NewRegisteredTimer("state/tree/calc/time", nil)
)
// SecureTrie is the old name of StateTrie. // SecureTrie is the old name of StateTrie.
// Deprecated: use StateTrie. // Deprecated: use StateTrie.
type SecureTrie = StateTrie type SecureTrie = StateTrie
@@ -63,6 +98,11 @@ type StateTrie struct {
// trie is initially empty. Otherwise, New will panic if db is nil // trie is initially empty. Otherwise, New will panic if db is nil
// and returns MissingNodeError if the root node cannot be found. // and returns MissingNodeError if the root node cannot be found.
func NewStateTrie(id *ID, db database.Database) (*StateTrie, error) { func NewStateTrie(id *ID, db database.Database) (*StateTrie, error) {
defer func(start time.Time) {
StateTreeOpenQPS.Mark(1)
StateTreeOpenTime.UpdateSince(start)
}(time.Now())
if db == nil { if db == nil {
panic("trie.NewStateTrie called without a database") panic("trie.NewStateTrie called without a database")
} }
@@ -87,6 +127,12 @@ func (t *StateTrie) MustGet(key []byte) []byte {
// If the specified storage slot is not in the trie, nil will be returned. // If the specified storage slot is not in the trie, nil will be returned.
// If a trie node is not found in the database, a MissingNodeError is returned. // If a trie node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) { func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) {
defer func(start time.Time) {
StateTreeGetQPS.Mark(1)
StateTreeGetTime.UpdateSince(start)
StateStorageTreeGetQPS.Mark(1)
StateStorageTreeGetTime.UpdateSince(start)
}(time.Now())
enc, err := t.trie.Get(t.hashKey(key)) enc, err := t.trie.Get(t.hashKey(key))
if err != nil || len(enc) == 0 { if err != nil || len(enc) == 0 {
return nil, err return nil, err
@@ -99,6 +145,12 @@ func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) {
// If the specified account is not in the trie, nil will be returned. // If the specified account is not in the trie, nil will be returned.
// If a trie node is not found in the database, a MissingNodeError is returned. // If a trie node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) GetAccount(address common.Address) (*types.StateAccount, error) { func (t *StateTrie) GetAccount(address common.Address) (*types.StateAccount, error) {
defer func(start time.Time) {
StateTreeGetQPS.Mark(1)
StateTreeGetTime.UpdateSince(start)
StateAccountTreeGetQPS.Mark(1)
StateAccountTreeGetTime.UpdateSince(start)
}(time.Now())
res, err := t.trie.Get(t.hashKey(address.Bytes())) res, err := t.trie.Get(t.hashKey(address.Bytes()))
if res == nil || err != nil { if res == nil || err != nil {
return nil, err return nil, err
@@ -153,6 +205,12 @@ func (t *StateTrie) MustUpdate(key, value []byte) {
// //
// If a node is not found in the database, a MissingNodeError is returned. // If a node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error { func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error {
defer func(start time.Time) {
StateTreePutQPS.Mark(1)
StateTreePutTime.UpdateSince(start)
StateStorageTreePutQPS.Mark(1)
StateStorageTreePutTime.UpdateSince(start)
}(time.Now())
hk := t.hashKey(key) hk := t.hashKey(key)
v, _ := rlp.EncodeToBytes(value) v, _ := rlp.EncodeToBytes(value)
err := t.trie.Update(hk, v) err := t.trie.Update(hk, v)
@@ -165,6 +223,12 @@ func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error {
// UpdateAccount will abstract the write of an account to the secure trie. // UpdateAccount will abstract the write of an account to the secure trie.
func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount) error { func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount) error {
defer func(start time.Time) {
StateTreePutQPS.Mark(1)
StateTreePutTime.UpdateSince(start)
StateAccountTreePutQPS.Mark(1)
StateAccountTreePutTime.UpdateSince(start)
}(time.Now())
hk := t.hashKey(address.Bytes()) hk := t.hashKey(address.Bytes())
data, err := rlp.EncodeToBytes(acc) data, err := rlp.EncodeToBytes(acc)
if err != nil { if err != nil {
@@ -193,6 +257,12 @@ func (t *StateTrie) MustDelete(key []byte) {
// If the specified trie node is not in the trie, nothing will be changed. // If the specified trie node is not in the trie, nothing will be changed.
// If a node is not found in the database, a MissingNodeError is returned. // If a node is not found in the database, a MissingNodeError is returned.
func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error { func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error {
defer func(start time.Time) {
StateTreeDelQPS.Mark(1)
StateTreeDelTime.UpdateSince(start)
StateStorageTreeDelQPS.Mark(1)
StateStorageTreeDelTime.UpdateSince(start)
}(time.Now())
hk := t.hashKey(key) hk := t.hashKey(key)
delete(t.getSecKeyCache(), string(hk)) delete(t.getSecKeyCache(), string(hk))
return t.trie.Delete(hk) return t.trie.Delete(hk)
@@ -200,6 +270,12 @@ func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error {
// DeleteAccount abstracts an account deletion from the trie. // DeleteAccount abstracts an account deletion from the trie.
func (t *StateTrie) DeleteAccount(address common.Address) error { func (t *StateTrie) DeleteAccount(address common.Address) error {
defer func(start time.Time) {
StateTreeDelQPS.Mark(1)
StateTreeDelTime.UpdateSince(start)
StateAccountTreeDelQPS.Mark(1)
StateAccountTreeDelTime.UpdateSince(start)
}(time.Now())
hk := t.hashKey(address.Bytes()) hk := t.hashKey(address.Bytes())
delete(t.getSecKeyCache(), string(hk)) delete(t.getSecKeyCache(), string(hk))
return t.trie.Delete(hk) return t.trie.Delete(hk)
@@ -222,6 +298,10 @@ func (t *StateTrie) GetKey(shaKey []byte) []byte {
// Once the trie is committed, it's not usable anymore. A new trie must // Once the trie is committed, it's not usable anymore. A new trie must
// be created with new root and updated trie database for following usage // be created with new root and updated trie database for following usage
func (t *StateTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) { func (t *StateTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) {
defer func(start time.Time) {
StateTreeCommitQPS.Mark(1)
StateTreeCommitTime.UpdateSince(start)
}(time.Now())
// Write all the pre-images to the actual disk database // Write all the pre-images to the actual disk database
if len(t.getSecKeyCache()) > 0 { if len(t.getSecKeyCache()) > 0 {
preimages := make(map[common.Hash][]byte) preimages := make(map[common.Hash][]byte)
@@ -238,6 +318,10 @@ func (t *StateTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, er
// Hash returns the root hash of StateTrie. It does not write to the // Hash returns the root hash of StateTrie. It does not write to the
// database and can be used even if the trie doesn't have one. // database and can be used even if the trie doesn't have one.
func (t *StateTrie) Hash() common.Hash { func (t *StateTrie) Hash() common.Hash {
defer func(start time.Time) {
StateTreeCalcQPS.Mark(1)
StateTreeCalcTime.UpdateSince(start)
}(time.Now())
return t.trie.Hash() return t.trie.Hash()
} }

View File

@@ -246,6 +246,10 @@ func (db *Database) Reader(root common.Hash) (layer, error) {
// The passed in maps(nodes, states) will be retained to avoid copying everything. // The passed in maps(nodes, states) will be retained to avoid copying everything.
// Therefore, these maps must not be changed afterwards. // Therefore, these maps must not be changed afterwards.
func (db *Database) Update(root common.Hash, parentRoot common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *triestate.Set) error { func (db *Database) Update(root common.Hash, parentRoot common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *triestate.Set) error {
defer func(start time.Time) {
PbssUpdateDiffQPS.Mark(1)
PbssUpdateDiffTime.UpdateSince(start)
}(time.Now())
// Hold the lock to prevent concurrent mutations. // Hold the lock to prevent concurrent mutations.
db.lock.Lock() db.lock.Lock()
defer db.lock.Unlock() defer db.lock.Unlock()

View File

@@ -20,6 +20,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"sync" "sync"
"time"
"github.com/VictoriaMetrics/fastcache" "github.com/VictoriaMetrics/fastcache"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@@ -197,11 +198,15 @@ func (dl *diskLayer) Node(owner common.Hash, path []byte, hash common.Hash) ([]b
nBlob []byte nBlob []byte
nHash common.Hash nHash common.Hash
) )
// TODO:
trieNodeQPS.Mark(1)
startLoadTrieNode := time.Now()
if owner == (common.Hash{}) { if owner == (common.Hash{}) {
nBlob, nHash = rawdb.ReadAccountTrieNode(dl.db.diskdb, path) nBlob, nHash = rawdb.ReadAccountTrieNode(dl.db.diskdb, path)
} else { } else {
nBlob, nHash = rawdb.ReadStorageTrieNode(dl.db.diskdb, owner, path) nBlob, nHash = rawdb.ReadStorageTrieNode(dl.db.diskdb, owner, path)
} }
trieNodeTime.Mark(time.Since(startLoadTrieNode).Nanoseconds())
if nHash != hash { if nHash != hash {
diskFalseMeter.Mark(1) diskFalseMeter.Mark(1)
log.Error("Unexpected trie node in disk", "owner", owner, "path", path, "expect", hash, "got", nHash) log.Error("Unexpected trie node in disk", "owner", owner, "path", path, "expect", hash, "got", nHash)

View File

@@ -53,4 +53,10 @@ var (
diffHashCacheMissMeter = metrics.NewRegisteredMeter("pathdb/difflayer/hashcache/miss", nil) diffHashCacheMissMeter = metrics.NewRegisteredMeter("pathdb/difflayer/hashcache/miss", nil)
diffHashCacheSlowPathMeter = metrics.NewRegisteredMeter("pathdb/difflayer/hashcache/slowpath", nil) diffHashCacheSlowPathMeter = metrics.NewRegisteredMeter("pathdb/difflayer/hashcache/slowpath", nil)
diffHashCacheLengthGauge = metrics.NewRegisteredGauge("pathdb/difflayer/hashcache/size", nil) diffHashCacheLengthGauge = metrics.NewRegisteredGauge("pathdb/difflayer/hashcache/size", nil)
PbssUpdateDiffQPS = metrics.NewRegisteredMeter("pbss/difflayer/update/qps", nil)
PbssUpdateDiffTime = metrics.NewRegisteredTimer("pbss/difflayer/update/time", nil)
trieNodeQPS = metrics.NewRegisteredMeter("pbss/trie/node/qps", nil)
trieNodeTime = metrics.NewRegisteredMeter("pbss/trie/node/time", nil)
) )