From 5faeeaaf62a149b9d51015e98fb75b767d519cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Garamv=C3=B6lgyi?= Date: Wed, 27 Mar 2024 16:36:08 +0000 Subject: [PATCH] feat: add metrics to block validation (#677) * feat: add metrics to block validation * more metrics * bump version --- core/block_validator.go | 24 ++++++++++++++++++++++++ core/state_processor.go | 24 +++++++++++++++++++++++- params/version.go | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/core/block_validator.go b/core/block_validator.go index ad367f9185d0..6773649c6d13 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "sync" + "time" "github.com/scroll-tech/go-ethereum/consensus" "github.com/scroll-tech/go-ethereum/core/rawdb" @@ -27,11 +28,20 @@ import ( "github.com/scroll-tech/go-ethereum/core/types" "github.com/scroll-tech/go-ethereum/ethdb" "github.com/scroll-tech/go-ethereum/log" + "github.com/scroll-tech/go-ethereum/metrics" "github.com/scroll-tech/go-ethereum/params" "github.com/scroll-tech/go-ethereum/rollup/circuitcapacitychecker" "github.com/scroll-tech/go-ethereum/trie" ) +var ( + validateL1MessagesTimer = metrics.NewRegisteredTimer("validator/l1msg", nil) + validateRowConsumptionTimer = metrics.NewRegisteredTimer("validator/rowconsumption", nil) + validateTraceTimer = metrics.NewRegisteredTimer("validator/trace", nil) + validateLockTimer = metrics.NewRegisteredTimer("validator/lock", nil) + validateCccTimer = metrics.NewRegisteredTimer("validator/ccc", nil) +) + // BlockValidator is responsible for validating block headers, uncles and // processed state. // @@ -134,6 +144,10 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { // - L1 messages follow the QueueIndex order. // - The L1 messages included in the block match the node's view of the L1 ledger. func (v *BlockValidator) ValidateL1Messages(block *types.Block) error { + defer func(t0 time.Time) { + validateL1MessagesTimer.Update(time.Since(t0)) + }(time.Now()) + // skip DB read if the block contains no L1 messages if !block.ContainsL1Messages() { return nil @@ -288,6 +302,10 @@ func (v *BlockValidator) createTraceEnvAndGetBlockTrace(block *types.Block) (*ty } func (v *BlockValidator) validateCircuitRowConsumption(block *types.Block) (*types.RowConsumption, error) { + defer func(t0 time.Time) { + validateRowConsumptionTimer.Update(time.Since(t0)) + }(time.Now()) + log.Trace( "Validator apply ccc for block", "id", v.circuitCapacityChecker.ID, @@ -296,17 +314,23 @@ func (v *BlockValidator) validateCircuitRowConsumption(block *types.Block) (*typ "len(txs)", block.Transactions().Len(), ) + traceStartTime := time.Now() traces, err := v.createTraceEnvAndGetBlockTrace(block) if err != nil { return nil, err } + validateTraceTimer.Update(time.Since(traceStartTime)) + lockStartTime := time.Now() v.cMu.Lock() defer v.cMu.Unlock() + validateLockTimer.Update(time.Since(lockStartTime)) + cccStartTime := time.Now() v.circuitCapacityChecker.Reset() log.Trace("Validator reset ccc", "id", v.circuitCapacityChecker.ID) rc, err := v.circuitCapacityChecker.ApplyBlock(traces) + validateCccTimer.Update(time.Since(cccStartTime)) log.Trace( "Validator apply ccc for block result", diff --git a/core/state_processor.go b/core/state_processor.go index 87ebbaa18790..faf93be448cc 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -19,6 +19,7 @@ package core import ( "fmt" "math/big" + "time" "github.com/scroll-tech/go-ethereum/common" "github.com/scroll-tech/go-ethereum/consensus" @@ -32,7 +33,14 @@ import ( "github.com/scroll-tech/go-ethereum/rollup/fees" ) -var processorBlockTransactionGauge = metrics.NewRegisteredGauge("processor/block/transactions", nil) +var ( + processorBlockTransactionGauge = metrics.NewRegisteredGauge("processor/block/transactions", nil) + processBlockTimer = metrics.NewRegisteredTimer("processor/block/process", nil) + finalizeBlockTimer = metrics.NewRegisteredTimer("processor/block/finalize", nil) + applyTransactionTimer = metrics.NewRegisteredTimer("processor/tx/apply", nil) + applyMessageTimer = metrics.NewRegisteredTimer("processor/tx/msg/apply", nil) + updateStatedbTimer = metrics.NewRegisteredTimer("processor/tx/statedb/update", nil) +) // StateProcessor is a basic Processor, which takes care of transitioning // state from one point to another. @@ -61,6 +69,10 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen // returns the amount of gas that was used in the process. If any of the // transactions failed to execute due to insufficient gas it will return an error. func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) { + defer func(t0 time.Time) { + processBlockTimer.Update(time.Since(t0)) + }(time.Now()) + var ( receipts types.Receipts usedGas = new(uint64) @@ -92,12 +104,18 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg allLogs = append(allLogs, receipt.Logs...) } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) + finalizeBlockStartTime := time.Now() p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles()) + finalizeBlockTimer.Update(time.Since(finalizeBlockStartTime)) return receipts, allLogs, *usedGas, nil } func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) { + defer func(t0 time.Time) { + applyTransactionTimer.Update(time.Since(t0)) + }(time.Now()) + // Create a new context to be used in the EVM environment. txContext := NewEVMTxContext(msg) evm.Reset(txContext, statedb) @@ -108,18 +126,22 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon } // Apply the transaction to the current state (included in the env). + applyMessageStartTime := time.Now() result, err := ApplyMessage(evm, msg, gp, l1DataFee) + applyMessageTimer.Update(time.Since(applyMessageStartTime)) if err != nil { return nil, err } // Update the state with pending changes. var root []byte + updateStatedbStartTime := time.Now() if config.IsByzantium(blockNumber) { statedb.Finalise(true) } else { root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes() } + updateStatedbTimer.Update(time.Since(updateStatedbStartTime)) *usedGas += result.UsedGas // If the result contains a revert reason, return it. diff --git a/params/version.go b/params/version.go index 5ab93b336933..5a5eb099fda4 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 28 // Patch version component of the current release + VersionPatch = 29 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string )