From e9a9f11cdb0e06304b93326c48a237655a88f846 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Mon, 13 Jun 2022 13:47:39 +0530 Subject: [PATCH 01/48] base setup for miner opentel --- miner/worker.go | 63 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 14c5ccd1a3..38d64c0b8b 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -17,6 +17,7 @@ package miner import ( + "context" "errors" "fmt" "math/big" @@ -25,6 +26,8 @@ import ( "time" mapset "github.com/deckarep/golang-set" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" @@ -148,6 +151,7 @@ type task struct { state *state.StateDB block *types.Block createdAt time.Time + ctx context.Context } const ( @@ -161,6 +165,7 @@ type newWorkReq struct { interrupt *int32 noempty bool timestamp int64 + ctx context.Context } // getWorkReq represents a request for getting a new sealing work with provided parameters. @@ -168,6 +173,7 @@ type getWorkReq struct { params *generateParams err error result chan *types.Block + ctx context.Context } // intervalAdjust represents a resubmitting interval adjustment. @@ -246,6 +252,9 @@ type worker struct { skipSealHook func(*task) bool // Method to decide whether skipping the sealing. fullTaskHook func() // Method to call before pushing the full sealing task. resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval. + + tracer trace.Tracer + span trace.Span } func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(header *types.Header) bool, init bool) *worker { @@ -272,6 +281,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus startCh: make(chan struct{}, 1), resubmitIntervalCh: make(chan time.Duration), resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize), + tracer: otel.GetTracerProvider().Tracer("MinerWorker"), } // Subscribe NewTxsEvent for tx pool worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh) @@ -286,9 +296,14 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus recommit = minRecommitInterval } + workerCtx := context.Background() + newWorkerCtx, newWorkerSpan := worker.tracer.Start(workerCtx, "newWorker") + + worker.span = newWorkerSpan + worker.wg.Add(4) go worker.mainLoop() - go worker.newWorkLoop(recommit) + go worker.newWorkLoop(newWorkerCtx, recommit) go worker.resultLoop() go worker.taskLoop() @@ -386,6 +401,7 @@ func (w *worker) close() { atomic.StoreInt32(&w.running, 0) close(w.exitCh) w.wg.Wait() + w.span.End() } // recalcRecommit recalculates the resubmitting interval upon feedback. @@ -414,7 +430,7 @@ func recalcRecommit(minRecommit, prev time.Duration, target float64, inc bool) t } // newWorkLoop is a standalone goroutine to submit new sealing work upon received events. -func (w *worker) newWorkLoop(recommit time.Duration) { +func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { defer w.wg.Done() var ( interrupt *int32 @@ -433,7 +449,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) { } interrupt = new(int32) select { - case w.newWorkCh <- &newWorkReq{interrupt: interrupt, noempty: noempty, timestamp: timestamp}: + case w.newWorkCh <- &newWorkReq{interrupt: interrupt, noempty: noempty, timestamp: timestamp, ctx: ctx}: case <-w.exitCh: return } @@ -531,10 +547,10 @@ func (w *worker) mainLoop() { for { select { case req := <-w.newWorkCh: - w.commitWork(req.interrupt, req.noempty, req.timestamp) + w.commitWork(req.ctx, req.interrupt, req.noempty, req.timestamp) case req := <-w.getWorkCh: - block, err := w.generateWork(req.params) + block, err := w.generateWork(req.ctx, req.params) if err != nil { req.err = err req.result <- nil @@ -562,7 +578,7 @@ func (w *worker) mainLoop() { if w.isRunning() && w.current != nil && len(w.current.uncles) < 2 { start := time.Now() if err := w.commitUncle(w.current, ev.Block.Header()); err == nil { - w.commit(w.current.copy(), nil, true, start) + w.commit(context.Background(), w.current.copy(), nil, true, start) } } @@ -609,7 +625,7 @@ func (w *worker) mainLoop() { // submit sealing work here since all empty submission will be rejected // by clique. Of course the advance sealing(empty submission) is disabled. if w.chainConfig.Clique != nil && w.chainConfig.Clique.Period == 0 { - w.commitWork(nil, true, time.Now().Unix()) + w.commitWork(context.Background(), nil, true, time.Now().Unix()) } } atomic.AddInt32(&w.newTxs, int32(len(ev.Txs))) @@ -646,6 +662,7 @@ func (w *worker) taskLoop() { for { select { case task := <-w.taskCh: + _, taskLoopSpan := w.tracer.Start(task.ctx, "taskLoop") if w.newTaskHook != nil { w.newTaskHook(task) } @@ -671,6 +688,7 @@ func (w *worker) taskLoop() { delete(w.pendingTasks, sealHash) w.pendingMu.Unlock() } + taskLoopSpan.End() case <-w.exitCh: interrupt() return @@ -1064,7 +1082,10 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { // fillTransactions retrieves the pending transactions from the txpool and fills them // into the given sealing block. The transaction selection and ordering strategy can // be customized with the plugin in the future. -func (w *worker) fillTransactions(interrupt *int32, env *environment) { +func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *environment) { + + _, fillTransactionsSpan := w.tracer.Start(ctx, "fillTransactions") + // Split the pending transactions into locals and remotes // Fill the block with all available pending transactions. pending := w.eth.TxPool().Pending(true) @@ -1087,23 +1108,30 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment) { return } } + + fillTransactionsSpan.End() } // generateWork generates a sealing block based on the given parameters. -func (w *worker) generateWork(params *generateParams) (*types.Block, error) { +func (w *worker) generateWork(ctx context.Context, params *generateParams) (*types.Block, error) { work, err := w.prepareWork(params) if err != nil { return nil, err } defer work.discard() - w.fillTransactions(nil, work) + w.fillTransactions(ctx, nil, work) return w.engine.FinalizeAndAssemble(w.chain, work.header, work.state, work.txs, work.unclelist(), work.receipts) } // commitWork generates several new sealing tasks based on the parent block // and submit them to the sealer. -func (w *worker) commitWork(interrupt *int32, noempty bool, timestamp int64) { +func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, timestamp int64) { + + _, commitWorkSpan := w.tracer.Start(ctx, "commitWork") + + // todo - analyze + start := time.Now() // Set the coinbase if the worker is running or it's required @@ -1125,11 +1153,11 @@ func (w *worker) commitWork(interrupt *int32, noempty bool, timestamp int64) { // Create an empty block based on temporary copied state for // sealing in advance without waiting block execution finished. if !noempty && atomic.LoadUint32(&w.noempty) == 0 { - w.commit(work.copy(), nil, false, start) + w.commit(ctx, work.copy(), nil, false, start) } // Fill pending transactions from the txpool - w.fillTransactions(interrupt, work) - w.commit(work.copy(), w.fullTaskHook, true, start) + w.fillTransactions(ctx, interrupt, work) + w.commit(ctx, work.copy(), w.fullTaskHook, true, start) // Swap out the old work with the new one, terminating any leftover // prefetcher processes in the mean time and starting a new one. @@ -1137,13 +1165,16 @@ func (w *worker) commitWork(interrupt *int32, noempty bool, timestamp int64) { w.current.discard() } w.current = work + + commitWorkSpan.End() + } // commit runs any post-transaction state modifications, assembles the final block // and commits new work if consensus engine is running. // Note the assumption is held that the mutation is allowed to the passed env, do // the deep copy first. -func (w *worker) commit(env *environment, interval func(), update bool, start time.Time) error { +func (w *worker) commit(ctx context.Context, env *environment, interval func(), update bool, start time.Time) error { if w.isRunning() { if interval != nil { interval() @@ -1158,7 +1189,7 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti // If we're post merge, just ignore if !w.isTTDReached(block.Header()) { select { - case w.taskCh <- &task{receipts: env.receipts, state: env.state, block: block, createdAt: time.Now()}: + case w.taskCh <- &task{receipts: env.receipts, state: env.state, block: block, createdAt: time.Now(), ctx: ctx}: w.unconfirmed.Shift(block.NumberU64() - 1) log.Info("Commit new sealing work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()), "uncles", len(env.uncles), "txs", env.tcount, From f612c39f14b170f892cd0e318b533f5e9b6c3ec8 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Mon, 13 Jun 2022 14:13:01 +0530 Subject: [PATCH 02/48] version change --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 4b608b1a5f..de4424f6ce 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 0 // Major version component of the current release - VersionMinor = 2 // Minor version component of the current release - VersionPatch = 16 // Patch version component of the current release - VersionMeta = "stable" // Version metadata to append to the version string + VersionMajor = 0 // Major version component of the current release + VersionMinor = 3 // Minor version component of the current release + VersionPatch = 0 // Patch version component of the current release + VersionMeta = "alpha" // Version metadata to append to the version string ) // Version holds the textual version string. From 6ca8301a4c11cfa9cea512ebc0dc6c64d0341875 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Mon, 13 Jun 2022 16:22:27 +0530 Subject: [PATCH 03/48] modify ctx passing --- miner/worker.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 38d64c0b8b..5ca3d1e2a4 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1085,6 +1085,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *environment) { _, fillTransactionsSpan := w.tracer.Start(ctx, "fillTransactions") + defer fillTransactionsSpan.End() // Split the pending transactions into locals and remotes // Fill the block with all available pending transactions. @@ -1109,7 +1110,6 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en } } - fillTransactionsSpan.End() } // generateWork generates a sealing block based on the given parameters. @@ -1128,9 +1128,8 @@ func (w *worker) generateWork(ctx context.Context, params *generateParams) (*typ // and submit them to the sealer. func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, timestamp int64) { - _, commitWorkSpan := w.tracer.Start(ctx, "commitWork") - - // todo - analyze + commitWorkCtx, commitWorkSpan := w.tracer.Start(ctx, "commitWork") + defer commitWorkSpan.End() start := time.Now() @@ -1153,11 +1152,11 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, // Create an empty block based on temporary copied state for // sealing in advance without waiting block execution finished. if !noempty && atomic.LoadUint32(&w.noempty) == 0 { - w.commit(ctx, work.copy(), nil, false, start) + w.commit(commitWorkCtx, work.copy(), nil, false, start) } // Fill pending transactions from the txpool - w.fillTransactions(ctx, interrupt, work) - w.commit(ctx, work.copy(), w.fullTaskHook, true, start) + w.fillTransactions(commitWorkCtx, interrupt, work) + w.commit(commitWorkCtx, work.copy(), w.fullTaskHook, true, start) // Swap out the old work with the new one, terminating any leftover // prefetcher processes in the mean time and starting a new one. @@ -1166,8 +1165,6 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, } w.current = work - commitWorkSpan.End() - } // commit runs any post-transaction state modifications, assembles the final block @@ -1175,6 +1172,10 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, // Note the assumption is held that the mutation is allowed to the passed env, do // the deep copy first. func (w *worker) commit(ctx context.Context, env *environment, interval func(), update bool, start time.Time) error { + + commitCtx, commitSpan := w.tracer.Start(ctx, "commit") + defer commitSpan.End() + if w.isRunning() { if interval != nil { interval() @@ -1189,7 +1190,7 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), // If we're post merge, just ignore if !w.isTTDReached(block.Header()) { select { - case w.taskCh <- &task{receipts: env.receipts, state: env.state, block: block, createdAt: time.Now(), ctx: ctx}: + case w.taskCh <- &task{receipts: env.receipts, state: env.state, block: block, createdAt: time.Now(), ctx: commitCtx}: w.unconfirmed.Shift(block.NumberU64() - 1) log.Info("Commit new sealing work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()), "uncles", len(env.uncles), "txs", env.tcount, From 767ee891395f7090a0c3ab0ba3c24fee17751a48 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Mon, 13 Jun 2022 17:02:43 +0530 Subject: [PATCH 04/48] add attributes --- core/types/transaction.go | 4 ++++ miner/worker.go | 45 +++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index 29820a0d78..1d9b3ac602 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -550,6 +550,10 @@ func (t *TransactionsByPriceAndNonce) Shift() { heap.Pop(&t.heads) } +func (t *TransactionsByPriceAndNonce) GetTxs() int { + return len(t.txs) +} + // Pop removes the best transaction, *not* replacing it with the next one from // the same account. This should be used when a transaction cannot be executed // and hence all subsequent ones should be discarded from the same account. diff --git a/miner/worker.go b/miner/worker.go index 5ca3d1e2a4..36d39c1098 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -27,6 +27,7 @@ import ( mapset "github.com/deckarep/golang-set" "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "github.com/ethereum/go-ethereum/common" @@ -296,15 +297,13 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus recommit = minRecommitInterval } - workerCtx := context.Background() - newWorkerCtx, newWorkerSpan := worker.tracer.Start(workerCtx, "newWorker") - - worker.span = newWorkerSpan + newWorkerCtx, newWorkSpan := worker.tracer.Start(context.Background(), "newWorker") + worker.span = newWorkSpan worker.wg.Add(4) go worker.mainLoop() go worker.newWorkLoop(newWorkerCtx, recommit) - go worker.resultLoop() + go worker.resultLoop(newWorkerCtx) go worker.taskLoop() // Submit first work to initialize pending state. @@ -663,6 +662,7 @@ func (w *worker) taskLoop() { select { case task := <-w.taskCh: _, taskLoopSpan := w.tracer.Start(task.ctx, "taskLoop") + if w.newTaskHook != nil { w.newTaskHook(task) } @@ -688,7 +688,9 @@ func (w *worker) taskLoop() { delete(w.pendingTasks, sealHash) w.pendingMu.Unlock() } + taskLoopSpan.End() + case <-w.exitCh: interrupt() return @@ -698,11 +700,12 @@ func (w *worker) taskLoop() { // resultLoop is a standalone goroutine to handle sealing result submitting // and flush relative data to the database. -func (w *worker) resultLoop() { +func (w *worker) resultLoop(ctx context.Context) { defer w.wg.Done() for { select { case block := <-w.resultCh: + _, resultLoopSpan := w.tracer.Start(ctx, "resultLoop") // Short circuit when receiving empty result. if block == nil { continue @@ -771,7 +774,12 @@ func (w *worker) resultLoop() { // Insert the block into the set of pending ones to resultLoop for confirmations w.unconfirmed.Insert(block.NumberU64(), block.Hash()) - + resultLoopSpan.SetAttributes( + attribute.String("hash", hash.String()), + attribute.Int("number", int(block.Number().Uint64())), + attribute.Int("txns", block.Transactions().Len()), + ) + resultLoopSpan.End() case <-w.exitCh: return } @@ -1098,16 +1106,32 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en } } if len(localTxs) > 0 { + fillTransactionsSpan.SetAttributes( + attribute.Int("len of localTxs", len(localTxs)), + ) txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) + fillTransactionsSpan.SetAttributes( + attribute.Int("len of localTxs txs", txs.GetTxs()), + ) if w.commitTransactions(env, txs, interrupt) { return } + fillTransactionsSpan.SetAttributes( + attribute.Int("len of final localTxs txns", env.tcount), + ) } if len(remoteTxs) > 0 { + attribute.Int("len of remoteTxs", len(remoteTxs)) txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) + fillTransactionsSpan.SetAttributes( + attribute.Int("len of remoteTxs txs", txs.GetTxs()), + ) if w.commitTransactions(env, txs, interrupt) { return } + fillTransactionsSpan.SetAttributes( + attribute.Int("len of final remoteTxs txns", env.tcount), + ) } } @@ -1201,10 +1225,17 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), log.Info("Worker has exited") } } + + commitSpan.SetAttributes( + attribute.Int("number", int(block.Number().Uint64())), + attribute.String("sealhash", w.engine.SealHash(block.Header()).String()), + attribute.Int("len of env.txs", len(env.txs)), + ) } if update { w.updateSnapshot(env) } + return nil } From bab7da1b94fd515fe518d77b566cf89e501520a7 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Mon, 13 Jun 2022 17:18:45 +0530 Subject: [PATCH 05/48] update fill txs span attributes --- miner/worker.go | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 36d39c1098..17a9c79515 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1106,31 +1106,29 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en } } if len(localTxs) > 0 { - fillTransactionsSpan.SetAttributes( - attribute.Int("len of localTxs", len(localTxs)), - ) + lenLocals := len(localTxs) txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) - fillTransactionsSpan.SetAttributes( - attribute.Int("len of localTxs txs", txs.GetTxs()), - ) + lenNewLocals := txs.GetTxs() if w.commitTransactions(env, txs, interrupt) { return } fillTransactionsSpan.SetAttributes( - attribute.Int("len of final localTxs txns", env.tcount), + attribute.Int("len of localTxs", lenLocals), + attribute.Int("len of sorted localTxs", lenNewLocals), + attribute.Int("len of final localTxs ", env.tcount), ) } if len(remoteTxs) > 0 { - attribute.Int("len of remoteTxs", len(remoteTxs)) + lenRemotes := len(remoteTxs) txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) - fillTransactionsSpan.SetAttributes( - attribute.Int("len of remoteTxs txs", txs.GetTxs()), - ) + lenNewRemotes := txs.GetTxs() if w.commitTransactions(env, txs, interrupt) { return } fillTransactionsSpan.SetAttributes( - attribute.Int("len of final remoteTxs txns", env.tcount), + attribute.Int("len of remoteTxs", lenRemotes), + attribute.Int("len of sorted remoteTxs", lenNewRemotes), + attribute.Int("len of final remoteTxs", env.tcount), ) } @@ -1228,6 +1226,7 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), commitSpan.SetAttributes( attribute.Int("number", int(block.Number().Uint64())), + attribute.String("hash", block.Hash().String()), attribute.String("sealhash", w.engine.SealHash(block.Header()).String()), attribute.Int("len of env.txs", len(env.txs)), ) From 3a078e6b040ac82d602d48ca6f53ead4e224e4b4 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Mon, 13 Jun 2022 17:23:10 +0530 Subject: [PATCH 06/48] fix: use common attributes for remote and local txs --- miner/worker.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 17a9c79515..8ddc9e4d2f 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1105,33 +1105,33 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en localTxs[account] = txs } } + lenLocals, lenNewLocals, localEnvTCount, lenRemotes, lenNewRemotes, remoteEnvTCount := 0, 0, 0, 0, 0, 0 if len(localTxs) > 0 { - lenLocals := len(localTxs) + lenLocals = len(localTxs) txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) - lenNewLocals := txs.GetTxs() + lenNewLocals = txs.GetTxs() if w.commitTransactions(env, txs, interrupt) { return } - fillTransactionsSpan.SetAttributes( - attribute.Int("len of localTxs", lenLocals), - attribute.Int("len of sorted localTxs", lenNewLocals), - attribute.Int("len of final localTxs ", env.tcount), - ) + localEnvTCount = env.tcount } if len(remoteTxs) > 0 { - lenRemotes := len(remoteTxs) + lenRemotes = len(remoteTxs) txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) - lenNewRemotes := txs.GetTxs() + lenNewRemotes = txs.GetTxs() if w.commitTransactions(env, txs, interrupt) { return } - fillTransactionsSpan.SetAttributes( - attribute.Int("len of remoteTxs", lenRemotes), - attribute.Int("len of sorted remoteTxs", lenNewRemotes), - attribute.Int("len of final remoteTxs", env.tcount), - ) + remoteEnvTCount = env.tcount } - + fillTransactionsSpan.SetAttributes( + attribute.Int("len of remoteTxs", lenRemotes), + attribute.Int("len of sorted remoteTxs", lenNewRemotes), + attribute.Int("len of final remoteTxs", localEnvTCount), + attribute.Int("len of localTxs", lenLocals), + attribute.Int("len of sorted localTxs", lenNewLocals), + attribute.Int("len of final localTxs ", remoteEnvTCount), + ) } // generateWork generates a sealing block based on the given parameters. From c2602caff3adf54aa0204bc16eb5d0c29b2aa9ee Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Mon, 13 Jun 2022 17:53:43 +0530 Subject: [PATCH 07/48] pass context in seal --- cmd/evm/internal/t8ntool/block.go | 3 ++- consensus/beacon/consensus.go | 5 +++-- consensus/bor/bor.go | 16 +++++++++++++++- consensus/clique/clique.go | 3 ++- consensus/consensus.go | 3 ++- consensus/ethash/ethash_test.go | 7 ++++--- consensus/ethash/sealer.go | 6 +++--- consensus/ethash/sealer_test.go | 11 ++++++----- miner/worker.go | 6 +++--- 9 files changed, 40 insertions(+), 20 deletions(-) diff --git a/cmd/evm/internal/t8ntool/block.go b/cmd/evm/internal/t8ntool/block.go index d4edd33bde..4d75a30d4b 100644 --- a/cmd/evm/internal/t8ntool/block.go +++ b/cmd/evm/internal/t8ntool/block.go @@ -17,6 +17,7 @@ package t8ntool import ( + "context" "crypto/ecdsa" "encoding/json" "errors" @@ -188,7 +189,7 @@ func (i *bbInput) sealEthash(block *types.Block) (*types.Block, error) { // If the testmode is used, the sealer will return quickly, and complain // "Sealing result is not read by miner" if it cannot write the result. results := make(chan *types.Block, 1) - if err := engine.Seal(nil, block, results, nil); err != nil { + if err := engine.Seal(context.Background(), nil, block, results, nil); err != nil { panic(fmt.Sprintf("failed to seal block: %v", err)) } found := <-results diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 1fd7deb872..b49e302bd6 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -17,6 +17,7 @@ package beacon import ( + "context" "errors" "fmt" "math/big" @@ -294,9 +295,9 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea // // Note, the method returns immediately and will send the result async. More // than one result may also be returned depending on the consensus algorithm. -func (beacon *Beacon) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { +func (beacon *Beacon) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { if !beacon.IsPoSHeader(block.Header()) { - return beacon.ethone.Seal(chain, block, results, stop) + return beacon.ethone.Seal(ctx, chain, block, results, stop) } // The seal verification is done by the external consensus engine, // return directly without pushing any block back. In another word diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 2f087af787..83889f6ba2 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -2,6 +2,7 @@ package bor import ( "bytes" + "context" "encoding/hex" "encoding/json" "errors" @@ -14,6 +15,8 @@ import ( "time" lru "github.com/hashicorp/golang-lru" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" "golang.org/x/crypto/sha3" "github.com/ethereum/go-ethereum/accounts" @@ -837,7 +840,11 @@ func (c *Bor) Authorize(signer common.Address, signFn SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. -func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { +func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { + + tracer := otel.GetTracerProvider().Tracer("MinerWorker") + _, sealSpan := tracer.Start(ctx, "Seal") + header := block.Header() // Sealing the genesis block is not supported number := header.Number.Uint64() @@ -907,6 +914,13 @@ func (c *Bor) Seal(chain consensus.ChainHeaderReader, block *types.Block, result "delay", delay, "headerDifficulty", header.Difficulty, ) + sealSpan.SetAttributes( + attribute.Int("number", int(number)), + attribute.String("hash", header.Hash().String()), + attribute.String("delay", delay.String()), + attribute.Bool("out-of-turn", wiggle > 0), + ) + sealSpan.End() } select { case results <- block.WithSeal(header): diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 685186817d..301f9f78d1 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -19,6 +19,7 @@ package clique import ( "bytes" + "context" "errors" "fmt" "io" @@ -589,7 +590,7 @@ func (c *Clique) Authorize(signer common.Address, signFn SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. -func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { +func (c *Clique) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { header := block.Header() // Sealing the genesis block is not supported diff --git a/consensus/consensus.go b/consensus/consensus.go index af8ce98ff3..9c16f75674 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -18,6 +18,7 @@ package consensus import ( + "context" "math/big" "github.com/ethereum/go-ethereum/common" @@ -105,7 +106,7 @@ type Engine interface { // // Note, the method returns immediately and will send the result async. More // than one result may also be returned depending on the consensus algorithm. - Seal(chain ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error + Seal(ctx context.Context, chain ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error // SealHash returns the hash of a block prior to it being sealed. SealHash(header *types.Header) common.Hash diff --git a/consensus/ethash/ethash_test.go b/consensus/ethash/ethash_test.go index 382eefeecf..d63eef286b 100644 --- a/consensus/ethash/ethash_test.go +++ b/consensus/ethash/ethash_test.go @@ -17,6 +17,7 @@ package ethash import ( + "context" "io/ioutil" "math/big" "math/rand" @@ -38,7 +39,7 @@ func TestTestMode(t *testing.T) { defer ethash.Close() results := make(chan *types.Block) - err := ethash.Seal(nil, types.NewBlockWithHeader(header), results, nil) + err := ethash.Seal(context.Background(), nil, types.NewBlockWithHeader(header), results, nil) if err != nil { t.Fatalf("failed to seal block: %v", err) } @@ -111,7 +112,7 @@ func TestRemoteSealer(t *testing.T) { // Push new work. results := make(chan *types.Block) - ethash.Seal(nil, block, results, nil) + ethash.Seal(context.Background(), nil, block, results, nil) var ( work [4]string @@ -128,7 +129,7 @@ func TestRemoteSealer(t *testing.T) { header = &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(1000)} block = types.NewBlockWithHeader(header) sealhash = ethash.SealHash(header) - ethash.Seal(nil, block, results, nil) + ethash.Seal(context.Background(), nil, block, results, nil) if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() { t.Error("expect to return the latest pushed work") diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go index 6fa60ef6a8..b83c282cba 100644 --- a/consensus/ethash/sealer.go +++ b/consensus/ethash/sealer.go @@ -48,7 +48,7 @@ var ( // Seal implements consensus.Engine, attempting to find a nonce that satisfies // the block's difficulty requirements. -func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { +func (ethash *Ethash) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { // If we're running a fake PoW, simply return a 0 nonce immediately if ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake { header := block.Header() @@ -62,7 +62,7 @@ func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block } // If we're running a shared PoW, delegate sealing to it if ethash.shared != nil { - return ethash.shared.Seal(chain, block, results, stop) + return ethash.shared.Seal(ctx, chain, block, results, stop) } // Create a runner and the multiple search threads it directs abort := make(chan struct{}) @@ -117,7 +117,7 @@ func (ethash *Ethash) Seal(chain consensus.ChainHeaderReader, block *types.Block case <-ethash.update: // Thread count was changed on user request, restart close(abort) - if err := ethash.Seal(chain, block, results, stop); err != nil { + if err := ethash.Seal(ctx, chain, block, results, stop); err != nil { ethash.config.Log.Error("Failed to restart sealing after update", "err", err) } } diff --git a/consensus/ethash/sealer_test.go b/consensus/ethash/sealer_test.go index a9e96af866..220aae1fd0 100644 --- a/consensus/ethash/sealer_test.go +++ b/consensus/ethash/sealer_test.go @@ -17,6 +17,7 @@ package ethash import ( + "context" "encoding/json" "io/ioutil" "math/big" @@ -57,7 +58,7 @@ func TestRemoteNotify(t *testing.T) { header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)} block := types.NewBlockWithHeader(header) - ethash.Seal(nil, block, nil, nil) + ethash.Seal(context.Background(), nil, block, nil, nil) select { case work := <-sink: if want := ethash.SealHash(header).Hex(); work[0] != want { @@ -105,7 +106,7 @@ func TestRemoteNotifyFull(t *testing.T) { header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)} block := types.NewBlockWithHeader(header) - ethash.Seal(nil, block, nil, nil) + ethash.Seal(context.Background(), nil, block, nil, nil) select { case work := <-sink: if want := "0x" + strconv.FormatUint(header.Number.Uint64(), 16); work["number"] != want { @@ -151,7 +152,7 @@ func TestRemoteMultiNotify(t *testing.T) { for i := 0; i < cap(sink); i++ { header := &types.Header{Number: big.NewInt(int64(i)), Difficulty: big.NewInt(100)} block := types.NewBlockWithHeader(header) - ethash.Seal(nil, block, results, nil) + ethash.Seal(context.Background(), nil, block, results, nil) } for i := 0; i < cap(sink); i++ { @@ -200,7 +201,7 @@ func TestRemoteMultiNotifyFull(t *testing.T) { for i := 0; i < cap(sink); i++ { header := &types.Header{Number: big.NewInt(int64(i)), Difficulty: big.NewInt(100)} block := types.NewBlockWithHeader(header) - ethash.Seal(nil, block, results, nil) + ethash.Seal(context.Background(), nil, block, results, nil) } for i := 0; i < cap(sink); i++ { @@ -266,7 +267,7 @@ func TestStaleSubmission(t *testing.T) { for id, c := range testcases { for _, h := range c.headers { - ethash.Seal(nil, types.NewBlockWithHeader(h), results, nil) + ethash.Seal(context.Background(), nil, types.NewBlockWithHeader(h), results, nil) } if res := api.SubmitWork(fakeNonce, ethash.SealHash(c.headers[c.submitIndex]), fakeDigest); res != c.submitRes { t.Errorf("case %d submit result mismatch, want %t, get %t", id+1, c.submitRes, res) diff --git a/miner/worker.go b/miner/worker.go index 8ddc9e4d2f..1a96ee1c0f 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -661,7 +661,7 @@ func (w *worker) taskLoop() { for { select { case task := <-w.taskCh: - _, taskLoopSpan := w.tracer.Start(task.ctx, "taskLoop") + // taskLoopCtx, taskLoopSpan := w.tracer.Start(task.ctx, "taskLoop") if w.newTaskHook != nil { w.newTaskHook(task) @@ -682,14 +682,14 @@ func (w *worker) taskLoop() { w.pendingTasks[sealHash] = task w.pendingMu.Unlock() - if err := w.engine.Seal(w.chain, task.block, w.resultCh, stopCh); err != nil { + if err := w.engine.Seal(task.ctx, w.chain, task.block, w.resultCh, stopCh); err != nil { log.Warn("Block sealing failed", "err", err) w.pendingMu.Lock() delete(w.pendingTasks, sealHash) w.pendingMu.Unlock() } - taskLoopSpan.End() + // taskLoopSpan.End() case <-w.exitCh: interrupt() From 1d9e1deadfe09955948f04fc67edc880ab0c9bd7 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Mon, 13 Jun 2022 18:02:00 +0530 Subject: [PATCH 08/48] fix --- consensus/bor/bor.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 83889f6ba2..d314f06701 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -890,6 +890,8 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block // Wait until sealing is terminated or delay timeout. log.Info("Waiting for slot to sign and propagate", "number", number, "hash", header.Hash, "delay-in-sec", uint(delay), "delay", common.PrettyDuration(delay)) + sealSpan.SetAttributes(attribute.String("test", "hello")) + sealSpan.End() go func() { select { @@ -914,13 +916,13 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block "delay", delay, "headerDifficulty", header.Difficulty, ) - sealSpan.SetAttributes( - attribute.Int("number", int(number)), - attribute.String("hash", header.Hash().String()), - attribute.String("delay", delay.String()), - attribute.Bool("out-of-turn", wiggle > 0), - ) - sealSpan.End() + // sealSpan.SetAttributes( + // attribute.Int("number", int(number)), + // attribute.String("hash", header.Hash().String()), + // attribute.String("delay", delay.String()), + // attribute.Bool("out-of-turn", wiggle > 0), + // ) + // sealSpan.End() } select { case results <- block.WithSeal(header): From f2522983d0040f675dc03f0abfd0a475aaf675c7 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Mon, 13 Jun 2022 18:16:03 +0530 Subject: [PATCH 09/48] fix --- consensus/bor/bor.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index d314f06701..a3c13021cc 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -17,6 +17,7 @@ import ( lru "github.com/hashicorp/golang-lru" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" "golang.org/x/crypto/sha3" "github.com/ethereum/go-ethereum/accounts" @@ -890,10 +891,8 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block // Wait until sealing is terminated or delay timeout. log.Info("Waiting for slot to sign and propagate", "number", number, "hash", header.Hash, "delay-in-sec", uint(delay), "delay", common.PrettyDuration(delay)) - sealSpan.SetAttributes(attribute.String("test", "hello")) - sealSpan.End() - go func() { + go func(sealSpan trace.Span) { select { case <-stop: log.Debug("Discarding sealing operation for block", "number", number) @@ -916,20 +915,20 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block "delay", delay, "headerDifficulty", header.Difficulty, ) - // sealSpan.SetAttributes( - // attribute.Int("number", int(number)), - // attribute.String("hash", header.Hash().String()), - // attribute.String("delay", delay.String()), - // attribute.Bool("out-of-turn", wiggle > 0), - // ) - // sealSpan.End() + sealSpan.SetAttributes( + attribute.Int("number", int(number)), + attribute.String("hash", header.Hash().String()), + attribute.String("delay", delay.String()), + attribute.Bool("out-of-turn", wiggle > 0), + ) + sealSpan.End() } select { case results <- block.WithSeal(header): default: log.Warn("Sealing result was not read by miner", "number", number, "sealhash", SealHash(header, c.config)) } - }() + }(sealSpan) return nil } From 11bbda024060a996aebc045c57fd2369d721ca54 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 14 Jun 2022 14:12:21 +0530 Subject: [PATCH 10/48] add traces to finalize and assemble --- consensus/beacon/consensus.go | 4 +- consensus/bor/bor.go | 74 ++++++++++++++++++++++++++++++++--- consensus/clique/clique.go | 2 +- consensus/consensus.go | 2 +- consensus/ethash/consensus.go | 3 +- core/chain_makers.go | 3 +- miner/worker.go | 4 +- tests/bor/helper.go | 3 +- 8 files changed, 80 insertions(+), 15 deletions(-) diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index b49e302bd6..338b08ca70 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -279,11 +279,11 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types. // FinalizeAndAssemble implements consensus.Engine, setting the final state and // assembling the block. -func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { +func (beacon *Beacon) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { // FinalizeAndAssemble is different with Prepare, it can be used in both block // generation and verification. So determine the consensus rules by header type. if !beacon.IsPoSHeader(header) { - return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts) + return beacon.ethone.FinalizeAndAssemble(ctx, chain, header, state, txs, uncles, receipts) } // Finalize and assemble the block beacon.Finalize(chain, header, state, txs, uncles) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index a3c13021cc..fe4a73d545 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -711,6 +711,11 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e // Finalize implements consensus.Engine, ensuring no uncles are set, nor block // rewards given. func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { + + tracer := otel.GetTracerProvider().Tracer("MinerWorker") + finalizeCtx, finalizeSpan := tracer.Start(context.Background(), "Finalize") + defer finalizeSpan.End() + stateSyncData := []*types.StateSyncData{} var err error @@ -720,14 +725,14 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, if headerNumber%c.config.Sprint == 0 { cx := statefull.ChainContext{Chain: chain, Bor: c} // check and commit span - if err := c.checkAndCommitSpan(state, header, cx); err != nil { + if err := c.checkAndCommitSpan(finalizeCtx, tracer, state, header, cx); err != nil { log.Error("Error while committing span", "error", err) return } if c.HeimdallClient != nil { // commit statees - stateSyncData, err = c.CommitStates(state, header, cx) + stateSyncData, err = c.CommitStates(finalizeCtx, tracer, state, header, cx) if err != nil { log.Error("Error while committing states", "error", err) return @@ -784,7 +789,18 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.State // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, // nor block rewards given, and returns the final block. -func (c *Bor) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { +func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { + + tracer := otel.GetTracerProvider().Tracer("MinerWorker") + finalizeCtx, finalizeSpan := tracer.Start(ctx, "FinalizeAndAssemble") + defer finalizeSpan.End() + + finalizeSpan.SetAttributes( + attribute.Int("number", int(header.Number.Int64())), + attribute.String("hash", header.Hash().String()), + attribute.Int("number of txs", len(txs)), + ) + stateSyncData := []*types.StateSyncData{} headerNumber := header.Number.Uint64() @@ -793,7 +809,7 @@ func (c *Bor) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *typ cx := statefull.ChainContext{Chain: chain, Bor: c} // check and commit span - err := c.checkAndCommitSpan(state, header, cx) + err := c.checkAndCommitSpan(finalizeCtx, tracer, state, header, cx) if err != nil { log.Error("Error while committing span", "error", err) return nil, err @@ -801,7 +817,7 @@ func (c *Bor) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *typ if c.HeimdallClient != nil { // commit states - stateSyncData, err = c.CommitStates(state, header, cx) + stateSyncData, err = c.CommitStates(finalizeCtx, tracer, state, header, cx) if err != nil { log.Error("Error while committing states", "error", err) return nil, err @@ -982,10 +998,16 @@ func (c *Bor) Close() error { } func (c *Bor) checkAndCommitSpan( + ctx context.Context, + tracer trace.Tracer, state *state.StateDB, header *types.Header, chain core.ChainContext, ) error { + + checkAndCommitSpanCtx, checkAndCommitSpan := tracer.Start(ctx, "checkAndCommitSpan") + defer checkAndCommitSpan.End() + headerNumber := header.Number.Uint64() span, err := c.spanner.GetCurrentSpan(header.ParentHash) @@ -993,8 +1015,14 @@ func (c *Bor) checkAndCommitSpan( return err } + checkAndCommitSpan.SetAttributes( + attribute.Int("number", int(headerNumber)), + attribute.String("hash", header.Hash().String()), + attribute.Int("current span id", int(span.ID)), + ) + if c.needToCommitSpan(span, headerNumber) { - return c.FetchAndCommitSpan(span.ID+1, state, header, chain) + return c.FetchAndCommitSpan(checkAndCommitSpanCtx, tracer, span.ID+1, state, header, chain) } return nil @@ -1020,11 +1048,17 @@ func (c *Bor) needToCommitSpan(span *span.Span, headerNumber uint64) bool { } func (c *Bor) FetchAndCommitSpan( + ctx context.Context, + tracer trace.Tracer, newSpanID uint64, state *state.StateDB, header *types.Header, chain core.ChainContext, ) error { + + _, fetchAndCommitSpan := tracer.Start(ctx, "FetchAndCommitSpan") + defer fetchAndCommitSpan.End() + var heimdallSpan span.HeimdallSpan if c.HeimdallClient == nil { @@ -1053,15 +1087,29 @@ func (c *Bor) FetchAndCommitSpan( ) } + fetchAndCommitSpan.SetAttributes( + attribute.Int("number", int(header.Number.Int64())), + attribute.String("hash", header.Hash().String()), + attribute.Int("fetched span id", int(heimdallSpan.ID)), + ) + return c.spanner.CommitSpan(heimdallSpan, state, header, chain) } // CommitStates commit states func (c *Bor) CommitStates( + ctx context.Context, + tracer trace.Tracer, state *state.StateDB, header *types.Header, chain statefull.ChainContext, ) ([]*types.StateSyncData, error) { + + _, commitStatesSpan := tracer.Start(ctx, "CommitStates") + defer commitStatesSpan.End() + + start1 := time.Now() + stateSyncs := make([]*types.StateSyncData, 0) number := header.Number.Uint64() @@ -1089,6 +1137,9 @@ func (c *Bor) CommitStates( } } + diff1 := time.Since(start1) + start2 := time.Now() + totalGas := 0 /// limit on gas for state sync per block chainID := c.chainConfig.ChainID.String() @@ -1122,6 +1173,17 @@ func (c *Bor) CommitStates( lastStateID++ } + diff2 := time.Since(start2) + + commitStatesSpan.SetAttributes( + attribute.Int("number", int(number)), + attribute.String("hash", header.Hash().String()), + attribute.String("fetch time", diff1.String()), + attribute.String("process time", diff2.String()), + attribute.Int("state sync count", len(stateSyncs)), + attribute.Int("total gas", totalGas), + ) + return stateSyncs, nil } diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 301f9f78d1..ad09552469 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -570,7 +570,7 @@ func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Heade // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, // nor block rewards given, and returns the final block. -func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { +func (c *Clique) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { // Finalize block c.Finalize(chain, header, state, txs, uncles) diff --git a/consensus/consensus.go b/consensus/consensus.go index 9c16f75674..c287972beb 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -98,7 +98,7 @@ type Engine interface { // // Note: The block header and state database might be updated to reflect any // consensus rules that happen at finalization (e.g. block rewards). - FinalizeAndAssemble(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, + FinalizeAndAssemble(ctx context.Context, chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) // Seal generates a new sealing request for the given input block and pushes diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 7dec436a26..761442f44e 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -18,6 +18,7 @@ package ethash import ( "bytes" + "context" "errors" "fmt" "math/big" @@ -598,7 +599,7 @@ func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types. // FinalizeAndAssemble implements consensus.Engine, accumulating the block and // uncle rewards, setting the final state and assembling the block. -func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { +func (ethash *Ethash) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { // Finalize block ethash.Finalize(chain, header, state, txs, uncles) diff --git a/core/chain_makers.go b/core/chain_makers.go index 4b2d2082df..e9944e4744 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -17,6 +17,7 @@ package core import ( + "context" "fmt" "math/big" @@ -258,7 +259,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse } if b.engine != nil { // Finalize and seal the block - block, _ := b.engine.FinalizeAndAssemble(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts) + block, _ := b.engine.FinalizeAndAssemble(context.Background(), chainreader, b.header, statedb, b.txs, b.uncles, b.receipts) // Write state changes to db root, err := statedb.Commit(config.IsEIP158(b.header.Number)) diff --git a/miner/worker.go b/miner/worker.go index 1a96ee1c0f..e35a0efe99 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1143,7 +1143,7 @@ func (w *worker) generateWork(ctx context.Context, params *generateParams) (*typ defer work.discard() w.fillTransactions(ctx, nil, work) - return w.engine.FinalizeAndAssemble(w.chain, work.header, work.state, work.txs, work.unclelist(), work.receipts) + return w.engine.FinalizeAndAssemble(ctx, w.chain, work.header, work.state, work.txs, work.unclelist(), work.receipts) } // commitWork generates several new sealing tasks based on the parent block @@ -1205,7 +1205,7 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), // Create a local environment copy, avoid the data race with snapshot state. // https://github.com/ethereum/go-ethereum/issues/24299 env := env.copy() - block, err := w.engine.FinalizeAndAssemble(w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts) + block, err := w.engine.FinalizeAndAssemble(ctx, w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts) if err != nil { return err } diff --git a/tests/bor/helper.go b/tests/bor/helper.go index a8a3ae4ea6..cc2e156aa9 100644 --- a/tests/bor/helper.go +++ b/tests/bor/helper.go @@ -1,6 +1,7 @@ package bor import ( + "context" "encoding/hex" "encoding/json" "io/ioutil" @@ -145,7 +146,7 @@ func buildNextBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, block * t.Fatalf("%s", err) } - _, err = _bor.FinalizeAndAssemble(chain, header, state, nil, nil, nil) + _, err = _bor.FinalizeAndAssemble(context.Background(), chain, header, state, nil, nil, nil) if err != nil { t.Fatalf("%s", err) } From 4fb9770be97212e28f3bcab8f5e1a1f666e868ed Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 14 Jun 2022 14:16:39 +0530 Subject: [PATCH 11/48] fix --- miner/worker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/worker.go b/miner/worker.go index e35a0efe99..0c557c562d 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1205,7 +1205,7 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), // Create a local environment copy, avoid the data race with snapshot state. // https://github.com/ethereum/go-ethereum/issues/24299 env := env.copy() - block, err := w.engine.FinalizeAndAssemble(ctx, w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts) + block, err := w.engine.FinalizeAndAssemble(commitCtx, w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts) if err != nil { return err } From 75677c25539310dc3f9c604d4aa9dac66570b00d Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 14 Jun 2022 15:02:55 +0530 Subject: [PATCH 12/48] use task ctx in result loop --- miner/worker.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 0c557c562d..c1819680d1 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -303,7 +303,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus worker.wg.Add(4) go worker.mainLoop() go worker.newWorkLoop(newWorkerCtx, recommit) - go worker.resultLoop(newWorkerCtx) + go worker.resultLoop() go worker.taskLoop() // Submit first work to initialize pending state. @@ -700,12 +700,11 @@ func (w *worker) taskLoop() { // resultLoop is a standalone goroutine to handle sealing result submitting // and flush relative data to the database. -func (w *worker) resultLoop(ctx context.Context) { +func (w *worker) resultLoop() { defer w.wg.Done() for { select { case block := <-w.resultCh: - _, resultLoopSpan := w.tracer.Start(ctx, "resultLoop") // Short circuit when receiving empty result. if block == nil { continue @@ -714,6 +713,7 @@ func (w *worker) resultLoop(ctx context.Context) { if w.chain.HasBlock(block.Hash(), block.NumberU64()) { continue } + start1 := time.Now() oldBlock := w.chain.GetBlockByNumber(block.NumberU64()) if oldBlock != nil { oldBlockAuthor, _ := w.chain.Engine().Author(oldBlock.Header()) @@ -723,6 +723,7 @@ func (w *worker) resultLoop(ctx context.Context) { continue } } + diff1 := time.Since(start1) var ( sealhash = w.engine.SealHash(block.Header()) hash = block.Hash() @@ -730,6 +731,7 @@ func (w *worker) resultLoop(ctx context.Context) { w.pendingMu.RLock() task, exist := w.pendingTasks[sealhash] w.pendingMu.RUnlock() + _, resultLoopSpan := w.tracer.Start(task.ctx, "resultLoop") if !exist { log.Error("Block found but no relative pending task", "number", block.Number(), "sealhash", sealhash, "hash", hash) continue @@ -761,7 +763,9 @@ func (w *worker) resultLoop(ctx context.Context) { logs = append(logs, receipt.Logs...) } // Commit block and state to database. + start2 := time.Now() _, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true) + diff2 := time.Since(start2) if err != nil { log.Error("Failed writing block to chain", "err", err) continue @@ -778,6 +782,8 @@ func (w *worker) resultLoop(ctx context.Context) { attribute.String("hash", hash.String()), attribute.Int("number", int(block.Number().Uint64())), attribute.Int("txns", block.Transactions().Len()), + attribute.String("Block fetch and check time taken", diff1.String()), + attribute.String("WriteBlockAndSetHead time taken", diff2.String()), ) resultLoopSpan.End() case <-w.exitCh: From 59050f35d362f828bf835f4409619ab0e9acbbfe Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 15 Jun 2022 16:51:41 +0530 Subject: [PATCH 13/48] only start parent span if no error --- miner/worker.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index c1819680d1..c15c8d7157 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1155,10 +1155,6 @@ func (w *worker) generateWork(ctx context.Context, params *generateParams) (*typ // commitWork generates several new sealing tasks based on the parent block // and submit them to the sealer. func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, timestamp int64) { - - commitWorkCtx, commitWorkSpan := w.tracer.Start(ctx, "commitWork") - defer commitWorkSpan.End() - start := time.Now() // Set the coinbase if the worker is running or it's required @@ -1177,6 +1173,13 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, if err != nil { return } + + commitWorkCtx, commitWorkSpan := w.tracer.Start(ctx, "commitWork") + commitWorkSpan.SetAttributes( + attribute.Int("number", int(work.header.Number.Uint64())), + ) + defer commitWorkSpan.End() + // Create an empty block based on temporary copied state for // sealing in advance without waiting block execution finished. if !noempty && atomic.LoadUint32(&w.noempty) == 0 { From 58d35401476bae415ed687328ea7b676e2fb4db6 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 15 Jun 2022 17:12:32 +0530 Subject: [PATCH 14/48] send nil tracer from Finalize --- consensus/bor/bor.go | 84 ++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index fe4a73d545..47fbafd8b3 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -711,11 +711,6 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header) e // Finalize implements consensus.Engine, ensuring no uncles are set, nor block // rewards given. func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { - - tracer := otel.GetTracerProvider().Tracer("MinerWorker") - finalizeCtx, finalizeSpan := tracer.Start(context.Background(), "Finalize") - defer finalizeSpan.End() - stateSyncData := []*types.StateSyncData{} var err error @@ -725,14 +720,14 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, if headerNumber%c.config.Sprint == 0 { cx := statefull.ChainContext{Chain: chain, Bor: c} // check and commit span - if err := c.checkAndCommitSpan(finalizeCtx, tracer, state, header, cx); err != nil { + if err := c.checkAndCommitSpan(context.Background(), nil, state, header, cx); err != nil { log.Error("Error while committing span", "error", err) return } if c.HeimdallClient != nil { // commit statees - stateSyncData, err = c.CommitStates(finalizeCtx, tracer, state, header, cx) + stateSyncData, err = c.CommitStates(context.Background(), nil, state, header, cx) if err != nil { log.Error("Error while committing states", "error", err) return @@ -1005,8 +1000,12 @@ func (c *Bor) checkAndCommitSpan( chain core.ChainContext, ) error { - checkAndCommitSpanCtx, checkAndCommitSpan := tracer.Start(ctx, "checkAndCommitSpan") - defer checkAndCommitSpan.End() + checkAndCommitSpanCtx := context.Background() + var checkAndCommitSpan trace.Span = nil + if tracer != nil { + checkAndCommitSpanCtx, checkAndCommitSpan = tracer.Start(ctx, "checkAndCommitSpan") + defer checkAndCommitSpan.End() + } headerNumber := header.Number.Uint64() @@ -1015,11 +1014,13 @@ func (c *Bor) checkAndCommitSpan( return err } - checkAndCommitSpan.SetAttributes( - attribute.Int("number", int(headerNumber)), - attribute.String("hash", header.Hash().String()), - attribute.Int("current span id", int(span.ID)), - ) + if checkAndCommitSpan != nil { + checkAndCommitSpan.SetAttributes( + attribute.Int("number", int(headerNumber)), + attribute.String("hash", header.Hash().String()), + attribute.Int("current span id", int(span.ID)), + ) + } if c.needToCommitSpan(span, headerNumber) { return c.FetchAndCommitSpan(checkAndCommitSpanCtx, tracer, span.ID+1, state, header, chain) @@ -1056,8 +1057,11 @@ func (c *Bor) FetchAndCommitSpan( chain core.ChainContext, ) error { - _, fetchAndCommitSpan := tracer.Start(ctx, "FetchAndCommitSpan") - defer fetchAndCommitSpan.End() + var fetchAndCommitSpan trace.Span = nil + if tracer != nil { + _, fetchAndCommitSpan = tracer.Start(ctx, "FetchAndCommitSpan") + defer fetchAndCommitSpan.End() + } var heimdallSpan span.HeimdallSpan @@ -1087,11 +1091,13 @@ func (c *Bor) FetchAndCommitSpan( ) } - fetchAndCommitSpan.SetAttributes( - attribute.Int("number", int(header.Number.Int64())), - attribute.String("hash", header.Hash().String()), - attribute.Int("fetched span id", int(heimdallSpan.ID)), - ) + if fetchAndCommitSpan != nil { + fetchAndCommitSpan.SetAttributes( + attribute.Int("number", int(header.Number.Int64())), + attribute.String("hash", header.Hash().String()), + attribute.Int("fetched span id", int(heimdallSpan.ID)), + ) + } return c.spanner.CommitSpan(heimdallSpan, state, header, chain) } @@ -1105,11 +1111,13 @@ func (c *Bor) CommitStates( chain statefull.ChainContext, ) ([]*types.StateSyncData, error) { - _, commitStatesSpan := tracer.Start(ctx, "CommitStates") - defer commitStatesSpan.End() - - start1 := time.Now() + var commitStatesSpan trace.Span = nil + if tracer != nil { + _, commitStatesSpan = tracer.Start(ctx, "CommitStates") + defer commitStatesSpan.End() + } + fetchStart := time.Now() stateSyncs := make([]*types.StateSyncData, 0) number := header.Number.Uint64() @@ -1137,11 +1145,9 @@ func (c *Bor) CommitStates( } } - diff1 := time.Since(start1) - start2 := time.Now() - + fetchTime := time.Since(fetchStart) + processStart := time.Now() totalGas := 0 /// limit on gas for state sync per block - chainID := c.chainConfig.ChainID.String() for _, eventRecord := range eventRecords { @@ -1173,16 +1179,18 @@ func (c *Bor) CommitStates( lastStateID++ } - diff2 := time.Since(start2) + processTime := time.Since(processStart) - commitStatesSpan.SetAttributes( - attribute.Int("number", int(number)), - attribute.String("hash", header.Hash().String()), - attribute.String("fetch time", diff1.String()), - attribute.String("process time", diff2.String()), - attribute.Int("state sync count", len(stateSyncs)), - attribute.Int("total gas", totalGas), - ) + if commitStatesSpan != nil { + commitStatesSpan.SetAttributes( + attribute.Int("number", int(number)), + attribute.String("hash", header.Hash().String()), + attribute.String("fetch time", fetchTime.String()), + attribute.String("process time", processTime.String()), + attribute.Int("state sync count", len(stateSyncs)), + attribute.Int("total gas", totalGas), + ) + } return stateSyncs, nil } From 20a5a9d2003a1a042627f98034e41e555e95cc3b Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 15 Jun 2022 17:27:35 +0530 Subject: [PATCH 15/48] clean up --- miner/worker.go | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index c15c8d7157..9f5509be5d 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -148,11 +148,11 @@ func (env *environment) discard() { // task contains all information for consensus engine sealing and result submitting. type task struct { + ctx context.Context receipts []*types.Receipt state *state.StateDB block *types.Block createdAt time.Time - ctx context.Context } const ( @@ -163,18 +163,18 @@ const ( // newWorkReq represents a request for new sealing work submitting with relative interrupt notifier. type newWorkReq struct { + ctx context.Context interrupt *int32 noempty bool timestamp int64 - ctx context.Context } // getWorkReq represents a request for getting a new sealing work with provided parameters. type getWorkReq struct { + ctx context.Context params *generateParams err error result chan *types.Block - ctx context.Context } // intervalAdjust represents a resubmitting interval adjustment. @@ -661,8 +661,6 @@ func (w *worker) taskLoop() { for { select { case task := <-w.taskCh: - // taskLoopCtx, taskLoopSpan := w.tracer.Start(task.ctx, "taskLoop") - if w.newTaskHook != nil { w.newTaskHook(task) } @@ -688,9 +686,6 @@ func (w *worker) taskLoop() { delete(w.pendingTasks, sealHash) w.pendingMu.Unlock() } - - // taskLoopSpan.End() - case <-w.exitCh: interrupt() return @@ -713,7 +708,7 @@ func (w *worker) resultLoop() { if w.chain.HasBlock(block.Hash(), block.NumberU64()) { continue } - start1 := time.Now() + getBlockStart := time.Now() oldBlock := w.chain.GetBlockByNumber(block.NumberU64()) if oldBlock != nil { oldBlockAuthor, _ := w.chain.Engine().Author(oldBlock.Header()) @@ -723,7 +718,7 @@ func (w *worker) resultLoop() { continue } } - diff1 := time.Since(start1) + getBlockTime := time.Since(getBlockStart) var ( sealhash = w.engine.SealHash(block.Header()) hash = block.Hash() @@ -763,9 +758,9 @@ func (w *worker) resultLoop() { logs = append(logs, receipt.Logs...) } // Commit block and state to database. - start2 := time.Now() + writeBlockStart := time.Now() _, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true) - diff2 := time.Since(start2) + writeBlockTime := time.Since(writeBlockStart) if err != nil { log.Error("Failed writing block to chain", "err", err) continue @@ -782,8 +777,8 @@ func (w *worker) resultLoop() { attribute.String("hash", hash.String()), attribute.Int("number", int(block.Number().Uint64())), attribute.Int("txns", block.Transactions().Len()), - attribute.String("Block fetch and check time taken", diff1.String()), - attribute.String("WriteBlockAndSetHead time taken", diff2.String()), + attribute.String("Block fetch and check time taken", getBlockTime.String()), + attribute.String("WriteBlockAndSetHead time taken", writeBlockTime.String()), ) resultLoopSpan.End() case <-w.exitCh: @@ -1131,12 +1126,12 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en remoteEnvTCount = env.tcount } fillTransactionsSpan.SetAttributes( - attribute.Int("len of remoteTxs", lenRemotes), - attribute.Int("len of sorted remoteTxs", lenNewRemotes), - attribute.Int("len of final remoteTxs", localEnvTCount), attribute.Int("len of localTxs", lenLocals), attribute.Int("len of sorted localTxs", lenNewLocals), - attribute.Int("len of final localTxs ", remoteEnvTCount), + attribute.Int("len of final localTxs ", localEnvTCount), + attribute.Int("len of remoteTxs", lenRemotes), + attribute.Int("len of sorted remoteTxs", lenNewRemotes), + attribute.Int("len of final remoteTxs", remoteEnvTCount), ) } @@ -1204,10 +1199,9 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, // the deep copy first. func (w *worker) commit(ctx context.Context, env *environment, interval func(), update bool, start time.Time) error { - commitCtx, commitSpan := w.tracer.Start(ctx, "commit") - defer commitSpan.End() - if w.isRunning() { + commitCtx, commitSpan := w.tracer.Start(ctx, "commit") + defer commitSpan.End() if interval != nil { interval() } @@ -1221,7 +1215,7 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), // If we're post merge, just ignore if !w.isTTDReached(block.Header()) { select { - case w.taskCh <- &task{receipts: env.receipts, state: env.state, block: block, createdAt: time.Now(), ctx: commitCtx}: + case w.taskCh <- &task{ctx: commitCtx, receipts: env.receipts, state: env.state, block: block, createdAt: time.Now()}: w.unconfirmed.Shift(block.NumberU64() - 1) log.Info("Commit new sealing work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()), "uncles", len(env.uncles), "txs", env.tcount, From bcb11f2a4c2440f1a13732e3ea28b19843223e33 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Mon, 20 Jun 2022 13:37:59 +0530 Subject: [PATCH 16/48] add sub function timings in span attribute --- consensus/bor/bor.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index ece1bebc94..8d86d2f092 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -790,12 +790,6 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead finalizeCtx, finalizeSpan := tracer.Start(ctx, "FinalizeAndAssemble") defer finalizeSpan.End() - finalizeSpan.SetAttributes( - attribute.Int("number", int(header.Number.Int64())), - attribute.String("hash", header.Hash().String()), - attribute.Int("number of txs", len(txs)), - ) - stateSyncData := []*types.StateSyncData{} headerNumber := header.Number.Uint64() @@ -820,22 +814,37 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead } } + start1 := time.Now() if err := c.changeContractCodeIfNeeded(headerNumber, state); err != nil { log.Error("Error changing contract code", "error", err) return nil, err } + diff1 := time.Since(start1) // No block rewards in PoA, so the state remains as is and uncles are dropped + start2 := time.Now() header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) header.UncleHash = types.CalcUncleHash(nil) + diff2 := time.Since(start2) // Assemble block + start3 := time.Now() block := types.NewBlock(header, txs, nil, receipts, new(trie.Trie)) + diff3 := time.Since(start3) // set state sync bc := chain.(core.BorStateSyncer) bc.SetStateSync(stateSyncData) + finalizeSpan.SetAttributes( + attribute.Int("number", int(header.Number.Int64())), + attribute.String("hash", header.Hash().String()), + attribute.Int("number of txs", len(txs)), + attribute.String("change contract code time", diff1.String()), + attribute.String("intermeddiate root hash calc time", diff2.String()), + attribute.String("assemble new block time", diff3.String()), + ) + // return the final block for sealing return block, nil } From 950bfe4bc7bbba700a3ad631066d520fa507f59d Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Mon, 20 Jun 2022 17:15:32 +0530 Subject: [PATCH 17/48] modify span attributes --- consensus/bor/bor.go | 20 ++++++++++++-------- miner/worker.go | 33 ++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 8d86d2f092..dfe09e0ae0 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -840,6 +840,7 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead attribute.Int("number", int(header.Number.Int64())), attribute.String("hash", header.Hash().String()), attribute.Int("number of txs", len(txs)), + attribute.Int("gas used", int(block.GasUsed())), attribute.String("change contract code time", diff1.String()), attribute.String("intermeddiate root hash calc time", diff2.String()), attribute.String("assemble new block time", diff3.String()), @@ -890,7 +891,10 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block // Bail out if we're unauthorized to sign a block if !snap.ValidatorSet.HasAddress(signer.Bytes()) { // Check the UnauthorizedSignerError.Error() msg to see why we pass number-1 - return &UnauthorizedSignerError{number - 1, signer.Bytes()} + err := &UnauthorizedSignerError{number - 1, signer.Bytes()} + sealSpan.SetAttributes(attribute.String("error", err.Error())) + sealSpan.End() + return err } successionNumber, err := snap.GetSignerSuccessionNumber(signer) @@ -1010,7 +1014,7 @@ func (c *Bor) checkAndCommitSpan( ) error { checkAndCommitSpanCtx := context.Background() - var checkAndCommitSpan trace.Span = nil + var checkAndCommitSpan trace.Span if tracer != nil { checkAndCommitSpanCtx, checkAndCommitSpan = tracer.Start(ctx, "checkAndCommitSpan") defer checkAndCommitSpan.End() @@ -1019,17 +1023,17 @@ func (c *Bor) checkAndCommitSpan( headerNumber := header.Number.Uint64() span, err := c.spanner.GetCurrentSpan(header.ParentHash) - if err != nil { - return err - } - if checkAndCommitSpan != nil { checkAndCommitSpan.SetAttributes( attribute.Int("number", int(headerNumber)), attribute.String("hash", header.Hash().String()), attribute.Int("current span id", int(span.ID)), + attribute.Bool("error", err != nil), ) } + if err != nil { + return err + } if c.needToCommitSpan(span, headerNumber) { return c.FetchAndCommitSpan(checkAndCommitSpanCtx, tracer, span.ID+1, state, header, chain) @@ -1066,7 +1070,7 @@ func (c *Bor) FetchAndCommitSpan( chain core.ChainContext, ) error { - var fetchAndCommitSpan trace.Span = nil + var fetchAndCommitSpan trace.Span if tracer != nil { _, fetchAndCommitSpan = tracer.Start(ctx, "FetchAndCommitSpan") defer fetchAndCommitSpan.End() @@ -1120,7 +1124,7 @@ func (c *Bor) CommitStates( chain statefull.ChainContext, ) ([]*types.StateSyncData, error) { - var commitStatesSpan trace.Span = nil + var commitStatesSpan trace.Span if tracer != nil { _, commitStatesSpan = tracer.Start(ctx, "CommitStates") defer commitStatesSpan.End() diff --git a/miner/worker.go b/miner/worker.go index 596ec1570c..173c7c25b1 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -765,6 +765,17 @@ func (w *worker) resultLoop() { writeBlockStart := time.Now() _, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true) writeBlockTime := time.Since(writeBlockStart) + resultLoopSpan.SetAttributes( + attribute.String("hash", hash.String()), + attribute.Int("number", int(block.Number().Uint64())), + attribute.Int("txns", block.Transactions().Len()), + attribute.Int("gas used", int(block.GasUsed())), + attribute.String("Block fetch and check time taken", getBlockTime.String()), + attribute.String("WriteBlockAndSetHead time taken", writeBlockTime.String()), + attribute.Bool("error", err != nil), + ) + resultLoopSpan.End() + if err != nil { log.Error("Failed writing block to chain", "err", err) continue @@ -777,14 +788,6 @@ func (w *worker) resultLoop() { // Insert the block into the set of pending ones to resultLoop for confirmations w.unconfirmed.Insert(block.NumberU64(), block.Hash()) - resultLoopSpan.SetAttributes( - attribute.String("hash", hash.String()), - attribute.Int("number", int(block.Number().Uint64())), - attribute.Int("txns", block.Transactions().Len()), - attribute.String("Block fetch and check time taken", getBlockTime.String()), - attribute.String("WriteBlockAndSetHead time taken", writeBlockTime.String()), - ) - resultLoopSpan.End() case <-w.exitCh: return } @@ -1213,6 +1216,13 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), // https://github.com/ethereum/go-ethereum/issues/24299 env := env.copy() block, err := w.engine.FinalizeAndAssemble(commitCtx, w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts) + commitSpan.SetAttributes( + attribute.Int("number", int(block.Number().Uint64())), + attribute.String("hash", block.Hash().String()), + attribute.String("sealhash", w.engine.SealHash(block.Header()).String()), + attribute.Int("len of env.txs", len(env.txs)), + attribute.Bool("error", err != nil), + ) if err != nil { return err } @@ -1230,13 +1240,6 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), log.Info("Worker has exited") } } - - commitSpan.SetAttributes( - attribute.Int("number", int(block.Number().Uint64())), - attribute.String("hash", block.Hash().String()), - attribute.String("sealhash", w.engine.SealHash(block.Header()).String()), - attribute.Int("len of env.txs", len(env.txs)), - ) } if update { w.updateSnapshot(env) From d848647f9d5fa0138aa6e8760f9cfcddb6dc5550 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 21 Jun 2022 15:36:01 +0530 Subject: [PATCH 18/48] set time attribute to milliseconds --- consensus/bor/bor.go | 13 +++++++------ miner/worker.go | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index dfe09e0ae0..69fa4f08fa 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -841,9 +841,9 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead attribute.String("hash", header.Hash().String()), attribute.Int("number of txs", len(txs)), attribute.Int("gas used", int(block.GasUsed())), - attribute.String("change contract code time", diff1.String()), - attribute.String("intermeddiate root hash calc time", diff2.String()), - attribute.String("assemble new block time", diff3.String()), + attribute.Int("change contract code time", int(diff1.Milliseconds())), + attribute.Int("intermeddiate root hash calc time", int(diff2.Milliseconds())), + attribute.Int("assemble new block time", int(diff3.Milliseconds())), ) // return the final block for sealing @@ -942,7 +942,8 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block sealSpan.SetAttributes( attribute.Int("number", int(number)), attribute.String("hash", header.Hash().String()), - attribute.String("delay", delay.String()), + attribute.Int("delay", int(delay.Milliseconds())), + attribute.Int("wiggle", int(wiggle.Milliseconds())), attribute.Bool("out-of-turn", wiggle > 0), ) sealSpan.End() @@ -1198,8 +1199,8 @@ func (c *Bor) CommitStates( commitStatesSpan.SetAttributes( attribute.Int("number", int(number)), attribute.String("hash", header.Hash().String()), - attribute.String("fetch time", fetchTime.String()), - attribute.String("process time", processTime.String()), + attribute.Int("fetch time", int(fetchTime.Milliseconds())), + attribute.Int("process time", int(processTime.Milliseconds())), attribute.Int("state sync count", len(stateSyncs)), attribute.Int("total gas", totalGas), ) diff --git a/miner/worker.go b/miner/worker.go index 173c7c25b1..2388682e8b 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -770,8 +770,9 @@ func (w *worker) resultLoop() { attribute.Int("number", int(block.Number().Uint64())), attribute.Int("txns", block.Transactions().Len()), attribute.Int("gas used", int(block.GasUsed())), - attribute.String("Block fetch and check time taken", getBlockTime.String()), - attribute.String("WriteBlockAndSetHead time taken", writeBlockTime.String()), + attribute.Int("Block fetch and check time taken", int(getBlockTime.Milliseconds())), + attribute.Int("WriteBlockAndSetHead time taken", int(writeBlockTime.Milliseconds())), + attribute.Int("elapsed", int(time.Since(task.createdAt).Milliseconds())), attribute.Bool("error", err != nil), ) resultLoopSpan.End() From cc1a18de6c04714eae4f1087e9072b95df95c6b7 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Wed, 22 Jun 2022 18:00:20 +0530 Subject: [PATCH 19/48] linters fix --- go.mod | 2 +- miner/worker.go | 29 +++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 1b452a67a1..ad9c0b1777 100644 --- a/go.mod +++ b/go.mod @@ -127,7 +127,7 @@ require ( github.com/tklauser/numcpus v0.2.2 // indirect github.com/zclconf/go-cty v1.8.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0 // indirect - go.opentelemetry.io/otel/trace v1.2.0 // indirect + go.opentelemetry.io/otel/trace v1.2.0 go.opentelemetry.io/proto/otlp v0.10.0 // indirect golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect diff --git a/miner/worker.go b/miner/worker.go index 2388682e8b..5f6d7ad5c1 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -581,7 +581,10 @@ func (w *worker) mainLoop() { if w.isRunning() && w.current != nil && len(w.current.uncles) < 2 { start := time.Now() if err := w.commitUncle(w.current, ev.Block.Header()); err == nil { - w.commit(context.Background(), w.current.copy(), nil, true, start) + commitErr := w.commit(context.Background(), w.current.copy(), nil, true, start) + if commitErr != nil { + log.Error("error while committing", commitErr) + } } } @@ -712,6 +715,7 @@ func (w *worker) resultLoop() { if w.chain.HasBlock(block.Hash(), block.NumberU64()) { continue } + getBlockStart := time.Now() oldBlock := w.chain.GetBlockByNumber(block.NumberU64()) if oldBlock != nil { @@ -722,6 +726,7 @@ func (w *worker) resultLoop() { continue } } + getBlockTime := time.Since(getBlockStart) var ( sealhash = w.engine.SealHash(block.Header()) @@ -1100,7 +1105,6 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { // into the given sealing block. The transaction selection and ordering strategy can // be customized with the plugin in the future. func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *environment) { - _, fillTransactionsSpan := w.tracer.Start(ctx, "fillTransactions") defer fillTransactionsSpan.End() @@ -1114,7 +1118,9 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en localTxs[account] = txs } } + lenLocals, lenNewLocals, localEnvTCount, lenRemotes, lenNewRemotes, remoteEnvTCount := 0, 0, 0, 0, 0, 0 + if len(localTxs) > 0 { lenLocals = len(localTxs) txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) @@ -1122,6 +1128,7 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en if w.commitTransactions(env, txs, interrupt) { return } + localEnvTCount = env.tcount } if len(remoteTxs) > 0 { @@ -1131,8 +1138,10 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en if w.commitTransactions(env, txs, interrupt) { return } + remoteEnvTCount = env.tcount } + fillTransactionsSpan.SetAttributes( attribute.Int("len of localTxs", lenLocals), attribute.Int("len of sorted localTxs", lenNewLocals), @@ -1152,6 +1161,7 @@ func (w *worker) generateWork(ctx context.Context, params *generateParams) (*typ defer work.discard() w.fillTransactions(ctx, nil, work) + return w.engine.FinalizeAndAssemble(ctx, w.chain, work.header, work.state, work.txs, work.unclelist(), work.receipts) } @@ -1178,19 +1188,27 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, } commitWorkCtx, commitWorkSpan := w.tracer.Start(ctx, "commitWork") + defer commitWorkSpan.End() + commitWorkSpan.SetAttributes( attribute.Int("number", int(work.header.Number.Uint64())), ) - defer commitWorkSpan.End() // Create an empty block based on temporary copied state for // sealing in advance without waiting block execution finished. if !noempty && atomic.LoadUint32(&w.noempty) == 0 { - w.commit(commitWorkCtx, work.copy(), nil, false, start) + err = w.commit(commitWorkCtx, work.copy(), nil, false, start) + if err != nil { + return + } } // Fill pending transactions from the txpool w.fillTransactions(commitWorkCtx, interrupt, work) - w.commit(commitWorkCtx, work.copy(), w.fullTaskHook, true, start) + + err = w.commit(commitWorkCtx, work.copy(), w.fullTaskHook, true, start) + if err != nil { + return + } // Swap out the old work with the new one, terminating any leftover // prefetcher processes in the mean time and starting a new one. @@ -1206,7 +1224,6 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, // Note the assumption is held that the mutation is allowed to the passed env, do // the deep copy first. func (w *worker) commit(ctx context.Context, env *environment, interval func(), update bool, start time.Time) error { - if w.isRunning() { commitCtx, commitSpan := w.tracer.Start(ctx, "commit") defer commitSpan.End() From 6022e86c34eb6f9a718d7737b58686d84d470930 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 22 Jun 2022 18:02:18 +0530 Subject: [PATCH 20/48] fix linters for consensus --- consensus/bor/bor.go | 11 +++++++---- consensus/ethash/ethash_test.go | 17 +++++++++++------ consensus/ethash/sealer.go | 1 + consensus/ethash/sealer_test.go | 30 +++++++++++++++++++++++++----- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 69fa4f08fa..b0d2395268 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -785,8 +785,8 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.State // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, // nor block rewards given, and returns the final block. func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { - tracer := otel.GetTracerProvider().Tracer("MinerWorker") + finalizeCtx, finalizeSpan := tracer.Start(ctx, "FinalizeAndAssemble") defer finalizeSpan.End() @@ -819,6 +819,7 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead log.Error("Error changing contract code", "error", err) return nil, err } + diff1 := time.Since(start1) // No block rewards in PoA, so the state remains as is and uncles are dropped @@ -863,7 +864,6 @@ func (c *Bor) Authorize(signer common.Address, signFn SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { - tracer := otel.GetTracerProvider().Tracer("MinerWorker") _, sealSpan := tracer.Start(ctx, "Seal") @@ -894,6 +894,7 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block err := &UnauthorizedSignerError{number - 1, signer.Bytes()} sealSpan.SetAttributes(attribute.String("error", err.Error())) sealSpan.End() + return err } @@ -1013,9 +1014,11 @@ func (c *Bor) checkAndCommitSpan( header *types.Header, chain core.ChainContext, ) error { + var ( + checkAndCommitSpanCtx = context.Background() + checkAndCommitSpan trace.Span + ) - checkAndCommitSpanCtx := context.Background() - var checkAndCommitSpan trace.Span if tracer != nil { checkAndCommitSpanCtx, checkAndCommitSpan = tracer.Start(ctx, "checkAndCommitSpan") defer checkAndCommitSpan.End() diff --git a/consensus/ethash/ethash_test.go b/consensus/ethash/ethash_test.go index d63eef286b..ef8cd3e8fa 100644 --- a/consensus/ethash/ethash_test.go +++ b/consensus/ethash/ethash_test.go @@ -112,12 +112,13 @@ func TestRemoteSealer(t *testing.T) { // Push new work. results := make(chan *types.Block) - ethash.Seal(context.Background(), nil, block, results, nil) + err := ethash.Seal(context.Background(), nil, block, results, nil) - var ( - work [4]string - err error - ) + if err != nil { + t.Error("error in sealing block") + } + + var work [4]string if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() { t.Error("expect to return a mining work has same hash") } @@ -129,7 +130,11 @@ func TestRemoteSealer(t *testing.T) { header = &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(1000)} block = types.NewBlockWithHeader(header) sealhash = ethash.SealHash(header) - ethash.Seal(context.Background(), nil, block, results, nil) + err = ethash.Seal(context.Background(), nil, block, results, nil) + + if err != nil { + t.Error("error in sealing block") + } if work, err = api.GetWork(); err != nil || work[0] != sealhash.Hex() { t.Error("expect to return the latest pushed work") diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go index b83c282cba..d851a065f2 100644 --- a/consensus/ethash/sealer.go +++ b/consensus/ethash/sealer.go @@ -117,6 +117,7 @@ func (ethash *Ethash) Seal(ctx context.Context, chain consensus.ChainHeaderReade case <-ethash.update: // Thread count was changed on user request, restart close(abort) + if err := ethash.Seal(ctx, chain, block, results, stop); err != nil { ethash.config.Log.Error("Failed to restart sealing after update", "err", err) } diff --git a/consensus/ethash/sealer_test.go b/consensus/ethash/sealer_test.go index 220aae1fd0..d850080277 100644 --- a/consensus/ethash/sealer_test.go +++ b/consensus/ethash/sealer_test.go @@ -58,7 +58,11 @@ func TestRemoteNotify(t *testing.T) { header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)} block := types.NewBlockWithHeader(header) - ethash.Seal(context.Background(), nil, block, nil, nil) + err := ethash.Seal(context.Background(), nil, block, nil, nil) + + if err != nil { + t.Error("error in sealing block") + } select { case work := <-sink: if want := ethash.SealHash(header).Hex(); work[0] != want { @@ -106,7 +110,11 @@ func TestRemoteNotifyFull(t *testing.T) { header := &types.Header{Number: big.NewInt(1), Difficulty: big.NewInt(100)} block := types.NewBlockWithHeader(header) - ethash.Seal(context.Background(), nil, block, nil, nil) + err := ethash.Seal(context.Background(), nil, block, nil, nil) + + if err != nil { + t.Error("error in sealing block") + } select { case work := <-sink: if want := "0x" + strconv.FormatUint(header.Number.Uint64(), 16); work["number"] != want { @@ -152,7 +160,11 @@ func TestRemoteMultiNotify(t *testing.T) { for i := 0; i < cap(sink); i++ { header := &types.Header{Number: big.NewInt(int64(i)), Difficulty: big.NewInt(100)} block := types.NewBlockWithHeader(header) - ethash.Seal(context.Background(), nil, block, results, nil) + err := ethash.Seal(context.Background(), nil, block, results, nil) + + if err != nil { + t.Error("error in sealing block") + } } for i := 0; i < cap(sink); i++ { @@ -201,7 +213,11 @@ func TestRemoteMultiNotifyFull(t *testing.T) { for i := 0; i < cap(sink); i++ { header := &types.Header{Number: big.NewInt(int64(i)), Difficulty: big.NewInt(100)} block := types.NewBlockWithHeader(header) - ethash.Seal(context.Background(), nil, block, results, nil) + err := ethash.Seal(context.Background(), nil, block, results, nil) + + if err != nil { + t.Error("error in sealing block") + } } for i := 0; i < cap(sink); i++ { @@ -267,7 +283,11 @@ func TestStaleSubmission(t *testing.T) { for id, c := range testcases { for _, h := range c.headers { - ethash.Seal(context.Background(), nil, types.NewBlockWithHeader(h), results, nil) + err := ethash.Seal(context.Background(), nil, types.NewBlockWithHeader(h), results, nil) + + if err != nil { + t.Error("error in sealing block") + } } if res := api.SubmitWork(fakeNonce, ethash.SealHash(c.headers[c.submitIndex]), fakeDigest); res != c.submitRes { t.Errorf("case %d submit result mismatch, want %t, get %t", id+1, c.submitRes, res) From c9f3d2578849fb6db8638e135e759f6a0e309c35 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 22 Jun 2022 18:08:44 +0530 Subject: [PATCH 21/48] add nolint to worker --- miner/worker.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/miner/worker.go b/miner/worker.go index 5f6d7ad5c1..744469b9c2 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -148,6 +148,7 @@ func (env *environment) discard() { // task contains all information for consensus engine sealing and result submitting. type task struct { + //nolint:containedctx ctx context.Context receipts []*types.Receipt state *state.StateDB @@ -163,6 +164,7 @@ const ( // newWorkReq represents a request for new sealing work submitting with relative interrupt notifier. type newWorkReq struct { + //nolint:containedctx ctx context.Context interrupt *int32 noempty bool @@ -171,6 +173,7 @@ type newWorkReq struct { // getWorkReq represents a request for getting a new sealing work with provided parameters. type getWorkReq struct { + //nolint:containedctx ctx context.Context params *generateParams err error @@ -433,6 +436,7 @@ func recalcRecommit(minRecommit, prev time.Duration, target float64, inc bool) t } // newWorkLoop is a standalone goroutine to submit new sealing work upon received events. +//nolint:gocognit func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { defer w.wg.Done() var ( From 9d7ac22fd319fee9b5c6001a6d5a1499dd166d86 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Wed, 22 Jun 2022 22:12:25 +0530 Subject: [PATCH 22/48] fix testcase --- miner/worker.go | 1 + 1 file changed, 1 insertion(+) diff --git a/miner/worker.go b/miner/worker.go index 744469b9c2..4e8d691452 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1283,6 +1283,7 @@ func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase noExtra: true, }, result: make(chan *types.Block, 1), + ctx: context.Background(), } select { case w.getWorkCh <- req: From 99984dc91bac234eee0f686f42aa7853181cbcfa Mon Sep 17 00:00:00 2001 From: Shivam Sharma Date: Wed, 6 Jul 2022 17:36:15 +0530 Subject: [PATCH 23/48] Added fillTransactions subTraces --- miner/worker.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/miner/worker.go b/miner/worker.go index 4e8d691452..25ec58abfd 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1109,11 +1109,14 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { // into the given sealing block. The transaction selection and ordering strategy can // be customized with the plugin in the future. func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *environment) { - _, fillTransactionsSpan := w.tracer.Start(ctx, "fillTransactions") + fillTxCtx, fillTransactionsSpan := w.tracer.Start(ctx, "fillTransactions") defer fillTransactionsSpan.End() // Split the pending transactions into locals and remotes // Fill the block with all available pending transactions. + + _, splittingTransactionsSpan := w.tracer.Start(fillTxCtx, "SplittingTransactions") + pending := w.eth.TxPool().Pending(true) localTxs, remoteTxs := make(map[common.Address]types.Transactions), pending for _, account := range w.eth.TxPool().Locals() { @@ -1122,26 +1125,53 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en localTxs[account] = txs } } + splittingTransactionsSpan.SetAttributes( + attribute.Int("LocalTx Len", len(localTxs)), + attribute.Int("RemoteTx Len", len(remoteTxs)), + ) + splittingTransactionsSpan.End() lenLocals, lenNewLocals, localEnvTCount, lenRemotes, lenNewRemotes, remoteEnvTCount := 0, 0, 0, 0, 0, 0 if len(localTxs) > 0 { lenLocals = len(localTxs) + _, transactionsByPriceAndNonceSpan := w.tracer.Start(fillTxCtx, "LocalTransactionsByPriceAndNonce") txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) + transactionsByPriceAndNonceSpan.SetAttributes( + attribute.Int("len of tx Heads", txs.GetTxs()), + ) + transactionsByPriceAndNonceSpan.End() lenNewLocals = txs.GetTxs() + + _, commitTransactionsSpan := w.tracer.Start(fillTxCtx, "LocalCommitTransactions") if w.commitTransactions(env, txs, interrupt) { return } + commitTransactionsSpan.SetAttributes( + attribute.Int("len of tx Heads", txs.GetTxs()), + ) + commitTransactionsSpan.End() localEnvTCount = env.tcount } if len(remoteTxs) > 0 { lenRemotes = len(remoteTxs) + _, TransactionsByPriceAndNonceSpan := w.tracer.Start(fillTxCtx, "RemoteTransactionsByPriceAndNonce") txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) + TransactionsByPriceAndNonceSpan.SetAttributes( + attribute.Int("len of tx Heads", txs.GetTxs()), + ) + TransactionsByPriceAndNonceSpan.End() lenNewRemotes = txs.GetTxs() + + _, CommitTransactionsSpan := w.tracer.Start(fillTxCtx, "RemoteCommitTransactions") if w.commitTransactions(env, txs, interrupt) { return } + CommitTransactionsSpan.SetAttributes( + attribute.Int("len of tx Heads", txs.GetTxs()), + ) + CommitTransactionsSpan.End() remoteEnvTCount = env.tcount } From 9588aa9d754e06021b01fcf55c773b70937397f6 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 12 Jul 2022 10:45:30 +0530 Subject: [PATCH 24/48] add traces in intermediate root hash function --- cmd/evm/internal/t8ntool/execution.go | 5 +-- cmd/evm/runner.go | 3 +- cmd/evm/staterunner.go | 3 +- consensus/beacon/consensus.go | 2 +- consensus/bor/bor.go | 4 +-- consensus/clique/clique.go | 2 +- consensus/ethash/consensus.go | 2 +- core/block_validator.go | 3 +- core/chain_makers.go | 2 +- core/state/statedb.go | 49 +++++++++++++++++++++++++-- core/state/statedb_test.go | 5 +-- core/state_prefetcher.go | 5 +-- core/state_processor.go | 3 +- eth/api_test.go | 5 +-- eth/tracers/api.go | 2 +- eth/tracers/api_bor.go | 2 +- tests/state_test_util.go | 3 +- 17 files changed, 76 insertions(+), 24 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 874685f15e..8d5272e83f 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -17,6 +17,7 @@ package t8ntool import ( + "context" "fmt" "math/big" "os" @@ -192,7 +193,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, if chainConfig.IsByzantium(vmContext.BlockNumber) { statedb.Finalise(true) } else { - root = statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)).Bytes() + root = statedb.IntermediateRoot(context.Background(), chainConfig.IsEIP158(vmContext.BlockNumber)).Bytes() } // Create a new receipt for the transaction, storing the intermediate root and @@ -223,7 +224,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, txIndex++ } - statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)) + statedb.IntermediateRoot(context.Background(), chainConfig.IsEIP158(vmContext.BlockNumber)) // Add mining reward? if miningReward > 0 { // Add mining reward. The mining reward may be `0`, which only makes a difference in the cases diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 889de43e0a..2c4ae44edf 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -18,6 +18,7 @@ package main import ( "bytes" + "context" "encoding/json" "fmt" "io/ioutil" @@ -269,7 +270,7 @@ func runCmd(ctx *cli.Context) error { if ctx.GlobalBool(DumpFlag.Name) { statedb.Commit(true) - statedb.IntermediateRoot(true) + statedb.IntermediateRoot(context.Background(), true) fmt.Println(string(statedb.Dump(nil))) } diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 90596d9b3c..46c959a7c4 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -17,6 +17,7 @@ package main import ( + "context" "encoding/json" "errors" "fmt" @@ -102,7 +103,7 @@ func stateTestCmd(ctx *cli.Context) error { _, s, err := test.Run(st, cfg, false) // print state root for evmlab tracing if ctx.GlobalBool(MachineFlag.Name) && s != nil { - fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", s.IntermediateRoot(false)) + fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", s.IntermediateRoot(context.Background(), false)) } if err != nil { // Test failed, mark as so and dump any state to aid debugging diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 338b08ca70..992acfdbae 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -274,7 +274,7 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types. } // The block reward is no longer handled here. It's done by the // external consensus engine. - header.Root = state.IntermediateRoot(true) + header.Root = state.IntermediateRoot(context.Background(), true) } // FinalizeAndAssemble implements consensus.Engine, setting the final state and diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 159e725027..ca41407bc0 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -741,7 +741,7 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, } // No block rewards in PoA, so the state remains as is and uncles are dropped - header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(context.Background(), chain.Config().IsEIP158(header.Number)) header.UncleHash = types.CalcUncleHash(nil) // Set state sync data to blockchain @@ -824,7 +824,7 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead // No block rewards in PoA, so the state remains as is and uncles are dropped start2 := time.Now() - header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(finalizeCtx, chain.Config().IsEIP158(header.Number)) header.UncleHash = types.CalcUncleHash(nil) diff2 := time.Since(start2) diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index ad09552469..512a04a9dd 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -564,7 +564,7 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header // rewards given. func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { // No block rewards in PoA, so the state remains as is and uncles are dropped - header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(context.Background(), chain.Config().IsEIP158(header.Number)) header.UncleHash = types.CalcUncleHash(nil) } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 761442f44e..75ddd6fdd6 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -594,7 +594,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { // Accumulate any block and uncle rewards and commit the final state root accumulateRewards(chain.Config(), state, header, uncles) - header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(context.Background(), chain.Config().IsEIP158(header.Number)) } // FinalizeAndAssemble implements consensus.Engine, accumulating the block and diff --git a/core/block_validator.go b/core/block_validator.go index 3763be0be0..3ed9c21c01 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -17,6 +17,7 @@ package core import ( + "context" "fmt" "github.com/ethereum/go-ethereum/consensus" @@ -96,7 +97,7 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD } // Validate the state root against the received state root and throw // an error if they don't match. - if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root { + if root := statedb.IntermediateRoot(context.Background(), v.config.IsEIP158(header.Number)); header.Root != root { return fmt.Errorf("invalid merkle root (remote: %x local: %x)", header.Root, root) } return nil diff --git a/core/chain_makers.go b/core/chain_makers.go index e9944e4744..561826cf1a 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -294,7 +294,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S time = parent.Time() + 10 // block time is fixed at 10 seconds } header := &types.Header{ - Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())), + Root: state.IntermediateRoot(context.Background(), chain.Config().IsEIP158(parent.Number())), ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), Difficulty: engine.CalcDifficulty(chain, time, &types.Header{ diff --git a/core/state/statedb.go b/core/state/statedb.go index 1d31cf470b..9b6f37c3a6 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -18,6 +18,7 @@ package state import ( + "context" "errors" "fmt" "math/big" @@ -33,6 +34,8 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" ) type revision struct { @@ -819,9 +822,17 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { // IntermediateRoot computes the current root hash of the state trie. // It is called in between transactions to get the root hash that // goes into transaction receipts. -func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { +func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) common.Hash { + // Fetch the tracer and create a sub-span here + tracer := otel.GetTracerProvider().Tracer("MinerWorker") + + _, intermediateRootSpan := tracer.Start(ctx, "IntermediateRoot") + defer intermediateRootSpan.End() + // Finalise all the dirty storage states and write them into the tries + finalizeStart := time.Now() s.Finalise(deleteEmptyObjects) + finalizeTime := time.Since(finalizeStart) // If there was a trie prefetcher operating, it gets aborted and irrevocably // modified after we start retrieving tries. Remove it from the statedb after @@ -842,19 +853,31 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { // the account prefetcher. Instead, let's process all the storage updates // first, giving the account prefeches just a few more milliseconds of time // to pull useful data from disk. + updateRootStart := time.Now() + updatedRootInitialLength := len(s.stateObjectsPending) + updated := 0 for addr := range s.stateObjectsPending { if obj := s.stateObjects[addr]; !obj.deleted { obj.updateRoot(s.db) + updated++ } } + updateRootTime := time.Since(updateRootStart) + // Now we're about to start to write changes to the trie. The trie is so far // _untouched_. We can check with the prefetcher, if it can give us a trie // which has the same root, but also has some content loaded into it. + trieFetchStart := time.Now() if prefetcher != nil { if trie := prefetcher.trie(s.originalRoot); trie != nil { s.trie = trie } } + trieFetchTime := time.Since(trieFetchStart) + + stateIterationStart := time.Now() + stateIterationLength := len(s.stateObjectsPending) + iterations := 0 usedAddrs := make([][]byte, 0, len(s.stateObjectsPending)) for addr := range s.stateObjectsPending { if obj := s.stateObjects[addr]; obj.deleted { @@ -865,7 +888,10 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { s.AccountUpdated += 1 } usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure + iterations++ } + stateIterationTime := time.Since(stateIterationStart) + if prefetcher != nil { prefetcher.used(s.originalRoot, usedAddrs) } @@ -876,7 +902,24 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { if metrics.EnabledExpensive { defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) } - return s.trie.Hash() + + hashCalculationStart := time.Now() + hash := s.trie.Hash() + hashCalculationTime := time.Since(hashCalculationStart) + + intermediateRootSpan.SetAttributes( + attribute.Int("finalize time", int(finalizeTime.Milliseconds())), + attribute.Int("updateRoot time", int(updateRootTime.Milliseconds())), + attribute.Int("updateRoot initial length", updatedRootInitialLength), + attribute.Int("updateRoot iterations", updated), + attribute.Int("trieFetch time", int(trieFetchTime.Milliseconds())), + attribute.Int("stateIteration time", int(stateIterationTime.Milliseconds())), + attribute.Int("stateIteration initial length", stateIterationLength), + attribute.Int("stateIteration iterations", iterations), + attribute.Int("hashCalculation time", int(hashCalculationTime.Milliseconds())), + ) + + return hash } // Prepare sets the current transaction hash and index which are @@ -900,7 +943,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) } // Finalize any pending changes and merge everything into the tries - s.IntermediateRoot(deleteEmptyObjects) + s.IntermediateRoot(context.Background(), deleteEmptyObjects) // Commit objects to the trie, measuring the elapsed time var storageCommitted int diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index e9576d4dc4..52cd5390c2 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -18,6 +18,7 @@ package state import ( "bytes" + "context" "encoding/binary" "fmt" "math" @@ -54,7 +55,7 @@ func TestUpdateLeaks(t *testing.T) { } } - root := state.IntermediateRoot(false) + root := state.IntermediateRoot(context.Background(), false) if err := state.Database().TrieDB().Commit(root, false, nil); err != nil { t.Errorf("can not commit trie %v to persistent database", root.Hex()) } @@ -93,7 +94,7 @@ func TestIntermediateLeaks(t *testing.T) { modify(transState, common.Address{i}, i, 0) } // Write modifications to trie. - transState.IntermediateRoot(false) + transState.IntermediateRoot(context.Background(), false) // Overwrite all the data with new values in the transient database. for i := byte(0); i < 255; i++ { diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 10a1722940..a925c0e2af 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -17,6 +17,7 @@ package core import ( + "context" "sync/atomic" "github.com/ethereum/go-ethereum/consensus" @@ -73,12 +74,12 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c } // If we're pre-byzantium, pre-load trie nodes for the intermediate root if !byzantium { - statedb.IntermediateRoot(true) + statedb.IntermediateRoot(context.Background(), true) } } // If were post-byzantium, pre-load trie nodes for the final root hash if byzantium { - statedb.IntermediateRoot(true) + statedb.IntermediateRoot(context.Background(), true) } } diff --git a/core/state_processor.go b/core/state_processor.go index d4c77ae410..6484cf93f3 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,6 +17,7 @@ package core import ( + "context" "fmt" "math/big" @@ -108,7 +109,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon if config.IsByzantium(blockNumber) { statedb.Finalise(true) } else { - root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes() + root = statedb.IntermediateRoot(context.Background(), config.IsEIP158(blockNumber)).Bytes() } *usedGas += result.UsedGas diff --git a/eth/api_test.go b/eth/api_test.go index 39a1d58460..1793b0ffac 100644 --- a/eth/api_test.go +++ b/eth/api_test.go @@ -18,6 +18,7 @@ package eth import ( "bytes" + "context" "fmt" "math/big" "reflect" @@ -84,7 +85,7 @@ func TestAccountRange(t *testing.T) { } } state.Commit(true) - root := state.IntermediateRoot(true) + root := state.IntermediateRoot(context.Background(), true) trie, err := statedb.OpenTrie(root) if err != nil { @@ -141,7 +142,7 @@ func TestEmptyAccountRange(t *testing.T) { st, _ = state.New(common.Hash{}, statedb, nil) ) st.Commit(true) - st.IntermediateRoot(true) + st.IntermediateRoot(context.Background(), true) results := st.IteratorDump(&state.DumpConfig{ SkipCode: true, SkipStorage: true, diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 08c17601e4..47a93c8f8d 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -544,7 +544,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config } // calling IntermediateRoot will internally call Finalize on the state // so any modifications are written to the trie - roots = append(roots, statedb.IntermediateRoot(deleteEmptyObjects)) + roots = append(roots, statedb.IntermediateRoot(context.Background(), deleteEmptyObjects)) } return roots, nil } diff --git a/eth/tracers/api_bor.go b/eth/tracers/api_bor.go index 6ab1a4290a..697abcb360 100644 --- a/eth/tracers/api_bor.go +++ b/eth/tracers/api_bor.go @@ -108,7 +108,7 @@ func (api *API) traceBorBlock(ctx context.Context, block *types.Block, config *T } res := &TxTraceResult{ Result: result, - IntermediateHash: statedb.IntermediateRoot(deleteEmptyObjects), + IntermediateHash: statedb.IntermediateRoot(context.Background(), deleteEmptyObjects), } return res diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 4fd3cf76b2..302e1866e0 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -17,6 +17,7 @@ package tests import ( + ctx "context" "encoding/hex" "encoding/json" "fmt" @@ -243,7 +244,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh // the coinbase gets no txfee, so isn't created, and thus needs to be touched statedb.AddBalance(block.Coinbase(), new(big.Int)) // And _now_ get the state root - root := statedb.IntermediateRoot(config.IsEIP158(block.Number())) + root := statedb.IntermediateRoot(ctx.Background(), config.IsEIP158(block.Number())) return snaps, statedb, root, nil } From acd192a44cbddaf4db9511269560db05a03b8b0b Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 12 Jul 2022 18:02:14 +0530 Subject: [PATCH 25/48] add traces in WriteBlockAndSetHead function, fix linters --- cmd/evm/internal/t8ntool/execution.go | 1 + core/blockchain.go | 99 +++++++++++++++++++++++++-- core/state/statedb.go | 5 ++ core/tests/blockchain_repair_test.go | 2 +- eth/ethconfig/config.go | 2 +- internal/cli/server/server.go | 4 +- miner/worker.go | 9 ++- tests/bor/helper.go | 2 +- 8 files changed, 110 insertions(+), 14 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 8d5272e83f..5581b972fb 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -224,6 +224,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, txIndex++ } + statedb.IntermediateRoot(context.Background(), chainConfig.IsEIP158(vmContext.BlockNumber)) // Add mining reward? if miningReward > 0 { diff --git a/core/blockchain.go b/core/blockchain.go index 8a4c581f66..6f0f6553b3 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -28,6 +28,9 @@ import ( "time" lru "github.com/hashicorp/golang-lru" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "golang.org/x/net/context" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/mclock" @@ -1205,7 +1208,8 @@ func (bc *BlockChain) writeKnownBlock(block *types.Block) error { // writeBlockWithState writes block, metadata and corresponding state data to the // database. -func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB) ([]*types.Log, error) { +//nolint:gocognit +func (bc *BlockChain) writeBlockWithState(ctx context.Context, block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB) ([]*types.Log, error) { // Calculate the total difficulty of the block ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) if ptd == nil { @@ -1214,15 +1218,32 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // Make sure no inconsistent state is leaked during insertion externTd := new(big.Int).Add(block.Difficulty(), ptd) + tracer := otel.GetTracerProvider().Tracer("MinerWorker") + + _, writeBlockWithStateSpan := tracer.Start(ctx, "writeBlockWithState") + defer writeBlockWithStateSpan.End() + // Irrelevant of the canonical status, write the block itself to the database. // // Note all the components of block(td, hash->number map, header, body, receipts) // should be written atomically. BlockBatch is used for containing all components. blockBatch := bc.db.NewBatch() + + writeTdStart := time.Now() rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd) + + writeTdTime := time.Since(writeTdStart) + + writeBlockStart := time.Now() rawdb.WriteBlock(blockBatch, block) + + writeBlockTime := time.Since(writeBlockStart) + + writeReceiptsStart := time.Now() rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts) + writeReceiptsTime := time.Since(writeReceiptsStart) + // System call appends state-sync logs into state. So, `state.Logs()` contains // all logs including system-call logs (state sync logs) while `logs` contains // only logs generated by transactions (receipts). @@ -1233,6 +1254,10 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // block logs = receipt logs + state sync logs = `state.Logs()` blockLogs := state.Logs() var stateSyncLogs []*types.Log + + writeBorReceiptStart := time.Now() + writeBorReceiptTime := time.Since(writeBorReceiptStart) + borLogs := false if len(blockLogs) > 0 { sort.SliceStable(blockLogs, func(i, j int) bool { return blockLogs[i].Index < blockLogs[j].Index @@ -1253,19 +1278,32 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // Write bor tx reverse lookup rawdb.WriteBorTxLookupEntry(blockBatch, block.Hash(), block.NumberU64()) + + writeBorReceiptTime = time.Since(writeBorReceiptStart) + borLogs = true } } + writePreimagesStart := time.Now() rawdb.WritePreimages(blockBatch, state.Preimages()) if err := blockBatch.Write(); err != nil { log.Crit("Failed to write block into disk", "err", err) } + + writePreimagesTime := time.Since(writePreimagesStart) + // Commit all cached state changes into underlying memory database. + commitCacheStart := time.Now() root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) if err != nil { return []*types.Log{}, err } triedb := bc.stateCache.TrieDB() + commitCacheTime := time.Since(commitCacheStart) + + garbageCollectionStart := time.Now() + garbageCollectionTime := time.Since(garbageCollectionStart) //nolint:staticcheck + garbageCollected := false // If we're running an archive node, always flush if bc.cacheConfig.TrieDirtyDisabled { @@ -1316,39 +1354,73 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. triedb.Dereference(root.(common.Hash)) } } + + garbageCollectionTime = time.Since(garbageCollectionStart) + garbageCollected = true } + + writeBlockWithStateSpan.SetAttributes( + attribute.Int("number", int(block.NumberU64())), + attribute.String("hash", block.Hash().String()), + attribute.Int("write total difficulty time", int(writeTdTime.Milliseconds())), + attribute.Int("write block time", int(writeBlockTime.Milliseconds())), + attribute.Int("write receipts time", int(writeReceiptsTime.Milliseconds())), + attribute.Bool("bor receipts present?", borLogs), + attribute.Int("write bor receipts time", int(writeBorReceiptTime.Milliseconds())), + attribute.Int("write preimage time", int(writePreimagesTime.Milliseconds())), + attribute.Int("commit cache time", int(commitCacheTime.Milliseconds())), + attribute.Bool("garbage collected?", garbageCollected), + attribute.Int("garbage collection time", int(garbageCollectionTime.Milliseconds())), + ) + return stateSyncLogs, nil } // WriteBlockWithState writes the block and all associated state to the database. -func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) { +func (bc *BlockChain) WriteBlockAndSetHead(ctx context.Context, 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) + return bc.writeBlockAndSetHead(ctx, block, receipts, logs, state, emitHeadEvent) } // writeBlockAndSetHead writes the block and all associated state to the database, // and also it applies the given block as the new chain head. 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) (status WriteStatus, err error) { +func (bc *BlockChain) writeBlockAndSetHead(ctx context.Context, block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) { var stateSyncLogs []*types.Log - if stateSyncLogs, err = bc.writeBlockWithState(block, receipts, logs, state); err != nil { + + tracer := otel.GetTracerProvider().Tracer("MinerWorker") + + _, writeBlockAndSetHeadSpan := tracer.Start(ctx, "writeBlockAndSetHead") + defer writeBlockAndSetHeadSpan.End() + + writeBlockWithStateStart := time.Now() + + if stateSyncLogs, err = bc.writeBlockWithState(ctx, block, receipts, logs, state); err != nil { return NonStatTy, err } + + writeBlockWithStateTime := time.Since(writeBlockWithStateStart) + currentBlock := bc.CurrentBlock() reorg, err := bc.forker.ReorgNeeded(currentBlock.Header(), block.Header()) if err != nil { return NonStatTy, err } + + reorgStart := time.Now() + reorgTime := time.Since(reorgStart) if reorg { // Reorganise the chain if the parent is not the head block if block.ParentHash() != currentBlock.Hash() { if err := bc.reorg(currentBlock, block); err != nil { return NonStatTy, err } + + reorgTime = time.Since(reorgStart) } status = CanonStatTy } else { @@ -1360,6 +1432,7 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types } bc.futureBlocks.Remove(block.Hash()) + sendEventStart := time.Now() if status == CanonStatTy { bc.chainFeed.Send(ChainEvent{Block: block, Hash: block.Hash(), Logs: logs}) if len(logs) > 0 { @@ -1392,6 +1465,18 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types NewChain: []*types.Block{block}, }) } + + sendEventTime := time.Since(sendEventStart) + + writeBlockAndSetHeadSpan.SetAttributes( + attribute.Int("number", int(block.NumberU64())), + attribute.String("hash", block.Hash().String()), + attribute.Int("write block with state time", int(writeBlockWithStateTime.Milliseconds())), + attribute.Bool("reorg", reorg), + attribute.Int("reorg time", int(reorgTime.Milliseconds())), + attribute.Int("send events time", int(sendEventTime.Milliseconds())), + ) + return status, nil } @@ -1735,9 +1820,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) var status WriteStatus if !setHead { // Don't set the head, only insert the block - _, err = bc.writeBlockWithState(block, receipts, logs, statedb) + _, err = bc.writeBlockWithState(context.Background(), block, receipts, logs, statedb) } else { - status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false) + status, err = bc.writeBlockAndSetHead(context.Background(), block, receipts, logs, statedb, false) } atomic.StoreUint32(&followupInterrupt, 1) if err != nil { diff --git a/core/state/statedb.go b/core/state/statedb.go index 9b6f37c3a6..dd8e135da2 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" ) @@ -832,6 +833,7 @@ func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) // Finalise all the dirty storage states and write them into the tries finalizeStart := time.Now() s.Finalise(deleteEmptyObjects) + finalizeTime := time.Since(finalizeStart) // If there was a trie prefetcher operating, it gets aborted and irrevocably @@ -862,6 +864,7 @@ func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) updated++ } } + updateRootTime := time.Since(updateRootStart) // Now we're about to start to write changes to the trie. The trie is so far @@ -873,6 +876,7 @@ func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) s.trie = trie } } + trieFetchTime := time.Since(trieFetchStart) stateIterationStart := time.Now() @@ -890,6 +894,7 @@ func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure iterations++ } + stateIterationTime := time.Since(stateIterationStart) if prefetcher != nil { diff --git a/core/tests/blockchain_repair_test.go b/core/tests/blockchain_repair_test.go index 8e86e4721d..cd2da5c3a3 100644 --- a/core/tests/blockchain_repair_test.go +++ b/core/tests/blockchain_repair_test.go @@ -39,7 +39,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/miner" //nolint:typecheck "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/tests/bor/mocks" ) diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 091600d8b5..d51e293413 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -30,7 +30,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/beacon" "github.com/ethereum/go-ethereum/consensus/bor" "github.com/ethereum/go-ethereum/consensus/bor/contract" - "github.com/ethereum/go-ethereum/consensus/bor/heimdall" + "github.com/ethereum/go-ethereum/consensus/bor/heimdall" //nolint:typecheck "github.com/ethereum/go-ethereum/consensus/bor/heimdall/span" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" diff --git a/internal/cli/server/server.go b/internal/cli/server/server.go index 7d5ec2c8f3..de196a1220 100644 --- a/internal/cli/server/server.go +++ b/internal/cli/server/server.go @@ -23,8 +23,8 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/consensus/beacon" - "github.com/ethereum/go-ethereum/consensus/bor" + "github.com/ethereum/go-ethereum/consensus/beacon" //nolint:typecheck + "github.com/ethereum/go-ethereum/consensus/bor" //nolint:typecheck "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/tracers" diff --git a/miner/worker.go b/miner/worker.go index f8fcc59c16..ea0ba96d75 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -740,7 +740,7 @@ func (w *worker) resultLoop() { w.pendingMu.RLock() task, exist := w.pendingTasks[sealhash] w.pendingMu.RUnlock() - _, resultLoopSpan := w.tracer.Start(task.ctx, "resultLoop") + resultLoopCtx, resultLoopSpan := w.tracer.Start(task.ctx, "resultLoop") if !exist { log.Error("Block found but no relative pending task", "number", block.Number(), "sealhash", sealhash, "hash", hash) continue @@ -773,7 +773,7 @@ func (w *worker) resultLoop() { } // Commit block and state to database. writeBlockStart := time.Now() - _, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true) + _, err := w.chain.WriteBlockAndSetHead(resultLoopCtx, block, receipts, logs, task.state, true) writeBlockTime := time.Since(writeBlockStart) resultLoopSpan.SetAttributes( attribute.String("hash", hash.String()), @@ -1126,6 +1126,7 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en localTxs[account] = txs } } + splittingTransactionsSpan.SetAttributes( attribute.Int("LocalTx Len", len(localTxs)), attribute.Int("RemoteTx Len", len(remoteTxs)), @@ -1142,12 +1143,14 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en attribute.Int("len of tx Heads", txs.GetTxs()), ) transactionsByPriceAndNonceSpan.End() + lenNewLocals = txs.GetTxs() _, commitTransactionsSpan := w.tracer.Start(fillTxCtx, "LocalCommitTransactions") if w.commitTransactions(env, txs, interrupt) { return } + commitTransactionsSpan.SetAttributes( attribute.Int("len of tx Heads", txs.GetTxs()), ) @@ -1163,12 +1166,14 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en attribute.Int("len of tx Heads", txs.GetTxs()), ) TransactionsByPriceAndNonceSpan.End() + lenNewRemotes = txs.GetTxs() _, CommitTransactionsSpan := w.tracer.Start(fillTxCtx, "RemoteCommitTransactions") if w.commitTransactions(env, txs, interrupt) { return } + CommitTransactionsSpan.SetAttributes( attribute.Int("len of tx Heads", txs.GetTxs()), ) diff --git a/tests/bor/helper.go b/tests/bor/helper.go index cc2e156aa9..fb2e8e541a 100644 --- a/tests/bor/helper.go +++ b/tests/bor/helper.go @@ -12,7 +12,7 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/bor" - "github.com/ethereum/go-ethereum/consensus/bor/heimdall" + "github.com/ethereum/go-ethereum/consensus/bor/heimdall" //nolint:typecheck "github.com/ethereum/go-ethereum/consensus/bor/heimdall/span" "github.com/ethereum/go-ethereum/consensus/bor/valset" "github.com/ethereum/go-ethereum/consensus/misc" From 15521675337b62a38ed6621184bc2d1fc0a3e6f3 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Fri, 15 Jul 2022 10:40:54 +0530 Subject: [PATCH 26/48] fix: linting errors --- consensus/bor/bor.go | 1 - 1 file changed, 1 deletion(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index d9f3d566ab..e23018c5aa 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -724,7 +724,6 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, headerNumber := header.Number.Uint64() if IsSprintStart(headerNumber, c.config.Sprint) { - cx := statefull.ChainContext{Chain: chain, Bor: c} // check and commit span if err := c.checkAndCommitSpan(context.Background(), nil, state, header, cx); err != nil { From b5dfe09e2e82f35f7d29d6baf8baf468a222108d Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Fri, 15 Jul 2022 11:21:30 +0530 Subject: [PATCH 27/48] fix: test cases --- tests/bor/helper.go | 5 +++-- tests/state_test.go | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/bor/helper.go b/tests/bor/helper.go index bdddb34b6d..f4b7321cc3 100644 --- a/tests/bor/helper.go +++ b/tests/bor/helper.go @@ -3,6 +3,7 @@ package bor import ( + "context" "encoding/hex" "encoding/json" "fmt" @@ -173,7 +174,7 @@ func buildNextBlock(t *testing.T, _bor consensus.Engine, chain *core.BlockChain, } // Finalize and seal the block - block, _ := _bor.FinalizeAndAssemble(chain, b.header, state, b.txs, nil, b.receipts) + block, _ := _bor.FinalizeAndAssemble(context.Background(), chain, b.header, state, b.txs, nil, b.receipts) // Write state changes to db root, err := state.Commit(chain.Config().IsEIP158(b.header.Number)) @@ -187,7 +188,7 @@ func buildNextBlock(t *testing.T, _bor consensus.Engine, chain *core.BlockChain, res := make(chan *types.Block, 1) - err = _bor.Seal(chain, block, res, nil) + err = _bor.Seal(context.Background(), chain, block, res, nil) if err != nil { // an error case - sign manually sign(t, header, signer, borConfig) diff --git a/tests/state_test.go b/tests/state_test.go index 1e7171ee20..c84e5356a0 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -22,6 +22,7 @@ package tests import ( "bufio" "bytes" + "context" "fmt" "math/big" "os" @@ -150,7 +151,7 @@ func TestState(t *testing.T) { withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { snaps, statedb, err := test.Run(subtest, vmconfig, true) if snaps != nil && statedb != nil { - if _, err := snaps.Journal(statedb.IntermediateRoot(false)); err != nil { + if _, err := snaps.Journal(context.Background(), statedb.IntermediateRoot(false)); err != nil { t.Errorf("in 'rlp_test.go', test '%s' failed with error: '%v'", name, err) return err } From 95066305f9f3a8b020cf208bda1af1b96576fd3e Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Fri, 15 Jul 2022 11:22:55 +0530 Subject: [PATCH 28/48] fix: go.mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 3a4eba29ef..c928db746a 100644 --- a/go.mod +++ b/go.mod @@ -130,7 +130,7 @@ require ( go.opentelemetry.io/otel/trace v1.2.0 go.opentelemetry.io/proto/otlp v0.10.0 // indirect golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect From 6f78f620d05758cbc1df076d34cf8472c412305a Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Fri, 15 Jul 2022 14:45:03 +0530 Subject: [PATCH 29/48] fix: testcase --- tests/state_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/state_test.go b/tests/state_test.go index c84e5356a0..e4be1cc56e 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -151,7 +151,7 @@ func TestState(t *testing.T) { withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { snaps, statedb, err := test.Run(subtest, vmconfig, true) if snaps != nil && statedb != nil { - if _, err := snaps.Journal(context.Background(), statedb.IntermediateRoot(false)); err != nil { + if _, err := snaps.Journal(statedb.IntermediateRoot(context.Background(), false)); err != nil { t.Errorf("in 'rlp_test.go', test '%s' failed with error: '%v'", name, err) return err } From b29e3008d4e8000f59ad5b0901b408515f2e2f98 Mon Sep 17 00:00:00 2001 From: Evgeny Danienko <6655321@bk.ru> Date: Tue, 19 Jul 2022 15:48:10 +0300 Subject: [PATCH 30/48] extract tracing package --- cmd/evm/staterunner.go | 3 +- common/tracing/context.go | 81 +++++++ consensus/bor/bor.go | 8 +- consensus/bor/validators_getter.go | 11 - consensus/bor/validators_getter_mock.go | 51 ----- miner/worker.go | 289 ++++++++++++++---------- tests/bor/helper.go | 6 +- tests/state_test.go | 2 +- tests/state_test_util.go | 19 +- 9 files changed, 272 insertions(+), 198 deletions(-) create mode 100644 common/tracing/context.go delete mode 100644 consensus/bor/validators_getter.go delete mode 100644 consensus/bor/validators_getter_mock.go diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 46c959a7c4..23f2a2c378 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -96,6 +96,7 @@ func stateTestCmd(ctx *cli.Context) error { Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name), } results := make([]StatetestResult, 0, len(tests)) + ctxGo := context.Background() for key, test := range tests { for _, st := range test.Subtests() { // Run the test and aggregate the result @@ -103,7 +104,7 @@ func stateTestCmd(ctx *cli.Context) error { _, s, err := test.Run(st, cfg, false) // print state root for evmlab tracing if ctx.GlobalBool(MachineFlag.Name) && s != nil { - fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", s.IntermediateRoot(context.Background(), false)) + fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", s.IntermediateRoot(ctxGo, false)) } if err != nil { // Test failed, mark as so and dump any state to aid debugging diff --git a/common/tracing/context.go b/common/tracing/context.go new file mode 100644 index 0000000000..f98404e8ad --- /dev/null +++ b/common/tracing/context.go @@ -0,0 +1,81 @@ +package tracing + +import ( + "context" + "time" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" +) + +type tracerKey struct{} + +type Option func(context.Context, trace.Span) + +func WithTracer(ctx context.Context, tr trace.Tracer) context.Context { + return context.WithValue(ctx, tracerKey{}, tr) +} + +func FromContext(ctx context.Context) trace.Tracer { + tr, _ := ctx.Value(tracerKey{}).(trace.Tracer) + + return tr +} + +func StartSpan(ctx context.Context, snapName string) (context.Context, trace.Span) { + tr := FromContext(ctx) + ctx, span := tr.Start(ctx, snapName) + ctx = WithTracer(ctx, tr) + + return ctx, span +} + +func Trace(ctx context.Context, spanName string) (context.Context, trace.Span) { + tr := FromContext(ctx) + + if tr == nil { + return ctx, nil + } + + return tr.Start(ctx, spanName) +} + +func Exec(ctx context.Context, spanName string, opts ...Option) { + var span trace.Span + + tr := FromContext(ctx) + + if tr != nil { + ctx, span = tr.Start(ctx, spanName) + } + + for _, optFn := range opts { + optFn(ctx, span) + } + + if tr != nil { + span.End() + } + + return +} + +func WithTime(fn func(context.Context, trace.Span)) Option { + return func(ctx context.Context, span trace.Span) { + ElapsedTime(ctx, span, "elapsed", fn) + } +} + +func ElapsedTime(ctx context.Context, span trace.Span, msg string, fn func(context.Context, trace.Span)) { + var now time.Time + + if span != nil { + now = time.Now() + } + + fn(ctx, span) + + if span != nil { + span.SetAttributes(attribute.Int(msg, int(time.Since(now).Milliseconds()))) + } +} diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index e23018c5aa..10d819cd55 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -723,17 +723,19 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, headerNumber := header.Number.Uint64() + ctx := context.Background() + if IsSprintStart(headerNumber, c.config.Sprint) { cx := statefull.ChainContext{Chain: chain, Bor: c} // check and commit span - if err := c.checkAndCommitSpan(context.Background(), nil, state, header, cx); err != nil { + if err := c.checkAndCommitSpan(ctx, nil, state, header, cx); err != nil { log.Error("Error while committing span", "error", err) return } if c.HeimdallClient != nil { // commit statees - stateSyncData, err = c.CommitStates(context.Background(), nil, state, header, cx) + stateSyncData, err = c.CommitStates(ctx, nil, state, header, cx) if err != nil { log.Error("Error while committing states", "error", err) return @@ -747,7 +749,7 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, } // No block rewards in PoA, so the state remains as is and uncles are dropped - header.Root = state.IntermediateRoot(context.Background(), chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(ctx, chain.Config().IsEIP158(header.Number)) header.UncleHash = types.CalcUncleHash(nil) // Set state sync data to blockchain diff --git a/consensus/bor/validators_getter.go b/consensus/bor/validators_getter.go deleted file mode 100644 index 90d1fccf6e..0000000000 --- a/consensus/bor/validators_getter.go +++ /dev/null @@ -1,11 +0,0 @@ -package bor - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/bor/valset" -) - -//go:generate mockgen -destination=./validators_getter_mock.go -package=bor . ValidatorsGetter -type ValidatorsGetter interface { - GetCurrentValidators(headerHash common.Hash, blockNumber uint64) ([]*valset.Validator, error) -} diff --git a/consensus/bor/validators_getter_mock.go b/consensus/bor/validators_getter_mock.go deleted file mode 100644 index ad99489d8e..0000000000 --- a/consensus/bor/validators_getter_mock.go +++ /dev/null @@ -1,51 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ethereum/go-ethereum/consensus/bor (interfaces: ValidatorsGetter) - -// Package bor is a generated GoMock package. -package bor - -import ( - reflect "reflect" - - common "github.com/ethereum/go-ethereum/common" - valset "github.com/ethereum/go-ethereum/consensus/bor/valset" - gomock "github.com/golang/mock/gomock" -) - -// MockValidatorsGetter is a mock of ValidatorsGetter interface. -type MockValidatorsGetter struct { - ctrl *gomock.Controller - recorder *MockValidatorsGetterMockRecorder -} - -// MockValidatorsGetterMockRecorder is the mock recorder for MockValidatorsGetter. -type MockValidatorsGetterMockRecorder struct { - mock *MockValidatorsGetter -} - -// NewMockValidatorsGetter creates a new mock instance. -func NewMockValidatorsGetter(ctrl *gomock.Controller) *MockValidatorsGetter { - mock := &MockValidatorsGetter{ctrl: ctrl} - mock.recorder = &MockValidatorsGetterMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockValidatorsGetter) EXPECT() *MockValidatorsGetterMockRecorder { - return m.recorder -} - -// GetCurrentValidators mocks base method. -func (m *MockValidatorsGetter) GetCurrentValidators(arg0 common.Hash, arg1 uint64) ([]*valset.Validator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidators", arg0, arg1) - ret0, _ := ret[0].([]*valset.Validator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentValidators indicates an expected call of GetCurrentValidators. -func (mr *MockValidatorsGetterMockRecorder) GetCurrentValidators(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidators", reflect.TypeOf((*MockValidatorsGetter)(nil).GetCurrentValidators), arg0, arg1) -} diff --git a/miner/worker.go b/miner/worker.go index ea0ba96d75..3f17c30ef4 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -31,6 +31,7 @@ import ( "go.opentelemetry.io/otel/trace" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/tracing" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core" @@ -256,9 +257,6 @@ type worker struct { skipSealHook func(*task) bool // Method to decide whether skipping the sealing. fullTaskHook func() // Method to call before pushing the full sealing task. resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval. - - tracer trace.Tracer - span trace.Span } //nolint:staticcheck @@ -286,7 +284,6 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus startCh: make(chan struct{}, 1), resubmitIntervalCh: make(chan time.Duration), resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize), - tracer: otel.GetTracerProvider().Tracer("MinerWorker"), } // Subscribe NewTxsEvent for tx pool worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh) @@ -301,12 +298,11 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus recommit = minRecommitInterval } - newWorkerCtx, newWorkSpan := worker.tracer.Start(context.Background(), "newWorker") - worker.span = newWorkSpan + ctx := tracing.WithTracer(context.Background(), otel.GetTracerProvider().Tracer("MinerWorker")) worker.wg.Add(4) - go worker.mainLoop() - go worker.newWorkLoop(newWorkerCtx, recommit) + go worker.mainLoop(ctx) + go worker.newWorkLoop(ctx, recommit) go worker.resultLoop() go worker.taskLoop() @@ -404,7 +400,6 @@ func (w *worker) close() { atomic.StoreInt32(&w.running, 0) close(w.exitCh) w.wg.Wait() - w.span.End() } // recalcRecommit recalculates the resubmitting interval upon feedback. @@ -452,6 +447,10 @@ func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { // commit aborts in-flight transaction execution with given signal and resubmits a new one. commit := func(noempty bool, s int32) { + // we close spans only by the place we created them + ctx, span := tracing.Trace(ctx, "worker.commit") + defer span.End() + if interrupt != nil { atomic.StoreInt32(interrupt, s) } @@ -466,6 +465,9 @@ func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { } // clearPending cleans the stale pending tasks. clearPending := func(number uint64) { + _, span := tracing.Trace(ctx, "worker.clearPending") + defer span.End() + w.pendingMu.Lock() for h, t := range w.pendingTasks { if t.block.NumberU64()+staleThreshold <= number { @@ -538,7 +540,7 @@ func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { // mainLoop is responsible for generating and submitting sealing work based on // the received event. It can support two modes: automatically generate task and // submit it or return task according to given parameters for various proposes. -func (w *worker) mainLoop() { +func (w *worker) mainLoop(ctx context.Context) { defer w.wg.Done() defer w.txsSub.Unsubscribe() defer w.chainHeadSub.Unsubscribe() @@ -586,7 +588,7 @@ func (w *worker) mainLoop() { if w.isRunning() && w.current != nil && len(w.current.uncles) < 2 { start := time.Now() if err := w.commitUncle(w.current, ev.Block.Header()); err == nil { - commitErr := w.commit(context.Background(), w.current.copy(), nil, true, start) + commitErr := w.commit(ctx, w.current.copy(), nil, true, start) if commitErr != nil { log.Error("error while committing", commitErr) } @@ -636,7 +638,7 @@ func (w *worker) mainLoop() { // submit sealing work here since all empty submission will be rejected // by clique. Of course the advance sealing(empty submission) is disabled. if w.chainConfig.Clique != nil && w.chainConfig.Clique.Period == 0 { - w.commitWork(context.Background(), nil, true, time.Now().Unix()) + w.commitWork(ctx, nil, true, time.Now().Unix()) } } atomic.AddInt32(&w.newTxs, int32(len(ev.Txs))) @@ -716,12 +718,12 @@ func (w *worker) resultLoop() { if block == nil { continue } + // Short circuit when receiving duplicate result caused by resubmitting. if w.chain.HasBlock(block.Hash(), block.NumberU64()) { continue } - getBlockStart := time.Now() oldBlock := w.chain.GetBlockByNumber(block.NumberU64()) if oldBlock != nil { oldBlockAuthor, _ := w.chain.Engine().Author(oldBlock.Header()) @@ -732,65 +734,72 @@ func (w *worker) resultLoop() { } } - getBlockTime := time.Since(getBlockStart) var ( sealhash = w.engine.SealHash(block.Header()) hash = block.Hash() ) + w.pendingMu.RLock() task, exist := w.pendingTasks[sealhash] w.pendingMu.RUnlock() - resultLoopCtx, resultLoopSpan := w.tracer.Start(task.ctx, "resultLoop") + if !exist { log.Error("Block found but no relative pending task", "number", block.Number(), "sealhash", sealhash, "hash", hash) continue } + // Different block could share same sealhash, deep copy here to prevent write-write conflict. var ( receipts = make([]*types.Receipt, len(task.receipts)) logs []*types.Log + err error ) - for i, taskReceipt := range task.receipts { - receipt := new(types.Receipt) - receipts[i] = receipt - *receipt = *taskReceipt - - // add block location fields - receipt.BlockHash = hash - receipt.BlockNumber = block.Number() - receipt.TransactionIndex = uint(i) - - // Update the block hash in all logs since it is now available and not when the - // receipt/log of individual transactions were created. - receipt.Logs = make([]*types.Log, len(taskReceipt.Logs)) - for i, taskLog := range taskReceipt.Logs { - log := new(types.Log) - receipt.Logs[i] = log - *log = *taskLog - log.BlockHash = hash + + tracing.Exec(task.ctx, "resultLoop", func(ctx context.Context, span trace.Span) { + for i, taskReceipt := range task.receipts { + receipt := new(types.Receipt) + receipts[i] = receipt + *receipt = *taskReceipt + + // add block location fields + receipt.BlockHash = hash + receipt.BlockNumber = block.Number() + receipt.TransactionIndex = uint(i) + + // Update the block hash in all logs since it is now available and not when the + // receipt/log of individual transactions were created. + receipt.Logs = make([]*types.Log, len(taskReceipt.Logs)) + for i, taskLog := range taskReceipt.Logs { + log := new(types.Log) + receipt.Logs[i] = log + *log = *taskLog + log.BlockHash = hash + } + logs = append(logs, receipt.Logs...) } - logs = append(logs, receipt.Logs...) - } - // Commit block and state to database. - writeBlockStart := time.Now() - _, err := w.chain.WriteBlockAndSetHead(resultLoopCtx, block, receipts, logs, task.state, true) - writeBlockTime := time.Since(writeBlockStart) - resultLoopSpan.SetAttributes( - attribute.String("hash", hash.String()), - attribute.Int("number", int(block.Number().Uint64())), - attribute.Int("txns", block.Transactions().Len()), - attribute.Int("gas used", int(block.GasUsed())), - attribute.Int("Block fetch and check time taken", int(getBlockTime.Milliseconds())), - attribute.Int("WriteBlockAndSetHead time taken", int(writeBlockTime.Milliseconds())), - attribute.Int("elapsed", int(time.Since(task.createdAt).Milliseconds())), - attribute.Bool("error", err != nil), - ) - resultLoopSpan.End() + + // Commit block and state to database. + tracing.ElapsedTime(ctx, span, "WriteBlockAndSetHead time taken", func(ctx context.Context, span trace.Span) { + + _, err = w.chain.WriteBlockAndSetHead(ctx, block, receipts, logs, task.state, true) + + }) + + span.SetAttributes( + attribute.String("hash", hash.String()), + attribute.Int("number", int(block.Number().Uint64())), + attribute.Int("txns", block.Transactions().Len()), + attribute.Int("gas used", int(block.GasUsed())), + attribute.Int("elapsed", int(time.Since(task.createdAt).Milliseconds())), + attribute.Bool("error", err != nil), + ) + }) if err != nil { log.Error("Failed writing block to chain", "err", err) continue } + log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash, "elapsed", common.PrettyDuration(time.Since(task.createdAt))) @@ -1110,79 +1119,98 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { // into the given sealing block. The transaction selection and ordering strategy can // be customized with the plugin in the future. func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *environment) { - fillTxCtx, fillTransactionsSpan := w.tracer.Start(ctx, "fillTransactions") - defer fillTransactionsSpan.End() + ctx, span := tracing.StartSpan(ctx, "fillTransactions") + defer span.End() // Split the pending transactions into locals and remotes // Fill the block with all available pending transactions. - _, splittingTransactionsSpan := w.tracer.Start(fillTxCtx, "SplittingTransactions") + var ( + localTxsCount int + remoteTxsCount int + localTxs = make(map[common.Address]types.Transactions) + remoteTxs map[common.Address]types.Transactions + ) + + tracing.Exec(ctx, "worker.SplittingTransactions", func(ctx context.Context, span trace.Span) { + pending := w.eth.TxPool().Pending(true) + remoteTxs = pending - pending := w.eth.TxPool().Pending(true) - localTxs, remoteTxs := make(map[common.Address]types.Transactions), pending - for _, account := range w.eth.TxPool().Locals() { - if txs := remoteTxs[account]; len(txs) > 0 { - delete(remoteTxs, account) - localTxs[account] = txs + for _, account := range w.eth.TxPool().Locals() { + if txs := remoteTxs[account]; len(txs) > 0 { + delete(remoteTxs, account) + localTxs[account] = txs + } } - } - splittingTransactionsSpan.SetAttributes( - attribute.Int("LocalTx Len", len(localTxs)), - attribute.Int("RemoteTx Len", len(remoteTxs)), - ) - splittingTransactionsSpan.End() + localTxsCount = len(localTxs) + remoteTxsCount = len(remoteTxs) + + span.SetAttributes( + attribute.Int("LocalTx Len", localTxsCount), + attribute.Int("RemoteTx Len", remoteTxsCount), + ) + }) lenLocals, lenNewLocals, localEnvTCount, lenRemotes, lenNewRemotes, remoteEnvTCount := 0, 0, 0, 0, 0, 0 - if len(localTxs) > 0 { - lenLocals = len(localTxs) - _, transactionsByPriceAndNonceSpan := w.tracer.Start(fillTxCtx, "LocalTransactionsByPriceAndNonce") - txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) - transactionsByPriceAndNonceSpan.SetAttributes( - attribute.Int("len of tx Heads", txs.GetTxs()), - ) - transactionsByPriceAndNonceSpan.End() + var committed bool + + if localTxsCount > 0 { + var txs *types.TransactionsByPriceAndNonce + + tracing.Exec(ctx, "worker.LocalTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) { + txs = types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) + + span.SetAttributes( + attribute.Int("len of tx Heads", txs.GetTxs()), + ) + }) lenNewLocals = txs.GetTxs() - _, commitTransactionsSpan := w.tracer.Start(fillTxCtx, "LocalCommitTransactions") - if w.commitTransactions(env, txs, interrupt) { + tracing.Exec(ctx, "worker.LocalCommitTransactions", func(ctx context.Context, span trace.Span) { + committed = w.commitTransactions(env, txs, interrupt) + }) + + if committed { return } - commitTransactionsSpan.SetAttributes( - attribute.Int("len of tx Heads", txs.GetTxs()), - ) - commitTransactionsSpan.End() - localEnvTCount = env.tcount } - if len(remoteTxs) > 0 { - lenRemotes = len(remoteTxs) - _, TransactionsByPriceAndNonceSpan := w.tracer.Start(fillTxCtx, "RemoteTransactionsByPriceAndNonce") - txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) - TransactionsByPriceAndNonceSpan.SetAttributes( - attribute.Int("len of tx Heads", txs.GetTxs()), - ) - TransactionsByPriceAndNonceSpan.End() + + if remoteTxsCount > 0 { + var txs *types.TransactionsByPriceAndNonce + + tracing.Exec(ctx, "worker.RemoteTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) { + txs = types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) + + span.SetAttributes( + attribute.Int("len of tx Heads", txs.GetTxs()), + ) + }) lenNewRemotes = txs.GetTxs() - _, CommitTransactionsSpan := w.tracer.Start(fillTxCtx, "RemoteCommitTransactions") - if w.commitTransactions(env, txs, interrupt) { + tracing.Exec(ctx, "worker.RemoteCommitTransactions", func(ctx context.Context, span trace.Span) { + txs = types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) + + committed = w.commitTransactions(env, txs, interrupt) + + span.SetAttributes( + attribute.Int("len of tx Heads", txs.GetTxs()), + ) + }) + + if committed { return } - CommitTransactionsSpan.SetAttributes( - attribute.Int("len of tx Heads", txs.GetTxs()), - ) - CommitTransactionsSpan.End() - remoteEnvTCount = env.tcount } - fillTransactionsSpan.SetAttributes( + span.SetAttributes( attribute.Int("len of localTxs", lenLocals), attribute.Int("len of sorted localTxs", lenNewLocals), attribute.Int("len of final localTxs ", localEnvTCount), @@ -1210,42 +1238,53 @@ func (w *worker) generateWork(ctx context.Context, params *generateParams) (*typ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, timestamp int64) { start := time.Now() - // Set the coinbase if the worker is running or it's required - var coinbase common.Address - if w.isRunning() { - if w.coinbase == (common.Address{}) { - log.Error("Refusing to mine without etherbase") - return + var ( + work *environment + err error + ) + + tracing.Exec(ctx, "worker.prepareWork", func(ctx context.Context, span trace.Span) { + // Set the coinbase if the worker is running or it's required + var coinbase common.Address + if w.isRunning() { + if w.coinbase == (common.Address{}) { + log.Error("Refusing to mine without etherbase") + return + } + + coinbase = w.coinbase // Use the preset address as the fee recipient } - coinbase = w.coinbase // Use the preset address as the fee recipient - } - work, err := w.prepareWork(&generateParams{ - timestamp: uint64(timestamp), - coinbase: coinbase, + + work, err = w.prepareWork(&generateParams{ + timestamp: uint64(timestamp), + coinbase: coinbase, + }) }) + if err != nil { return } - commitWorkCtx, commitWorkSpan := w.tracer.Start(ctx, "commitWork") - defer commitWorkSpan.End() + ctx, span := tracing.StartSpan(ctx, "commitWork") + defer span.End() - commitWorkSpan.SetAttributes( + span.SetAttributes( attribute.Int("number", int(work.header.Number.Uint64())), ) // Create an empty block based on temporary copied state for // sealing in advance without waiting block execution finished. if !noempty && atomic.LoadUint32(&w.noempty) == 0 { - err = w.commit(commitWorkCtx, work.copy(), nil, false, start) + err = w.commit(ctx, work.copy(), nil, false, start) if err != nil { return } } + // Fill pending transactions from the txpool - w.fillTransactions(commitWorkCtx, interrupt, work) + w.fillTransactions(ctx, interrupt, work) - err = w.commit(commitWorkCtx, work.copy(), w.fullTaskHook, true, start) + err = w.commit(ctx, work.copy(), w.fullTaskHook, true, start) if err != nil { return } @@ -1255,8 +1294,8 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, if w.current != nil { w.current.discard() } - w.current = work + w.current = work } // commit runs any post-transaction state modifications, assembles the final block @@ -1265,29 +1304,35 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, // the deep copy first. func (w *worker) commit(ctx context.Context, env *environment, interval func(), update bool, start time.Time) error { if w.isRunning() { - commitCtx, commitSpan := w.tracer.Start(ctx, "commit") - defer commitSpan.End() + ctx, span := tracing.StartSpan(ctx, "commit") + defer span.End() + if interval != nil { interval() } + // Create a local environment copy, avoid the data race with snapshot state. // https://github.com/ethereum/go-ethereum/issues/24299 env := env.copy() - block, err := w.engine.FinalizeAndAssemble(commitCtx, w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts) - commitSpan.SetAttributes( + + block, err := w.engine.FinalizeAndAssemble(ctx, w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts) + + span.SetAttributes( attribute.Int("number", int(block.Number().Uint64())), attribute.String("hash", block.Hash().String()), attribute.String("sealhash", w.engine.SealHash(block.Header()).String()), attribute.Int("len of env.txs", len(env.txs)), attribute.Bool("error", err != nil), ) + if err != nil { return err } + // If we're post merge, just ignore if !w.isTTDReached(block.Header()) { select { - case w.taskCh <- &task{ctx: commitCtx, receipts: env.receipts, state: env.state, block: block, createdAt: time.Now()}: + case w.taskCh <- &task{ctx: ctx, receipts: env.receipts, state: env.state, block: block, createdAt: time.Now()}: w.unconfirmed.Shift(block.NumberU64() - 1) log.Info("Commit new sealing work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()), "uncles", len(env.uncles), "txs", env.tcount, @@ -1308,6 +1353,8 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), // getSealingBlock generates the sealing block based on the given parameters. func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase common.Address, random common.Hash) (*types.Block, error) { + ctx := tracing.WithTracer(context.Background(), otel.GetTracerProvider().Tracer("getSealingBlock")) + req := &getWorkReq{ params: &generateParams{ timestamp: timestamp, @@ -1319,14 +1366,16 @@ func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase noExtra: true, }, result: make(chan *types.Block, 1), - ctx: context.Background(), + ctx: ctx, } + select { case w.getWorkCh <- req: block := <-req.result if block == nil { return nil, req.err } + return block, nil case <-w.exitCh: return nil, errors.New("miner closed") diff --git a/tests/bor/helper.go b/tests/bor/helper.go index 53b2b50551..ddddc97572 100644 --- a/tests/bor/helper.go +++ b/tests/bor/helper.go @@ -173,8 +173,10 @@ func buildNextBlock(t *testing.T, _bor consensus.Engine, chain *core.BlockChain, b.addTxWithChain(chain, state, tx, addr) } + ctx := context.Background() + // Finalize and seal the block - block, _ := _bor.FinalizeAndAssemble(context.Background(), chain, b.header, state, b.txs, nil, b.receipts) + block, _ := _bor.FinalizeAndAssemble(ctx, chain, b.header, state, b.txs, nil, b.receipts) // Write state changes to db root, err := state.Commit(chain.Config().IsEIP158(b.header.Number)) @@ -188,7 +190,7 @@ func buildNextBlock(t *testing.T, _bor consensus.Engine, chain *core.BlockChain, res := make(chan *types.Block, 1) - err = _bor.Seal(context.Background(), chain, block, res, nil) + err = _bor.Seal(ctx, chain, block, res, nil) if err != nil { // an error case - sign manually sign(t, header, signer, borConfig) diff --git a/tests/state_test.go b/tests/state_test.go index c84e5356a0..e4be1cc56e 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -151,7 +151,7 @@ func TestState(t *testing.T) { withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { snaps, statedb, err := test.Run(subtest, vmconfig, true) if snaps != nil && statedb != nil { - if _, err := snaps.Journal(context.Background(), statedb.IntermediateRoot(false)); err != nil { + if _, err := snaps.Journal(statedb.IntermediateRoot(context.Background(), false)); err != nil { t.Errorf("in 'rlp_test.go', test '%s' failed with error: '%v'", name, err) return err } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 302e1866e0..b1f024cc92 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -17,7 +17,7 @@ package tests import ( - ctx "context" + "context" "encoding/hex" "encoding/json" "fmt" @@ -25,6 +25,8 @@ import ( "strconv" "strings" + "golang.org/x/crypto/sha3" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" @@ -38,7 +40,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // StateTest checks transaction processing without block context. @@ -218,15 +219,15 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh // Prepare the EVM. txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) - context.GetHash = vmTestBlockHash - context.BaseFee = baseFee + evmContext := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase) + evmContext.GetHash = vmTestBlockHash + evmContext.BaseFee = baseFee if t.json.Env.Random != nil { rnd := common.BigToHash(t.json.Env.Random) - context.Random = &rnd - context.Difficulty = big.NewInt(0) + evmContext.Random = &rnd + evmContext.Difficulty = big.NewInt(0) } - evm := vm.NewEVM(context, txContext, statedb, config, vmconfig) + evm := vm.NewEVM(evmContext, txContext, statedb, config, vmconfig) // Execute the message. snapshot := statedb.Snapshot() gaspool := new(core.GasPool) @@ -244,7 +245,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh // the coinbase gets no txfee, so isn't created, and thus needs to be touched statedb.AddBalance(block.Coinbase(), new(big.Int)) // And _now_ get the state root - root := statedb.IntermediateRoot(ctx.Background(), config.IsEIP158(block.Number())) + root := statedb.IntermediateRoot(context.Background(), config.IsEIP158(block.Number())) return snaps, statedb, root, nil } From 478a7e05100cc400b14caf1cbe3ec82df5c6ad86 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Tue, 16 Aug 2022 16:49:38 +0530 Subject: [PATCH 31/48] linters fix --- common/tracing/context.go | 2 -- miner/worker.go | 2 ++ tests/state_test_util.go | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/common/tracing/context.go b/common/tracing/context.go index f98404e8ad..4c9246c9df 100644 --- a/common/tracing/context.go +++ b/common/tracing/context.go @@ -56,8 +56,6 @@ func Exec(ctx context.Context, spanName string, opts ...Option) { if tr != nil { span.End() } - - return } func WithTime(fn func(context.Context, trace.Span)) Option { diff --git a/miner/worker.go b/miner/worker.go index 3f17c30ef4..b9ac283de9 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -301,6 +301,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus ctx := tracing.WithTracer(context.Background(), otel.GetTracerProvider().Tracer("MinerWorker")) worker.wg.Add(4) + go worker.mainLoop(ctx) go worker.newWorkLoop(ctx, recommit) go worker.resultLoop() @@ -540,6 +541,7 @@ func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { // mainLoop is responsible for generating and submitting sealing work based on // the received event. It can support two modes: automatically generate task and // submit it or return task according to given parameters for various proposes. +// nolint: gocognit func (w *worker) mainLoop(ctx context.Context) { defer w.wg.Done() defer w.txsSub.Unsubscribe() diff --git a/tests/state_test_util.go b/tests/state_test_util.go index b1f024cc92..4d118c20f9 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -227,6 +227,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh evmContext.Random = &rnd evmContext.Difficulty = big.NewInt(0) } + evm := vm.NewEVM(evmContext, txContext, statedb, config, vmconfig) // Execute the message. snapshot := statedb.Snapshot() From 2d68b7c7b1105080563a4e1a6949dabc10acaff8 Mon Sep 17 00:00:00 2001 From: Evgeny Danienko <6655321@bk.ru> Date: Wed, 17 Aug 2022 10:08:08 +0300 Subject: [PATCH 32/48] debug --- common/tracing/context.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/common/tracing/context.go b/common/tracing/context.go index 4c9246c9df..a140d9970f 100644 --- a/common/tracing/context.go +++ b/common/tracing/context.go @@ -17,7 +17,11 @@ func WithTracer(ctx context.Context, tr trace.Tracer) context.Context { } func FromContext(ctx context.Context) trace.Tracer { - tr, _ := ctx.Value(tracerKey{}).(trace.Tracer) + tr, ok := ctx.Value(tracerKey{}).(trace.Tracer) + + if !ok { + panic("nil tracer") + } return tr } @@ -47,6 +51,8 @@ func Exec(ctx context.Context, spanName string, opts ...Option) { if tr != nil { ctx, span = tr.Start(ctx, spanName) + } else { + panic("nil tracer") } for _, optFn := range opts { From 441a7655a221e819126a3dca7b5788d5275fd253 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Wed, 17 Aug 2022 13:41:09 +0530 Subject: [PATCH 33/48] Revert "debug" This reverts commit 2d68b7c7b1105080563a4e1a6949dabc10acaff8. --- common/tracing/context.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/common/tracing/context.go b/common/tracing/context.go index a140d9970f..4c9246c9df 100644 --- a/common/tracing/context.go +++ b/common/tracing/context.go @@ -17,11 +17,7 @@ func WithTracer(ctx context.Context, tr trace.Tracer) context.Context { } func FromContext(ctx context.Context) trace.Tracer { - tr, ok := ctx.Value(tracerKey{}).(trace.Tracer) - - if !ok { - panic("nil tracer") - } + tr, _ := ctx.Value(tracerKey{}).(trace.Tracer) return tr } @@ -51,8 +47,6 @@ func Exec(ctx context.Context, spanName string, opts ...Option) { if tr != nil { ctx, span = tr.Start(ctx, spanName) - } else { - panic("nil tracer") } for _, optFn := range opts { From ae94046c4eb174156672a239ceac739156adecc0 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Mon, 22 Aug 2022 13:11:30 +0530 Subject: [PATCH 34/48] fix: panic in NewTransactionsByPriceAndNonce iteration --- core/types/transaction.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/types/transaction.go b/core/types/transaction.go index 1d9b3ac602..e0e52f25bc 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -508,6 +508,10 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa // Initialize a price and received time based heap with the head transactions heads := make(TxByPriceAndTime, 0, len(txs)) for from, accTxs := range txs { + if len(accTxs) == 0 { + continue + } + acc, _ := Sender(signer, accTxs[0]) wrapped, err := NewTxWithMinerFee(accTxs[0], baseFee) // Remove transaction if sender doesn't match from, or if wrapping fails. From aa532ee1ac8375cb283e36c93e1fcfcc8138d273 Mon Sep 17 00:00:00 2001 From: Arpit Temani Date: Tue, 27 Sep 2022 12:20:43 +0530 Subject: [PATCH 35/48] change heimdall version to develop --- .github/matic-cli-config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/matic-cli-config.yml b/.github/matic-cli-config.yml index f643f4b192..2b83b684c6 100644 --- a/.github/matic-cli-config.yml +++ b/.github/matic-cli-config.yml @@ -8,4 +8,4 @@ numOfNonValidators: 0 ethURL: http://ganache:9545 devnetType: docker borDockerBuildContext: "../../bor" -heimdallDockerBuildContext: "https://github.com/maticnetwork/heimdall.git#v0.3.0-dev" \ No newline at end of file +heimdallDockerBuildContext: "https://github.com/maticnetwork/heimdall.git#develop" From 9bdbc1efb56d009a3ea8d700bd66adad7b496823 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 27 Sep 2022 13:57:41 +0530 Subject: [PATCH 36/48] miner/worker: fix duplicate call to tx ordering --- miner/worker.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index b9ac283de9..a1dc27ec0e 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -433,6 +433,7 @@ func recalcRecommit(minRecommit, prev time.Duration, target float64, inc bool) t } // newWorkLoop is a standalone goroutine to submit new sealing work upon received events. +// //nolint:gocognit func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { defer w.wg.Done() @@ -1196,13 +1197,7 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en lenNewRemotes = txs.GetTxs() tracing.Exec(ctx, "worker.RemoteCommitTransactions", func(ctx context.Context, span trace.Span) { - txs = types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) - committed = w.commitTransactions(env, txs, interrupt) - - span.SetAttributes( - attribute.Int("len of tx Heads", txs.GetTxs()), - ) }) if committed { From 9b4f7961f9ab7e23d8cbfa104f8551c9113fd630 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 27 Sep 2022 18:54:43 +0530 Subject: [PATCH 37/48] miner/worker: refactor tracing --- miner/worker.go | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index a1dc27ec0e..0e25276cef 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1150,14 +1150,16 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en remoteTxsCount = len(remoteTxs) span.SetAttributes( - attribute.Int("LocalTx Len", localTxsCount), - attribute.Int("RemoteTx Len", remoteTxsCount), + attribute.Int("len of local txs", localTxsCount), + attribute.Int("len of remote txs", remoteTxsCount), ) }) - lenLocals, lenNewLocals, localEnvTCount, lenRemotes, lenNewRemotes, remoteEnvTCount := 0, 0, 0, 0, 0, 0 - - var committed bool + var ( + localEnvTCount int + remoteEnvTCount int + committed bool + ) if localTxsCount > 0 { var txs *types.TransactionsByPriceAndNonce @@ -1166,12 +1168,10 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en txs = types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) span.SetAttributes( - attribute.Int("len of tx Heads", txs.GetTxs()), + attribute.Int("len of tx local Heads", txs.GetTxs()), ) }) - lenNewLocals = txs.GetTxs() - tracing.Exec(ctx, "worker.LocalCommitTransactions", func(ctx context.Context, span trace.Span) { committed = w.commitTransactions(env, txs, interrupt) }) @@ -1190,12 +1190,10 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en txs = types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) span.SetAttributes( - attribute.Int("len of tx Heads", txs.GetTxs()), + attribute.Int("len of tx remote Heads", txs.GetTxs()), ) }) - lenNewRemotes = txs.GetTxs() - tracing.Exec(ctx, "worker.RemoteCommitTransactions", func(ctx context.Context, span trace.Span) { committed = w.commitTransactions(env, txs, interrupt) }) @@ -1208,12 +1206,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en } span.SetAttributes( - attribute.Int("len of localTxs", lenLocals), - attribute.Int("len of sorted localTxs", lenNewLocals), - attribute.Int("len of final localTxs ", localEnvTCount), - attribute.Int("len of remoteTxs", lenRemotes), - attribute.Int("len of sorted remoteTxs", lenNewRemotes), - attribute.Int("len of final remoteTxs", remoteEnvTCount), + attribute.Int("len of final local txs ", localEnvTCount), + attribute.Int("len of final remote txs", remoteEnvTCount), ) } From b626090a00ced5cf8a98b9feb4c43235a28fba36 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 27 Sep 2022 18:55:00 +0530 Subject: [PATCH 38/48] consensus/bor: use tracing package --- consensus/bor/bor.go | 109 ++++++++++++------------------------------- 1 file changed, 30 insertions(+), 79 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 433825066b..be5c7d901b 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -23,6 +23,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/tracing" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/bor/api" "github.com/ethereum/go-ethereum/consensus/bor/clerk" @@ -743,14 +744,14 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, if IsSprintStart(headerNumber, c.config.Sprint) { cx := statefull.ChainContext{Chain: chain, Bor: c} // check and commit span - if err := c.checkAndCommitSpan(ctx, nil, state, header, cx); err != nil { + if err := c.checkAndCommitSpan(ctx, state, header, cx); err != nil { log.Error("Error while committing span", "error", err) return } if c.HeimdallClient != nil { // commit statees - stateSyncData, err = c.CommitStates(ctx, nil, state, header, cx) + stateSyncData, err = c.CommitStates(ctx, state, header, cx) if err != nil { log.Error("Error while committing states", "error", err) return @@ -808,28 +809,34 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.State // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, // nor block rewards given, and returns the final block. func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { - tracer := otel.GetTracerProvider().Tracer("MinerWorker") - - finalizeCtx, finalizeSpan := tracer.Start(ctx, "FinalizeAndAssemble") + finalizeCtx, finalizeSpan := tracing.StartSpan(ctx, "bor.FinalizeAndAssemble") defer finalizeSpan.End() stateSyncData := []*types.StateSyncData{} headerNumber := header.Number.Uint64() + var err error + if IsSprintStart(headerNumber, c.config.Sprint) { cx := statefull.ChainContext{Chain: chain, Bor: c} - // check and commit span - err := c.checkAndCommitSpan(finalizeCtx, tracer, state, header, cx) + tracing.Exec(finalizeCtx, "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) { + // check and commit span + err = c.checkAndCommitSpan(finalizeCtx, state, header, cx) + }) + if err != nil { log.Error("Error while committing span", "error", err) return nil, err } if c.HeimdallClient != nil { - // commit states - stateSyncData, err = c.CommitStates(finalizeCtx, tracer, state, header, cx) + tracing.Exec(finalizeCtx, "bor.checkAndCommitSpan", func(ctx context.Context, span trace.Span) { + // commit states + stateSyncData, err = c.CommitStates(finalizeCtx, state, header, cx) + }) + if err != nil { log.Error("Error while committing states", "error", err) return nil, err @@ -837,24 +844,25 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead } } - start1 := time.Now() - if err := c.changeContractCodeIfNeeded(headerNumber, state); err != nil { + tracing.Exec(finalizeCtx, "bor.changeContractCodeIfNeeded", func(ctx context.Context, span trace.Span) { + err = c.changeContractCodeIfNeeded(headerNumber, state) + }) + + if err != nil { log.Error("Error changing contract code", "error", err) return nil, err } - diff1 := time.Since(start1) + // No block rewards in PoA, so the state remains as it is + tracing.Exec(finalizeCtx, "bor.IntermediateRoot", func(ctx context.Context, span trace.Span) { + header.Root = state.IntermediateRoot(finalizeCtx, chain.Config().IsEIP158(header.Number)) + }) - // No block rewards in PoA, so the state remains as is and uncles are dropped - start2 := time.Now() - header.Root = state.IntermediateRoot(finalizeCtx, chain.Config().IsEIP158(header.Number)) + // Uncles are dropped header.UncleHash = types.CalcUncleHash(nil) - diff2 := time.Since(start2) // Assemble block - start3 := time.Now() block := types.NewBlock(header, txs, nil, receipts, new(trie.Trie)) - diff3 := time.Since(start3) // set state sync bc := chain.(core.BorStateSyncer) @@ -865,9 +873,6 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead attribute.String("hash", header.Hash().String()), attribute.Int("number of txs", len(txs)), attribute.Int("gas used", int(block.GasUsed())), - attribute.Int("change contract code time", int(diff1.Milliseconds())), - attribute.Int("intermeddiate root hash calc time", int(diff2.Milliseconds())), - attribute.Int("assemble new block time", int(diff3.Milliseconds())), ) // return the final block for sealing @@ -1032,38 +1037,19 @@ func (c *Bor) Close() error { func (c *Bor) checkAndCommitSpan( ctx context.Context, - tracer trace.Tracer, state *state.StateDB, header *types.Header, chain core.ChainContext, ) error { - var ( - checkAndCommitSpanCtx = context.Background() - checkAndCommitSpan trace.Span - ) - - if tracer != nil { - checkAndCommitSpanCtx, checkAndCommitSpan = tracer.Start(ctx, "checkAndCommitSpan") - defer checkAndCommitSpan.End() - } - headerNumber := header.Number.Uint64() - span, err := c.spanner.GetCurrentSpan(checkAndCommitSpanCtx, header.ParentHash) - if checkAndCommitSpan != nil { - checkAndCommitSpan.SetAttributes( - attribute.Int("number", int(headerNumber)), - attribute.String("hash", header.Hash().String()), - attribute.Int("current span id", int(span.ID)), - attribute.Bool("error", err != nil), - ) - } + span, err := c.spanner.GetCurrentSpan(ctx, header.ParentHash) if err != nil { return err } if c.needToCommitSpan(span, headerNumber) { - return c.FetchAndCommitSpan(checkAndCommitSpanCtx, tracer, span.ID+1, state, header, chain) + return c.FetchAndCommitSpan(ctx, span.ID+1, state, header, chain) } return nil @@ -1090,19 +1076,11 @@ func (c *Bor) needToCommitSpan(currentSpan *span.Span, headerNumber uint64) bool func (c *Bor) FetchAndCommitSpan( ctx context.Context, - tracer trace.Tracer, newSpanID uint64, state *state.StateDB, header *types.Header, chain core.ChainContext, ) error { - - var fetchAndCommitSpan trace.Span - if tracer != nil { - _, fetchAndCommitSpan = tracer.Start(ctx, "FetchAndCommitSpan") - defer fetchAndCommitSpan.End() - } - var heimdallSpan span.HeimdallSpan if c.HeimdallClient == nil { @@ -1131,34 +1109,17 @@ func (c *Bor) FetchAndCommitSpan( ) } - if fetchAndCommitSpan != nil { - fetchAndCommitSpan.SetAttributes( - attribute.Int("number", int(header.Number.Int64())), - attribute.String("hash", header.Hash().String()), - attribute.Int("fetched span id", int(heimdallSpan.ID)), - ) - } - return c.spanner.CommitSpan(ctx, heimdallSpan, state, header, chain) } // CommitStates commit states func (c *Bor) CommitStates( ctx context.Context, - tracer trace.Tracer, state *state.StateDB, header *types.Header, chain statefull.ChainContext, ) ([]*types.StateSyncData, error) { - - var commitStatesSpan trace.Span - if tracer != nil { - _, commitStatesSpan = tracer.Start(ctx, "CommitStates") - defer commitStatesSpan.End() - } - fetchStart := time.Now() - stateSyncs := make([]*types.StateSyncData, 0) number := header.Number.Uint64() _lastStateID, err := c.GenesisContractsClient.LastStateId(number - 1) @@ -1189,7 +1150,7 @@ func (c *Bor) CommitStates( processStart := time.Now() totalGas := 0 /// limit on gas for state sync per block chainID := c.chainConfig.ChainID.String() - stateSyncs = make([]*types.StateSyncData, len(eventRecords)) + stateSyncs := make([]*types.StateSyncData, len(eventRecords)) var gasUsed uint64 @@ -1227,17 +1188,7 @@ func (c *Bor) CommitStates( processTime := time.Since(processStart) - if commitStatesSpan != nil { - commitStatesSpan.SetAttributes( - attribute.Int("number", int(number)), - attribute.String("hash", header.Hash().String()), - attribute.Int("fetch time", int(fetchTime.Milliseconds())), - attribute.Int("process time", int(processTime.Milliseconds())), - attribute.Int("state sync count", len(stateSyncs)), - attribute.Int("total gas", totalGas), - ) - } - log.Info("StateSyncData", "Gas", totalGas, "Block-number", number, "LastStateID", lastStateID, "TotalRecords", len(eventRecords)) + log.Info("StateSyncData", "gas", totalGas, "number", number, "lastStateID", lastStateID, "total records", len(eventRecords), "fetch time", int(fetchTime.Milliseconds()), "process time", int(processTime.Milliseconds())) return stateSyncs, nil } From 4324423102fed7e8d79cec7bae7fc165cb00a564 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Tue, 27 Sep 2022 20:37:48 +0530 Subject: [PATCH 39/48] tracing: add more abstraction for spans --- common/tracing/context.go | 19 +++++++++++++++++++ consensus/bor/bor.go | 20 ++++++++++---------- miner/worker.go | 33 +++++++++++++++++++-------------- 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/common/tracing/context.go b/common/tracing/context.go index 4c9246c9df..401ec54379 100644 --- a/common/tracing/context.go +++ b/common/tracing/context.go @@ -24,12 +24,23 @@ func FromContext(ctx context.Context) trace.Tracer { func StartSpan(ctx context.Context, snapName string) (context.Context, trace.Span) { tr := FromContext(ctx) + + if tr == nil { + return ctx, nil + } + ctx, span := tr.Start(ctx, snapName) ctx = WithTracer(ctx, tr) return ctx, span } +func EndSpan(span trace.Span) { + if span != nil { + span.End() + } +} + func Trace(ctx context.Context, spanName string) (context.Context, trace.Span) { tr := FromContext(ctx) @@ -77,3 +88,11 @@ func ElapsedTime(ctx context.Context, span trace.Span, msg string, fn func(conte span.SetAttributes(attribute.Int(msg, int(time.Since(now).Milliseconds()))) } } + +func SetAttributes(span trace.Span, kvs ...attribute.KeyValue) { + if span != nil { + for _, kv := range kvs { + span.SetAttributes(kv) + } + } +} diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index be5c7d901b..87a5a964ae 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -16,7 +16,6 @@ import ( "time" lru "github.com/hashicorp/golang-lru" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "golang.org/x/crypto/sha3" @@ -810,7 +809,7 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.State // nor block rewards given, and returns the final block. func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { finalizeCtx, finalizeSpan := tracing.StartSpan(ctx, "bor.FinalizeAndAssemble") - defer finalizeSpan.End() + defer tracing.EndSpan(finalizeSpan) stateSyncData := []*types.StateSyncData{} @@ -868,7 +867,8 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead bc := chain.(core.BorStateSyncer) bc.SetStateSync(stateSyncData) - finalizeSpan.SetAttributes( + tracing.SetAttributes( + finalizeSpan, attribute.Int("number", int(header.Number.Int64())), attribute.String("hash", header.Hash().String()), attribute.Int("number of txs", len(txs)), @@ -891,8 +891,8 @@ func (c *Bor) Authorize(currentSigner common.Address, signFn SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { - tracer := otel.GetTracerProvider().Tracer("MinerWorker") - _, sealSpan := tracer.Start(ctx, "Seal") + _, sealSpan := tracing.StartSpan(ctx, "bor.Seal") + defer tracing.EndSpan(sealSpan) header := block.Header() // Sealing the genesis block is not supported @@ -918,9 +918,6 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block if !snap.ValidatorSet.HasAddress(currentSigner.signer) { // Check the UnauthorizedSignerError.Error() msg to see why we pass number-1 err := &UnauthorizedSignerError{number - 1, currentSigner.signer.Bytes()} - sealSpan.SetAttributes(attribute.String("error", err.Error())) - sealSpan.End() - return err } @@ -966,14 +963,17 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block "delay", delay, "headerDifficulty", header.Difficulty, ) - sealSpan.SetAttributes( + + tracing.SetAttributes( + sealSpan, attribute.Int("number", int(number)), attribute.String("hash", header.Hash().String()), attribute.Int("delay", int(delay.Milliseconds())), attribute.Int("wiggle", int(wiggle.Milliseconds())), attribute.Bool("out-of-turn", wiggle > 0), ) - sealSpan.End() + + tracing.EndSpan(sealSpan) } select { case results <- block.WithSeal(header): diff --git a/miner/worker.go b/miner/worker.go index 0e25276cef..88cb88154b 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -451,7 +451,7 @@ func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { commit := func(noempty bool, s int32) { // we close spans only by the place we created them ctx, span := tracing.Trace(ctx, "worker.commit") - defer span.End() + tracing.EndSpan(span) if interrupt != nil { atomic.StoreInt32(interrupt, s) @@ -468,7 +468,7 @@ func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { // clearPending cleans the stale pending tasks. clearPending := func(number uint64) { _, span := tracing.Trace(ctx, "worker.clearPending") - defer span.End() + tracing.EndSpan(span) w.pendingMu.Lock() for h, t := range w.pendingTasks { @@ -783,12 +783,11 @@ func (w *worker) resultLoop() { // Commit block and state to database. tracing.ElapsedTime(ctx, span, "WriteBlockAndSetHead time taken", func(ctx context.Context, span trace.Span) { - _, err = w.chain.WriteBlockAndSetHead(ctx, block, receipts, logs, task.state, true) - }) - span.SetAttributes( + tracing.SetAttributes( + span, attribute.String("hash", hash.String()), attribute.Int("number", int(block.Number().Uint64())), attribute.Int("txns", block.Transactions().Len()), @@ -1123,7 +1122,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { // be customized with the plugin in the future. func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *environment) { ctx, span := tracing.StartSpan(ctx, "fillTransactions") - defer span.End() + defer tracing.EndSpan(span) // Split the pending transactions into locals and remotes // Fill the block with all available pending transactions. @@ -1149,7 +1148,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en localTxsCount = len(localTxs) remoteTxsCount = len(remoteTxs) - span.SetAttributes( + tracing.SetAttributes( + span, attribute.Int("len of local txs", localTxsCount), attribute.Int("len of remote txs", remoteTxsCount), ) @@ -1167,7 +1167,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en tracing.Exec(ctx, "worker.LocalTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) { txs = types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) - span.SetAttributes( + tracing.SetAttributes( + span, attribute.Int("len of tx local Heads", txs.GetTxs()), ) }) @@ -1189,7 +1190,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en tracing.Exec(ctx, "worker.RemoteTransactionsByPriceAndNonce", func(ctx context.Context, span trace.Span) { txs = types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) - span.SetAttributes( + tracing.SetAttributes( + span, attribute.Int("len of tx remote Heads", txs.GetTxs()), ) }) @@ -1205,7 +1207,8 @@ func (w *worker) fillTransactions(ctx context.Context, interrupt *int32, env *en remoteEnvTCount = env.tcount } - span.SetAttributes( + tracing.SetAttributes( + span, attribute.Int("len of final local txs ", localEnvTCount), attribute.Int("len of final remote txs", remoteEnvTCount), ) @@ -1257,9 +1260,10 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, } ctx, span := tracing.StartSpan(ctx, "commitWork") - defer span.End() + defer tracing.EndSpan(span) - span.SetAttributes( + tracing.SetAttributes( + span, attribute.Int("number", int(work.header.Number.Uint64())), ) @@ -1296,7 +1300,7 @@ func (w *worker) commitWork(ctx context.Context, interrupt *int32, noempty bool, func (w *worker) commit(ctx context.Context, env *environment, interval func(), update bool, start time.Time) error { if w.isRunning() { ctx, span := tracing.StartSpan(ctx, "commit") - defer span.End() + defer tracing.EndSpan(span) if interval != nil { interval() @@ -1308,7 +1312,8 @@ func (w *worker) commit(ctx context.Context, env *environment, interval func(), block, err := w.engine.FinalizeAndAssemble(ctx, w.chain, env.header, env.state, env.txs, env.unclelist(), env.receipts) - span.SetAttributes( + tracing.SetAttributes( + span, attribute.Int("number", int(block.Number().Uint64())), attribute.String("hash", block.Hash().String()), attribute.String("sealhash", w.engine.SealHash(block.Header()).String()), From a810072c6af238e5d0306fe3c18b39e98c71b40d Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Wed, 28 Sep 2022 13:38:52 +0530 Subject: [PATCH 40/48] tracing: set all attributes at once --- common/tracing/context.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/tracing/context.go b/common/tracing/context.go index 401ec54379..510e45d775 100644 --- a/common/tracing/context.go +++ b/common/tracing/context.go @@ -91,8 +91,6 @@ func ElapsedTime(ctx context.Context, span trace.Span, msg string, fn func(conte func SetAttributes(span trace.Span, kvs ...attribute.KeyValue) { if span != nil { - for _, kv := range kvs { - span.SetAttributes(kv) - } + span.SetAttributes(kvs...) } } From 54fef9ccabf44fecb761dc104b7eef038bddedf5 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 29 Sep 2022 13:52:07 +0530 Subject: [PATCH 41/48] remove nested tracing from blockchain.WriteBlockAndSetHead function --- core/blockchain.go | 100 ++++----------------------------------------- miner/worker.go | 4 +- 2 files changed, 10 insertions(+), 94 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 37d23503b1..48d5e966db 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -28,9 +28,6 @@ import ( "time" lru "github.com/hashicorp/golang-lru" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "golang.org/x/net/context" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" @@ -226,6 +223,7 @@ type BlockChain struct { // NewBlockChain returns a fully initialised block chain using information // available in the database. It initialises the default Ethereum Validator // and Processor. +// //nolint:gocognit func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64, checker ethereum.ChainValidator) (*BlockChain, error) { if cacheConfig == nil { @@ -1229,8 +1227,7 @@ func (bc *BlockChain) writeKnownBlock(block *types.Block) error { // writeBlockWithState writes block, metadata and corresponding state data to the // database. -//nolint:gocognit -func (bc *BlockChain) writeBlockWithState(ctx context.Context, block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB) ([]*types.Log, error) { +func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB) ([]*types.Log, error) { // Calculate the total difficulty of the block ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) if ptd == nil { @@ -1239,32 +1236,15 @@ func (bc *BlockChain) writeBlockWithState(ctx context.Context, block *types.Bloc // Make sure no inconsistent state is leaked during insertion externTd := new(big.Int).Add(block.Difficulty(), ptd) - tracer := otel.GetTracerProvider().Tracer("MinerWorker") - - _, writeBlockWithStateSpan := tracer.Start(ctx, "writeBlockWithState") - defer writeBlockWithStateSpan.End() - // Irrelevant of the canonical status, write the block itself to the database. // // Note all the components of block(td, hash->number map, header, body, receipts) // should be written atomically. BlockBatch is used for containing all components. blockBatch := bc.db.NewBatch() - - writeTdStart := time.Now() rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd) - - writeTdTime := time.Since(writeTdStart) - - writeBlockStart := time.Now() rawdb.WriteBlock(blockBatch, block) - - writeBlockTime := time.Since(writeBlockStart) - - writeReceiptsStart := time.Now() rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts) - writeReceiptsTime := time.Since(writeReceiptsStart) - // System call appends state-sync logs into state. So, `state.Logs()` contains // all logs including system-call logs (state sync logs) while `logs` contains // only logs generated by transactions (receipts). @@ -1275,10 +1255,6 @@ func (bc *BlockChain) writeBlockWithState(ctx context.Context, block *types.Bloc // block logs = receipt logs + state sync logs = `state.Logs()` blockLogs := state.Logs() var stateSyncLogs []*types.Log - - writeBorReceiptStart := time.Now() - writeBorReceiptTime := time.Since(writeBorReceiptStart) - borLogs := false if len(blockLogs) > 0 { sort.SliceStable(blockLogs, func(i, j int) bool { return blockLogs[i].Index < blockLogs[j].Index @@ -1299,32 +1275,19 @@ func (bc *BlockChain) writeBlockWithState(ctx context.Context, block *types.Bloc // Write bor tx reverse lookup rawdb.WriteBorTxLookupEntry(blockBatch, block.Hash(), block.NumberU64()) - - writeBorReceiptTime = time.Since(writeBorReceiptStart) - borLogs = true } } - writePreimagesStart := time.Now() rawdb.WritePreimages(blockBatch, state.Preimages()) if err := blockBatch.Write(); err != nil { log.Crit("Failed to write block into disk", "err", err) } - - writePreimagesTime := time.Since(writePreimagesStart) - // Commit all cached state changes into underlying memory database. - commitCacheStart := time.Now() root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) if err != nil { return []*types.Log{}, err } triedb := bc.stateCache.TrieDB() - commitCacheTime := time.Since(commitCacheStart) - - garbageCollectionStart := time.Now() - garbageCollectionTime := time.Since(garbageCollectionStart) //nolint:staticcheck - garbageCollected := false // If we're running an archive node, always flush if bc.cacheConfig.TrieDirtyDisabled { @@ -1375,73 +1338,39 @@ func (bc *BlockChain) writeBlockWithState(ctx context.Context, block *types.Bloc triedb.Dereference(root.(common.Hash)) } } - - garbageCollectionTime = time.Since(garbageCollectionStart) - garbageCollected = true } - - writeBlockWithStateSpan.SetAttributes( - attribute.Int("number", int(block.NumberU64())), - attribute.String("hash", block.Hash().String()), - attribute.Int("write total difficulty time", int(writeTdTime.Milliseconds())), - attribute.Int("write block time", int(writeBlockTime.Milliseconds())), - attribute.Int("write receipts time", int(writeReceiptsTime.Milliseconds())), - attribute.Bool("bor receipts present?", borLogs), - attribute.Int("write bor receipts time", int(writeBorReceiptTime.Milliseconds())), - attribute.Int("write preimage time", int(writePreimagesTime.Milliseconds())), - attribute.Int("commit cache time", int(commitCacheTime.Milliseconds())), - attribute.Bool("garbage collected?", garbageCollected), - attribute.Int("garbage collection time", int(garbageCollectionTime.Milliseconds())), - ) - return stateSyncLogs, nil } // WriteBlockWithState writes the block and all associated state to the database. -func (bc *BlockChain) WriteBlockAndSetHead(ctx context.Context, block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (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(ctx, block, receipts, logs, state, emitHeadEvent) + return bc.writeBlockAndSetHead(block, receipts, logs, state, emitHeadEvent) } // writeBlockAndSetHead writes the block and all associated state to the database, // and also it applies the given block as the new chain head. This function expects // the chain mutex to be held. -func (bc *BlockChain) writeBlockAndSetHead(ctx context.Context, block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (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) { var stateSyncLogs []*types.Log - - tracer := otel.GetTracerProvider().Tracer("MinerWorker") - - _, writeBlockAndSetHeadSpan := tracer.Start(ctx, "writeBlockAndSetHead") - defer writeBlockAndSetHeadSpan.End() - - writeBlockWithStateStart := time.Now() - - if stateSyncLogs, err = bc.writeBlockWithState(ctx, block, receipts, logs, state); err != nil { + if stateSyncLogs, err = bc.writeBlockWithState(block, receipts, logs, state); err != nil { return NonStatTy, err } - - writeBlockWithStateTime := time.Since(writeBlockWithStateStart) - currentBlock := bc.CurrentBlock() reorg, err := bc.forker.ReorgNeeded(currentBlock.Header(), block.Header()) if err != nil { return NonStatTy, err } - - reorgStart := time.Now() - reorgTime := time.Since(reorgStart) if reorg { // Reorganise the chain if the parent is not the head block if block.ParentHash() != currentBlock.Hash() { if err := bc.reorg(currentBlock, block); err != nil { return NonStatTy, err } - - reorgTime = time.Since(reorgStart) } status = CanonStatTy } else { @@ -1453,7 +1382,6 @@ func (bc *BlockChain) writeBlockAndSetHead(ctx context.Context, block *types.Blo } bc.futureBlocks.Remove(block.Hash()) - sendEventStart := time.Now() if status == CanonStatTy { bc.chainFeed.Send(ChainEvent{Block: block, Hash: block.Hash(), Logs: logs}) if len(logs) > 0 { @@ -1486,18 +1414,6 @@ func (bc *BlockChain) writeBlockAndSetHead(ctx context.Context, block *types.Blo NewChain: []*types.Block{block}, }) } - - sendEventTime := time.Since(sendEventStart) - - writeBlockAndSetHeadSpan.SetAttributes( - attribute.Int("number", int(block.NumberU64())), - attribute.String("hash", block.Hash().String()), - attribute.Int("write block with state time", int(writeBlockWithStateTime.Milliseconds())), - attribute.Bool("reorg", reorg), - attribute.Int("reorg time", int(reorgTime.Milliseconds())), - attribute.Int("send events time", int(sendEventTime.Milliseconds())), - ) - return status, nil } @@ -1853,9 +1769,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) var status WriteStatus if !setHead { // Don't set the head, only insert the block - _, err = bc.writeBlockWithState(context.Background(), block, receipts, logs, statedb) + _, err = bc.writeBlockWithState(block, receipts, logs, statedb) } else { - status, err = bc.writeBlockAndSetHead(context.Background(), block, receipts, logs, statedb, false) + status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false) } atomic.StoreUint32(&followupInterrupt, 1) if err != nil { diff --git a/miner/worker.go b/miner/worker.go index 88cb88154b..9f3cd77c23 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -782,8 +782,8 @@ func (w *worker) resultLoop() { } // Commit block and state to database. - tracing.ElapsedTime(ctx, span, "WriteBlockAndSetHead time taken", func(ctx context.Context, span trace.Span) { - _, err = w.chain.WriteBlockAndSetHead(ctx, block, receipts, logs, task.state, true) + tracing.ElapsedTime(ctx, span, "WriteBlockAndSetHead time taken", func(_ context.Context, _ trace.Span) { + _, err = w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true) }) tracing.SetAttributes( From c99de20049ecf2a43e67ebddc81fd721828de3d5 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 29 Sep 2022 13:59:03 +0530 Subject: [PATCH 42/48] remove nested tracing from statedb.IntermediateRoot function --- cmd/evm/internal/t8ntool/execution.go | 5 +-- cmd/evm/runner.go | 3 +- cmd/evm/staterunner.go | 4 +- consensus/beacon/consensus.go | 9 +++-- consensus/bor/bor.go | 4 +- consensus/clique/clique.go | 2 +- consensus/ethash/consensus.go | 2 +- core/block_validator.go | 3 +- core/chain_makers.go | 2 +- core/state/statedb.go | 54 ++------------------------- core/state/statedb_test.go | 5 +-- core/state_prefetcher.go | 5 +-- core/state_processor.go | 3 +- eth/api_test.go | 5 +-- eth/tracers/api.go | 2 +- eth/tracers/api_bor.go | 2 +- tests/state_test.go | 3 +- tests/state_test_util.go | 3 +- 18 files changed, 29 insertions(+), 87 deletions(-) diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 5581b972fb..c848b953f8 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -17,7 +17,6 @@ package t8ntool import ( - "context" "fmt" "math/big" "os" @@ -193,7 +192,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, if chainConfig.IsByzantium(vmContext.BlockNumber) { statedb.Finalise(true) } else { - root = statedb.IntermediateRoot(context.Background(), chainConfig.IsEIP158(vmContext.BlockNumber)).Bytes() + root = statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)).Bytes() } // Create a new receipt for the transaction, storing the intermediate root and @@ -225,7 +224,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, txIndex++ } - statedb.IntermediateRoot(context.Background(), chainConfig.IsEIP158(vmContext.BlockNumber)) + statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)) // Add mining reward? if miningReward > 0 { // Add mining reward. The mining reward may be `0`, which only makes a difference in the cases diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 2c4ae44edf..889de43e0a 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -18,7 +18,6 @@ package main import ( "bytes" - "context" "encoding/json" "fmt" "io/ioutil" @@ -270,7 +269,7 @@ func runCmd(ctx *cli.Context) error { if ctx.GlobalBool(DumpFlag.Name) { statedb.Commit(true) - statedb.IntermediateRoot(context.Background(), true) + statedb.IntermediateRoot(true) fmt.Println(string(statedb.Dump(nil))) } diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 23f2a2c378..90596d9b3c 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -17,7 +17,6 @@ package main import ( - "context" "encoding/json" "errors" "fmt" @@ -96,7 +95,6 @@ func stateTestCmd(ctx *cli.Context) error { Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name), } results := make([]StatetestResult, 0, len(tests)) - ctxGo := context.Background() for key, test := range tests { for _, st := range test.Subtests() { // Run the test and aggregate the result @@ -104,7 +102,7 @@ func stateTestCmd(ctx *cli.Context) error { _, s, err := test.Run(st, cfg, false) // print state root for evmlab tracing if ctx.GlobalBool(MachineFlag.Name) && s != nil { - fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", s.IntermediateRoot(ctxGo, false)) + fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", s.IntermediateRoot(false)) } if err != nil { // Test failed, mark as so and dump any state to aid debugging diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 992acfdbae..b7102c1e67 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -171,10 +171,11 @@ func (beacon *Beacon) VerifyUncles(chain consensus.ChainReader, block *types.Blo // verifyHeader checks whether a header conforms to the consensus rules of the // stock Ethereum consensus engine. The difference between the beacon and classic is // (a) The following fields are expected to be constants: -// - difficulty is expected to be 0 -// - nonce is expected to be 0 -// - unclehash is expected to be Hash(emptyHeader) +// - difficulty is expected to be 0 +// - nonce is expected to be 0 +// - unclehash is expected to be Hash(emptyHeader) // to be the desired constants +// // (b) the timestamp is not verified anymore // (c) the extradata is limited to 32 bytes func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header) error { @@ -274,7 +275,7 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types. } // The block reward is no longer handled here. It's done by the // external consensus engine. - header.Root = state.IntermediateRoot(context.Background(), true) + header.Root = state.IntermediateRoot(true) } // FinalizeAndAssemble implements consensus.Engine, setting the final state and diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 87a5a964ae..458c7554a0 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -764,7 +764,7 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, } // No block rewards in PoA, so the state remains as is and uncles are dropped - header.Root = state.IntermediateRoot(ctx, chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) header.UncleHash = types.CalcUncleHash(nil) // Set state sync data to blockchain @@ -854,7 +854,7 @@ func (c *Bor) FinalizeAndAssemble(ctx context.Context, chain consensus.ChainHead // No block rewards in PoA, so the state remains as it is tracing.Exec(finalizeCtx, "bor.IntermediateRoot", func(ctx context.Context, span trace.Span) { - header.Root = state.IntermediateRoot(finalizeCtx, chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) }) // Uncles are dropped diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 512a04a9dd..ad09552469 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -564,7 +564,7 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header // rewards given. func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { // No block rewards in PoA, so the state remains as is and uncles are dropped - header.Root = state.IntermediateRoot(context.Background(), chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) header.UncleHash = types.CalcUncleHash(nil) } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 75ddd6fdd6..761442f44e 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -594,7 +594,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { // Accumulate any block and uncle rewards and commit the final state root accumulateRewards(chain.Config(), state, header, uncles) - header.Root = state.IntermediateRoot(context.Background(), chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) } // FinalizeAndAssemble implements consensus.Engine, accumulating the block and diff --git a/core/block_validator.go b/core/block_validator.go index 3ed9c21c01..3763be0be0 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -17,7 +17,6 @@ package core import ( - "context" "fmt" "github.com/ethereum/go-ethereum/consensus" @@ -97,7 +96,7 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD } // Validate the state root against the received state root and throw // an error if they don't match. - if root := statedb.IntermediateRoot(context.Background(), 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)", header.Root, root) } return nil diff --git a/core/chain_makers.go b/core/chain_makers.go index 561826cf1a..e9944e4744 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -294,7 +294,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S time = parent.Time() + 10 // block time is fixed at 10 seconds } header := &types.Header{ - Root: state.IntermediateRoot(context.Background(), chain.Config().IsEIP158(parent.Number())), + Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())), ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), Difficulty: engine.CalcDifficulty(chain, time, &types.Header{ diff --git a/core/state/statedb.go b/core/state/statedb.go index 1758472eba..c236a79b5a 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -18,7 +18,6 @@ package state import ( - "context" "errors" "fmt" "math/big" @@ -34,9 +33,6 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" ) type revision struct { @@ -823,19 +819,10 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { // IntermediateRoot computes the current root hash of the state trie. // It is called in between transactions to get the root hash that // goes into transaction receipts. -func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) common.Hash { - // Fetch the tracer and create a sub-span here - tracer := otel.GetTracerProvider().Tracer("MinerWorker") - - _, intermediateRootSpan := tracer.Start(ctx, "IntermediateRoot") - defer intermediateRootSpan.End() - +func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { // Finalise all the dirty storage states and write them into the tries - finalizeStart := time.Now() s.Finalise(deleteEmptyObjects) - finalizeTime := time.Since(finalizeStart) - // 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. @@ -855,33 +842,19 @@ func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) // the account prefetcher. Instead, let's process all the storage updates // first, giving the account prefeches just a few more milliseconds of time // to pull useful data from disk. - updateRootStart := time.Now() - updatedRootInitialLength := len(s.stateObjectsPending) - updated := 0 for addr := range s.stateObjectsPending { if obj := s.stateObjects[addr]; !obj.deleted { obj.updateRoot(s.db) - updated++ } } - - updateRootTime := time.Since(updateRootStart) - // Now we're about to start to write changes to the trie. The trie is so far // _untouched_. We can check with the prefetcher, if it can give us a trie // which has the same root, but also has some content loaded into it. - trieFetchStart := time.Now() if prefetcher != nil { if trie := prefetcher.trie(s.originalRoot); trie != nil { s.trie = trie } } - - trieFetchTime := time.Since(trieFetchStart) - - stateIterationStart := time.Now() - stateIterationLength := len(s.stateObjectsPending) - iterations := 0 usedAddrs := make([][]byte, 0, len(s.stateObjectsPending)) for addr := range s.stateObjectsPending { if obj := s.stateObjects[addr]; obj.deleted { @@ -892,11 +865,7 @@ func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) s.AccountUpdated += 1 } usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure - iterations++ } - - stateIterationTime := time.Since(stateIterationStart) - if prefetcher != nil { prefetcher.used(s.originalRoot, usedAddrs) } @@ -907,24 +876,7 @@ func (s *StateDB) IntermediateRoot(ctx context.Context, deleteEmptyObjects bool) if metrics.EnabledExpensive { defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) } - - hashCalculationStart := time.Now() - hash := s.trie.Hash() - hashCalculationTime := time.Since(hashCalculationStart) - - intermediateRootSpan.SetAttributes( - attribute.Int("finalize time", int(finalizeTime.Milliseconds())), - attribute.Int("updateRoot time", int(updateRootTime.Milliseconds())), - attribute.Int("updateRoot initial length", updatedRootInitialLength), - attribute.Int("updateRoot iterations", updated), - attribute.Int("trieFetch time", int(trieFetchTime.Milliseconds())), - attribute.Int("stateIteration time", int(stateIterationTime.Milliseconds())), - attribute.Int("stateIteration initial length", stateIterationLength), - attribute.Int("stateIteration iterations", iterations), - attribute.Int("hashCalculation time", int(hashCalculationTime.Milliseconds())), - ) - - return hash + return s.trie.Hash() } // Prepare sets the current transaction hash and index which are @@ -948,7 +900,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) } // Finalize any pending changes and merge everything into the tries - s.IntermediateRoot(context.Background(), deleteEmptyObjects) + s.IntermediateRoot(deleteEmptyObjects) // Commit objects to the trie, measuring the elapsed time var storageCommitted int diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 52cd5390c2..e9576d4dc4 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -18,7 +18,6 @@ package state import ( "bytes" - "context" "encoding/binary" "fmt" "math" @@ -55,7 +54,7 @@ func TestUpdateLeaks(t *testing.T) { } } - root := state.IntermediateRoot(context.Background(), false) + root := state.IntermediateRoot(false) if err := state.Database().TrieDB().Commit(root, false, nil); err != nil { t.Errorf("can not commit trie %v to persistent database", root.Hex()) } @@ -94,7 +93,7 @@ func TestIntermediateLeaks(t *testing.T) { modify(transState, common.Address{i}, i, 0) } // Write modifications to trie. - transState.IntermediateRoot(context.Background(), false) + transState.IntermediateRoot(false) // Overwrite all the data with new values in the transient database. for i := byte(0); i < 255; i++ { diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index a925c0e2af..10a1722940 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -17,7 +17,6 @@ package core import ( - "context" "sync/atomic" "github.com/ethereum/go-ethereum/consensus" @@ -74,12 +73,12 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c } // If we're pre-byzantium, pre-load trie nodes for the intermediate root if !byzantium { - statedb.IntermediateRoot(context.Background(), true) + statedb.IntermediateRoot(true) } } // If were post-byzantium, pre-load trie nodes for the final root hash if byzantium { - statedb.IntermediateRoot(context.Background(), true) + statedb.IntermediateRoot(true) } } diff --git a/core/state_processor.go b/core/state_processor.go index 6484cf93f3..d4c77ae410 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,7 +17,6 @@ package core import ( - "context" "fmt" "math/big" @@ -109,7 +108,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon if config.IsByzantium(blockNumber) { statedb.Finalise(true) } else { - root = statedb.IntermediateRoot(context.Background(), config.IsEIP158(blockNumber)).Bytes() + root = statedb.IntermediateRoot(config.IsEIP158(blockNumber)).Bytes() } *usedGas += result.UsedGas diff --git a/eth/api_test.go b/eth/api_test.go index 1793b0ffac..39a1d58460 100644 --- a/eth/api_test.go +++ b/eth/api_test.go @@ -18,7 +18,6 @@ package eth import ( "bytes" - "context" "fmt" "math/big" "reflect" @@ -85,7 +84,7 @@ func TestAccountRange(t *testing.T) { } } state.Commit(true) - root := state.IntermediateRoot(context.Background(), true) + root := state.IntermediateRoot(true) trie, err := statedb.OpenTrie(root) if err != nil { @@ -142,7 +141,7 @@ func TestEmptyAccountRange(t *testing.T) { st, _ = state.New(common.Hash{}, statedb, nil) ) st.Commit(true) - st.IntermediateRoot(context.Background(), true) + st.IntermediateRoot(true) results := st.IteratorDump(&state.DumpConfig{ SkipCode: true, SkipStorage: true, diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 47a93c8f8d..08c17601e4 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -544,7 +544,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config } // calling IntermediateRoot will internally call Finalize on the state // so any modifications are written to the trie - roots = append(roots, statedb.IntermediateRoot(context.Background(), deleteEmptyObjects)) + roots = append(roots, statedb.IntermediateRoot(deleteEmptyObjects)) } return roots, nil } diff --git a/eth/tracers/api_bor.go b/eth/tracers/api_bor.go index 5e118370ea..f42c7a27f7 100644 --- a/eth/tracers/api_bor.go +++ b/eth/tracers/api_bor.go @@ -108,7 +108,7 @@ func (api *API) traceBorBlock(ctx context.Context, block *types.Block, config *T } res := &TxTraceResult{ Result: result, - IntermediateHash: statedb.IntermediateRoot(context.Background(), deleteEmptyObjects), + IntermediateHash: statedb.IntermediateRoot(deleteEmptyObjects), } return res diff --git a/tests/state_test.go b/tests/state_test.go index 515a9cc9c8..f18b84d16e 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -22,7 +22,6 @@ package tests import ( "bufio" "bytes" - "context" "fmt" "math/big" "os" @@ -150,7 +149,7 @@ func TestState(t *testing.T) { withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { snaps, statedb, err := test.Run(subtest, vmconfig, true) if snaps != nil && statedb != nil { - if _, err := snaps.Journal(statedb.IntermediateRoot(context.Background(), false)); err != nil { + if _, err := snaps.Journal(statedb.IntermediateRoot(false)); err != nil { t.Errorf("in 'rlp_test.go', test '%s' failed with error: '%v'", name, err) return err } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 4d118c20f9..65f93bfbe3 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -17,7 +17,6 @@ package tests import ( - "context" "encoding/hex" "encoding/json" "fmt" @@ -246,7 +245,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh // the coinbase gets no txfee, so isn't created, and thus needs to be touched statedb.AddBalance(block.Coinbase(), new(big.Int)) // And _now_ get the state root - root := statedb.IntermediateRoot(context.Background(), config.IsEIP158(block.Number())) + root := statedb.IntermediateRoot(config.IsEIP158(block.Number())) return snaps, statedb, root, nil } From b6ff1331cd2a5f8a5833d6355fb2154b1a8ed9a3 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 29 Sep 2022 14:04:25 +0530 Subject: [PATCH 43/48] handle end span in bor.Seal function --- consensus/bor/bor.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 458c7554a0..554089c9b6 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -892,7 +892,13 @@ func (c *Bor) Authorize(currentSigner common.Address, signFn SignerFn) { // the local signing credentials. func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { _, sealSpan := tracing.StartSpan(ctx, "bor.Seal") - defer tracing.EndSpan(sealSpan) + var endSpan bool = true + defer func() { + // Only end span in case of early-returns/errors + if endSpan { + tracing.EndSpan(sealSpan) + } + }() header := block.Header() // Sealing the genesis block is not supported @@ -982,6 +988,9 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block } }(sealSpan) + // Set the endSpan flag to false, as the go routine will handle it + endSpan = false + return nil } From 91388bf24c4892b29f0b511b478bc4710e6717bf Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 29 Sep 2022 14:09:15 +0530 Subject: [PATCH 44/48] fix: typo --- consensus/bor/bor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 554089c9b6..0ea92873b1 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -749,7 +749,7 @@ func (c *Bor) Finalize(chain consensus.ChainHeaderReader, header *types.Header, } if c.HeimdallClient != nil { - // commit statees + // commit states stateSyncData, err = c.CommitStates(ctx, state, header, cx) if err != nil { log.Error("Error while committing states", "error", err) From f4a8a86448a909965f95e57d0e1e779cf32fc7c3 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 29 Sep 2022 14:26:37 +0530 Subject: [PATCH 45/48] minor fixes --- consensus/bor/bor.go | 3 +-- miner/worker.go | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 0ea92873b1..48da71062e 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -923,8 +923,7 @@ func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block // Bail out if we're unauthorized to sign a block if !snap.ValidatorSet.HasAddress(currentSigner.signer) { // Check the UnauthorizedSignerError.Error() msg to see why we pass number-1 - err := &UnauthorizedSignerError{number - 1, currentSigner.signer.Bytes()} - return err + return &UnauthorizedSignerError{number - 1, currentSigner.signer.Bytes()} } successionNumber, err := snap.GetSignerSuccessionNumber(currentSigner.signer) diff --git a/miner/worker.go b/miner/worker.go index 9f3cd77c23..797e7ea980 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -450,7 +450,7 @@ func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { // commit aborts in-flight transaction execution with given signal and resubmits a new one. commit := func(noempty bool, s int32) { // we close spans only by the place we created them - ctx, span := tracing.Trace(ctx, "worker.commit") + ctx, span := tracing.Trace(ctx, "worker.newWorkLoop.commit") tracing.EndSpan(span) if interrupt != nil { @@ -467,7 +467,7 @@ func (w *worker) newWorkLoop(ctx context.Context, recommit time.Duration) { } // clearPending cleans the stale pending tasks. clearPending := func(number uint64) { - _, span := tracing.Trace(ctx, "worker.clearPending") + _, span := tracing.Trace(ctx, "worker.newWorkLoop.clearPending") tracing.EndSpan(span) w.pendingMu.Lock() @@ -593,7 +593,7 @@ func (w *worker) mainLoop(ctx context.Context) { if err := w.commitUncle(w.current, ev.Block.Header()); err == nil { commitErr := w.commit(ctx, w.current.copy(), nil, true, start) if commitErr != nil { - log.Error("error while committing", commitErr) + log.Error("error while committing work for mining", "err", commitErr) } } } From c07ed79091157b5dad834f45cf07296c5d52a92a Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 29 Sep 2022 14:31:59 +0530 Subject: [PATCH 46/48] fix: linters --- consensus/bor/bor.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 48da71062e..dee3998703 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -892,7 +892,9 @@ func (c *Bor) Authorize(currentSigner common.Address, signFn SignerFn) { // the local signing credentials. func (c *Bor) Seal(ctx context.Context, chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { _, sealSpan := tracing.StartSpan(ctx, "bor.Seal") + var endSpan bool = true + defer func() { // Only end span in case of early-returns/errors if endSpan { From 6e6268bbdffd03f392aa51eb4f0c3554c09d165d Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 29 Sep 2022 16:40:54 +0530 Subject: [PATCH 47/48] fix: remove nolint --- core/tests/blockchain_repair_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/tests/blockchain_repair_test.go b/core/tests/blockchain_repair_test.go index 539638c90d..d99978a134 100644 --- a/core/tests/blockchain_repair_test.go +++ b/core/tests/blockchain_repair_test.go @@ -39,7 +39,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/miner" //nolint:typecheck + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/tests/bor/mocks" ) From 1d32559c72fe3f6ef3c22d24d0c0cb230b0b6eb6 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 29 Sep 2022 16:42:11 +0530 Subject: [PATCH 48/48] go mod tidy --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 27afbe5f07..18a2ca0ae7 100644 --- a/go.mod +++ b/go.mod @@ -122,7 +122,7 @@ require ( github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.0 // indirect github.com/opentracing/opentracing-go v1.1.0 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml v1.9.5 github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/posener/complete v1.1.1 // indirect @@ -134,7 +134,7 @@ require ( go.opentelemetry.io/proto/otlp v0.10.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/net v0.0.0-20220728030405-41545e8bf201 + golang.org/x/net v0.0.0-20220728030405-41545e8bf201 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect google.golang.org/genproto v0.0.0-20220725144611-272f38e5d71b // indirect