Compare commits
19 Commits
faucet-rat
...
versa_base
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5b5805359 | ||
|
|
34bc9e02aa | ||
|
|
8a3d62e756 | ||
|
|
d4879836c0 | ||
|
|
4b00174821 | ||
|
|
3082da4e86 | ||
|
|
d334f520be | ||
|
|
cef6acec23 | ||
|
|
092fbafa3c | ||
|
|
c4e8ec7fea | ||
|
|
83a9b13771 | ||
|
|
c6cb43b7ca | ||
|
|
222e10810e | ||
|
|
26b236fb5f | ||
|
|
900cf26c65 | ||
|
|
75d162983a | ||
|
|
719412551a | ||
|
|
f0c7795542 | ||
|
|
4566ac7659 |
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/consensus"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"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
|
||||
// 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.
|
||||
validateFuns := []func() error{
|
||||
func() error {
|
||||
defer func(start time.Time) {
|
||||
validateBloomTimer.UpdateSince(start)
|
||||
}(time.Now())
|
||||
|
||||
rbloom := types.CreateBloom(receipts)
|
||||
if rbloom != header.Bloom {
|
||||
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
|
||||
},
|
||||
func() error {
|
||||
defer func(start time.Time) {
|
||||
validateReceiptTimer.UpdateSince(start)
|
||||
}(time.Now())
|
||||
receiptSha := types.DeriveSha(receipts, trie.NewStackTrie(nil))
|
||||
if receiptSha != header.ReceiptHash {
|
||||
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 {
|
||||
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 {
|
||||
return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error())
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ var (
|
||||
blockInsertMgaspsGauge = metrics.NewRegisteredGauge("chain/insert/mgasps", nil)
|
||||
|
||||
chainInfoGauge = metrics.NewRegisteredGaugeInfo("chain/info", nil)
|
||||
mGasPsGauge = metrics.NewRegisteredGauge("chain/process/gas", nil)
|
||||
|
||||
accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil)
|
||||
accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil)
|
||||
@@ -91,10 +92,13 @@ var (
|
||||
|
||||
triedbCommitTimer = metrics.NewRegisteredTimer("chain/triedb/commits", nil)
|
||||
|
||||
blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil)
|
||||
blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil)
|
||||
blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", nil)
|
||||
blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil)
|
||||
blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil)
|
||||
blockValidationTimer = metrics.NewRegisteredTimer("chain/validation", nil)
|
||||
blockExecutionTimer = metrics.NewRegisteredTimer("chain/execution", 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)
|
||||
blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil)
|
||||
@@ -1798,6 +1802,12 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||
if err := blockBatch.Write(); err != nil {
|
||||
log.Crit("Failed to write block into disk", "err", err)
|
||||
}
|
||||
bc.hc.tdCache.Add(block.Hash(), externTd)
|
||||
bc.blockCache.Add(block.Hash(), block)
|
||||
bc.receiptsCache.Add(block.Hash(), receipts)
|
||||
if bc.chainConfig.IsCancun(block.Number(), block.Time()) {
|
||||
bc.sidecarsCache.Add(block.Hash(), block.Sidecars())
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
@@ -1908,30 +1918,26 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||
|
||||
// WriteBlockAndSetHead writes the given block and all associated state to the database,
|
||||
// and applies the block as the new chain head.
|
||||
func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool, mux *event.TypeMux) (status WriteStatus, err error) {
|
||||
func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
|
||||
if !bc.chainmu.TryLock() {
|
||||
return NonStatTy, errChainStopped
|
||||
}
|
||||
defer bc.chainmu.Unlock()
|
||||
|
||||
return bc.writeBlockAndSetHead(block, receipts, logs, state, emitHeadEvent, mux)
|
||||
return bc.writeBlockAndSetHead(block, receipts, logs, state, emitHeadEvent)
|
||||
}
|
||||
|
||||
// writeBlockAndSetHead is the internal implementation of WriteBlockAndSetHead.
|
||||
// This function expects the chain mutex to be held.
|
||||
func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool, mux *event.TypeMux) (status WriteStatus, err error) {
|
||||
func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
|
||||
if err := bc.writeBlockWithState(block, receipts, state); err != nil {
|
||||
return NonStatTy, err
|
||||
}
|
||||
currentBlock := bc.CurrentBlock()
|
||||
reorg, err := bc.forker.ReorgNeededWithFastFinality(currentBlock, block.Header())
|
||||
if err != nil {
|
||||
return NonStatTy, err
|
||||
}
|
||||
if reorg && mux != nil {
|
||||
mux.Post(NewSealedBlockEvent{Block: block})
|
||||
}
|
||||
|
||||
if err := bc.writeBlockWithState(block, receipts, state); err != nil {
|
||||
return NonStatTy, err
|
||||
}
|
||||
if reorg {
|
||||
// Reorganise the chain if the parent is not the head block
|
||||
if block.ParentHash() != currentBlock.Hash() {
|
||||
@@ -2266,6 +2272,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||
statedb.StopPrefetcher()
|
||||
return it.index, err
|
||||
}
|
||||
blockExecutionTotalTimer.UpdateSince(pstart)
|
||||
|
||||
ptime := time.Since(pstart)
|
||||
|
||||
// Validate the state using the default validator
|
||||
@@ -2276,6 +2284,8 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||
statedb.StopPrefetcher()
|
||||
return it.index, err
|
||||
}
|
||||
blockValidationTotalTimer.UpdateSince(vstart)
|
||||
|
||||
vtime := time.Since(vstart)
|
||||
proctime := time.Since(start) // processing + validation
|
||||
|
||||
@@ -2304,11 +2314,12 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||
// Don't set the head, only insert the block
|
||||
err = bc.writeBlockWithState(block, receipts, statedb)
|
||||
} else {
|
||||
status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false, nil)
|
||||
status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false)
|
||||
}
|
||||
if err != nil {
|
||||
return it.index, err
|
||||
}
|
||||
blockWriteTotalTimer.UpdateSince(wstart)
|
||||
|
||||
bc.cacheReceipts(block.Hash(), receipts, block)
|
||||
|
||||
|
||||
@@ -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,
|
||||
"elapsed", common.PrettyDuration(elapsed), "mgasps", mgasps,
|
||||
}
|
||||
mGasPsGauge.Update(int64(mgasps))
|
||||
blockInsertMgaspsGauge.Update(int64(mgasps))
|
||||
if timestamp := time.Unix(int64(end.Time()), 0); time.Since(timestamp) > time.Minute {
|
||||
context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...)
|
||||
|
||||
@@ -27,10 +27,7 @@ type NewTxsEvent struct{ Txs []*types.Transaction }
|
||||
// ReannoTxsEvent is posted when a batch of local pending transactions exceed a specified duration.
|
||||
type ReannoTxsEvent struct{ Txs []*types.Transaction }
|
||||
|
||||
// NewSealedBlockEvent is posted when a block has been sealed.
|
||||
type NewSealedBlockEvent struct{ Block *types.Block }
|
||||
|
||||
// NewMinedBlockEvent is posted when a block has been mined.
|
||||
// NewMinedBlockEvent is posted when a block has been imported.
|
||||
type NewMinedBlockEvent struct{ Block *types.Block }
|
||||
|
||||
// RemovedLogsEvent is posted when a reorg happens
|
||||
|
||||
@@ -34,4 +34,7 @@ var (
|
||||
slotDeletionCount = metrics.NewRegisteredMeter("state/delete/storage/slot", nil)
|
||||
slotDeletionSize = metrics.NewRegisteredMeter("state/delete/storage/size", 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)
|
||||
)
|
||||
|
||||
@@ -286,6 +286,13 @@ func (dl *diffLayer) Stale() bool {
|
||||
// Account directly retrieves the account associated with a particular hash in
|
||||
// the snapshot slim data format.
|
||||
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)
|
||||
if err != nil {
|
||||
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.
|
||||
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
|
||||
// all the maps in all the layers below
|
||||
dl.lock.RLock()
|
||||
|
||||
@@ -19,6 +19,7 @@ package snapshot
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/fastcache"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@@ -136,7 +137,12 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
|
||||
return blob, nil
|
||||
}
|
||||
// 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)
|
||||
snapNodeTime.Mark(time.Since(startLoadSnapNode).Nanoseconds())
|
||||
|
||||
dl.cache.Set(hash[:], blob)
|
||||
|
||||
snapshotCleanAccountMissMeter.Mark(1)
|
||||
@@ -176,7 +182,11 @@ func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
|
||||
return blob, nil
|
||||
}
|
||||
// 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)
|
||||
snapNodeTime.Mark(time.Since(startLoadSnapNode).Nanoseconds())
|
||||
dl.cache.Set(key, blob)
|
||||
|
||||
snapshotCleanStorageMissMeter.Mark(1)
|
||||
|
||||
@@ -50,4 +50,15 @@ var (
|
||||
snapStorageWriteCounter = metrics.NewRegisteredCounter("state/snapshot/generation/duration/storage/write", nil)
|
||||
// snapStorageCleanCounter measures time spent on deleting storages
|
||||
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)
|
||||
)
|
||||
|
||||
@@ -223,6 +223,14 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
||||
return common.Hash{}
|
||||
}
|
||||
// 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 (
|
||||
enc []byte
|
||||
err error
|
||||
|
||||
@@ -54,6 +54,16 @@ type revision struct {
|
||||
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
|
||||
// within the merkle trie. StateDBs take care of caching and storing
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
statedb.storagePool = NewStoragePool()
|
||||
//statedb.storagePool = NewStoragePool()
|
||||
return statedb, nil
|
||||
}
|
||||
|
||||
@@ -716,6 +726,14 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
||||
if obj := s.stateObjects[addr]; obj != nil {
|
||||
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
|
||||
var data *types.StateAccount
|
||||
if s.snap != nil {
|
||||
@@ -1147,6 +1165,10 @@ func (s *StateDB) populateSnapStorage(obj *stateObject) bool {
|
||||
}
|
||||
|
||||
func (s *StateDB) AccountsIntermediateRoot() {
|
||||
defer func(start time.Time) {
|
||||
storageIntermediateRootTimer.UpdateSince(start)
|
||||
}(time.Now())
|
||||
|
||||
tasks := make(chan func())
|
||||
finishCh := make(chan struct{})
|
||||
defer close(finishCh)
|
||||
@@ -1191,6 +1213,9 @@ func (s *StateDB) AccountsIntermediateRoot() {
|
||||
}
|
||||
|
||||
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
|
||||
// modified after we start retrieving tries. Remove it from the statedb after
|
||||
// this round of use.
|
||||
|
||||
@@ -729,7 +729,7 @@ func (h *handler) Start(maxPeers int, maxPeersPerIP int) {
|
||||
|
||||
// broadcast mined blocks
|
||||
h.wg.Add(1)
|
||||
h.minedBlockSub = h.eventMux.Subscribe(core.NewMinedBlockEvent{}, core.NewSealedBlockEvent{})
|
||||
h.minedBlockSub = h.eventMux.Subscribe(core.NewMinedBlockEvent{})
|
||||
go h.minedBroadcastLoop()
|
||||
|
||||
// start sync handlers
|
||||
@@ -946,9 +946,8 @@ func (h *handler) minedBroadcastLoop() {
|
||||
if obj == nil {
|
||||
continue
|
||||
}
|
||||
if ev, ok := obj.Data.(core.NewSealedBlockEvent); ok {
|
||||
h.BroadcastBlock(ev.Block, true) // Propagate block to peers
|
||||
} else if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok {
|
||||
if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok {
|
||||
h.BroadcastBlock(ev.Block, true) // First propagate block to peers
|
||||
h.BroadcastBlock(ev.Block, false) // Only then announce to the rest
|
||||
}
|
||||
case <-h.stopCh:
|
||||
|
||||
6
go.mod
6
go.mod
@@ -24,7 +24,7 @@ require (
|
||||
github.com/deckarep/golang-set/v2 v2.5.0
|
||||
github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127
|
||||
github.com/ethereum/c-kzg-4844 v0.4.0
|
||||
github.com/fatih/color v1.14.1
|
||||
github.com/fatih/color v1.16.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e
|
||||
github.com/fjl/memsize v0.0.2
|
||||
@@ -82,7 +82,7 @@ require (
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a
|
||||
golang.org/x/sync v0.6.0
|
||||
golang.org/x/sys v0.18.0
|
||||
golang.org/x/sys v0.20.0
|
||||
golang.org/x/text v0.14.0
|
||||
golang.org/x/time v0.5.0
|
||||
golang.org/x/tools v0.18.0
|
||||
@@ -159,7 +159,7 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 // indirect
|
||||
github.com/gtank/merlin v0.1.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.4 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
|
||||
|
||||
18
go.sum
18
go.sum
@@ -326,8 +326,9 @@ github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R
|
||||
github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
|
||||
@@ -580,14 +581,13 @@ github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
|
||||
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
@@ -1503,8 +1503,8 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
||||
@@ -665,7 +665,7 @@ func (w *worker) resultLoop() {
|
||||
// Commit block and state to database.
|
||||
task.state.SetExpectedStateRoot(block.Root())
|
||||
start := time.Now()
|
||||
status, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true, w.mux)
|
||||
status, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true)
|
||||
if status != core.CanonStatTy {
|
||||
if err != nil {
|
||||
log.Error("Failed writing block to chain", "err", err, "status", status)
|
||||
|
||||
@@ -17,13 +17,48 @@
|
||||
package trie
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
"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.
|
||||
// Deprecated: use StateTrie.
|
||||
type SecureTrie = StateTrie
|
||||
@@ -63,6 +98,11 @@ type StateTrie struct {
|
||||
// trie is initially empty. Otherwise, New will panic if db is nil
|
||||
// and returns MissingNodeError if the root node cannot be found.
|
||||
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 {
|
||||
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 a trie node is not found in the database, a MissingNodeError is returned.
|
||||
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))
|
||||
if err != nil || len(enc) == 0 {
|
||||
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 a trie node is not found in the database, a MissingNodeError is returned.
|
||||
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()))
|
||||
if res == nil || err != nil {
|
||||
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.
|
||||
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)
|
||||
v, _ := rlp.EncodeToBytes(value)
|
||||
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.
|
||||
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())
|
||||
data, err := rlp.EncodeToBytes(acc)
|
||||
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 a node is not found in the database, a MissingNodeError is returned.
|
||||
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)
|
||||
delete(t.getSecKeyCache(), string(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.
|
||||
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())
|
||||
delete(t.getSecKeyCache(), string(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
|
||||
// be created with new root and updated trie database for following usage
|
||||
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
|
||||
if len(t.getSecKeyCache()) > 0 {
|
||||
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
|
||||
// database and can be used even if the trie doesn't have one.
|
||||
func (t *StateTrie) Hash() common.Hash {
|
||||
defer func(start time.Time) {
|
||||
StateTreeCalcQPS.Mark(1)
|
||||
StateTreeCalcTime.UpdateSince(start)
|
||||
}(time.Now())
|
||||
return t.trie.Hash()
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
// 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 {
|
||||
defer func(start time.Time) {
|
||||
PbssUpdateDiffQPS.Mark(1)
|
||||
PbssUpdateDiffTime.UpdateSince(start)
|
||||
}(time.Now())
|
||||
// Hold the lock to prevent concurrent mutations.
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/fastcache"
|
||||
"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
|
||||
nHash common.Hash
|
||||
)
|
||||
// TODO:
|
||||
trieNodeQPS.Mark(1)
|
||||
startLoadTrieNode := time.Now()
|
||||
if owner == (common.Hash{}) {
|
||||
nBlob, nHash = rawdb.ReadAccountTrieNode(dl.db.diskdb, path)
|
||||
} else {
|
||||
nBlob, nHash = rawdb.ReadStorageTrieNode(dl.db.diskdb, owner, path)
|
||||
}
|
||||
trieNodeTime.Mark(time.Since(startLoadTrieNode).Nanoseconds())
|
||||
if nHash != hash {
|
||||
diskFalseMeter.Mark(1)
|
||||
log.Error("Unexpected trie node in disk", "owner", owner, "path", path, "expect", hash, "got", nHash)
|
||||
|
||||
@@ -53,4 +53,10 @@ var (
|
||||
diffHashCacheMissMeter = metrics.NewRegisteredMeter("pathdb/difflayer/hashcache/miss", nil)
|
||||
diffHashCacheSlowPathMeter = metrics.NewRegisteredMeter("pathdb/difflayer/hashcache/slowpath", 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)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user