From d599917e9ee65adfa9706e0b461db32dddf997a5 Mon Sep 17 00:00:00 2001 From: andrepatta <9854773+andrepatta@users.noreply.github.com> Date: Mon, 3 Nov 2025 04:52:37 -0300 Subject: [PATCH 1/2] miner: update min/max recommit interval values and make timestamp always refresh --- miner/worker.go | 18 +++++++++--------- miner/worker_test.go | 32 ++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 1dd2083..3d27e45 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -59,11 +59,11 @@ const ( // minRecommitInterval is the minimal time interval to recreate the sealing block with // any newly arrived transactions. - minRecommitInterval = 1 * time.Second + minRecommitInterval = 5 * time.Second // maxRecommitInterval is the maximum time interval to recreate the sealing block with // any newly arrived transactions. - maxRecommitInterval = 15 * time.Second + maxRecommitInterval = 2 * time.Minute // intervalAdjustRatio is the impact a single interval adjustment has on sealing work // resubmitting interval. @@ -450,14 +450,14 @@ func (w *worker) newWorkLoop(recommit time.Duration) { commit(false, commitInterruptNewHead) case <-timer.C: - // If sealing is running resubmit a new work cycle periodically to pull in - // higher priced transactions. Disable this overhead for pending blocks. + // Periodically rebuild sealing work so the header timestamp stays fresh, + // even if no new transactions arrived. if w.isRunning() && (w.chainConfig.Clique == nil || w.chainConfig.Clique.Period > 0) { - // Short circuit if no new transaction arrives. - if atomic.LoadInt32(&w.newTxs) == 0 { - timer.Reset(recommit) - continue - } + // Always refresh the timestamp used for the next block template. + timestamp = time.Now().Unix() + // Always (re)commit a fresh template on the timer to avoid hashing + // an old header for minutes and then submitting a stale-timestamp block. + log.Info("Update block header timestamp", "time", timestamp) commit(true, commitInterruptResubmit) } diff --git a/miner/worker_test.go b/miner/worker_test.go index e6b6be1..9c32225 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -261,7 +261,7 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool) { if _, err := chain.InsertChain([]*types.Block{block}); err != nil { t.Fatalf("failed to insert new mined block %d: %v", block.NumberU64(), err) } - case <-time.After(3 * time.Second): // Worker needs 1s to include new changes. + case <-time.After(10 * time.Second): // Worker needs 5s to include new changes. t.Fatalf("timeout") } } @@ -366,7 +366,7 @@ func testRegenerateMiningBlock(t *testing.T, chainConfig *params.ChainConfig, en for i := 0; i < 2; i += 1 { select { case <-taskCh: - case <-time.NewTimer(time.Second).C: + case <-time.NewTimer(10 * time.Second).C: t.Error("new task timeout") } } @@ -375,7 +375,7 @@ func testRegenerateMiningBlock(t *testing.T, chainConfig *params.ChainConfig, en select { case <-taskCh: - case <-time.NewTimer(time.Second).C: + case <-time.NewTimer(10 * time.Second).C: t.Error("new task timeout") } } @@ -415,18 +415,26 @@ func testAdjustInterval(t *testing.T, chainConfig *params.ChainConfig, engine co switch index { case 0: - wantMinInterval, wantRecommitInterval = 3*time.Second, 3*time.Second + // setRecommitInterval(3s) → clamped to new min (5s) + wantMinInterval, wantRecommitInterval = 5*time.Second, 5*time.Second case 1: - origin := float64(3 * time.Second.Nanoseconds()) - estimate := origin*(1-intervalAdjustRatio) + intervalAdjustRatio*(origin/0.8+intervalAdjustBias) - wantMinInterval, wantRecommitInterval = 3*time.Second, time.Duration(estimate)*time.Nanosecond + // inc=true, ratio=0.8, starting from prev=5s + // recalc: next = prev*(1-a) + a*(prev/ratio + bias) + // where a=intervalAdjustRatio (0.1), bias=intervalAdjustBias (200ms) + prev := float64((5 * time.Second).Nanoseconds()) + estimate := prev*(1-intervalAdjustRatio) + + intervalAdjustRatio*(prev/0.8+intervalAdjustBias) + wantMinInterval, wantRecommitInterval = 5*time.Second, time.Duration(estimate)*time.Nanosecond case 2: - estimate := result[index-1] - min := float64(3 * time.Second.Nanoseconds()) - estimate = estimate*(1-intervalAdjustRatio) + intervalAdjustRatio*(min-intervalAdjustBias) - wantMinInterval, wantRecommitInterval = 3*time.Second, time.Duration(estimate)*time.Nanosecond + // dec=false → drift back toward min with negative bias + prev := result[index-1] // nanoseconds from previous hook call + min := float64((5 * time.Second).Nanoseconds()) + estimate := prev*(1-intervalAdjustRatio) + + intervalAdjustRatio*(min-intervalAdjustBias) + wantMinInterval, wantRecommitInterval = 5*time.Second, time.Duration(estimate)*time.Nanosecond case 3: - wantMinInterval, wantRecommitInterval = time.Second, time.Second + // setRecommitInterval(500ms) → clamped to new min (5s) + wantMinInterval, wantRecommitInterval = 5*time.Second, 5*time.Second } // Check interval From 2ef4dc9576933f969a8820a9b3d4b545f8ee15e3 Mon Sep 17 00:00:00 2001 From: andrepatta <9854773+andrepatta@users.noreply.github.com> Date: Mon, 3 Nov 2025 04:53:00 -0300 Subject: [PATCH 2/2] prlconfig: set default recommit interval to 20 seconds --- prl/prlconfig/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prl/prlconfig/config.go b/prl/prlconfig/config.go index 36edb3d..5914886 100644 --- a/prl/prlconfig/config.go +++ b/prl/prlconfig/config.go @@ -85,7 +85,7 @@ var Defaults = Config{ Miner: miner.Config{ GasCeil: 600000000, GasPrice: big.NewInt(params.GWei), - Recommit: 3 * time.Second, + Recommit: 20 * time.Second, }, TxPool: core.DefaultTxPoolConfig, RPCGasCap: 600000000,