Skip to content

Commit 647b200

Browse files
authored
Merge pull request #2 from microstack-tech/fix_recommit_interval
Fix: Fresh block timestamps + sensible recommit bounds for PoW mining
2 parents 290d597 + 2ef4dc9 commit 647b200

File tree

3 files changed

+30
-22
lines changed

3 files changed

+30
-22
lines changed

miner/worker.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ const (
5959

6060
// minRecommitInterval is the minimal time interval to recreate the sealing block with
6161
// any newly arrived transactions.
62-
minRecommitInterval = 1 * time.Second
62+
minRecommitInterval = 5 * time.Second
6363

6464
// maxRecommitInterval is the maximum time interval to recreate the sealing block with
6565
// any newly arrived transactions.
66-
maxRecommitInterval = 15 * time.Second
66+
maxRecommitInterval = 2 * time.Minute
6767

6868
// intervalAdjustRatio is the impact a single interval adjustment has on sealing work
6969
// resubmitting interval.
@@ -450,14 +450,14 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
450450
commit(false, commitInterruptNewHead)
451451

452452
case <-timer.C:
453-
// If sealing is running resubmit a new work cycle periodically to pull in
454-
// higher priced transactions. Disable this overhead for pending blocks.
453+
// Periodically rebuild sealing work so the header timestamp stays fresh,
454+
// even if no new transactions arrived.
455455
if w.isRunning() && (w.chainConfig.Clique == nil || w.chainConfig.Clique.Period > 0) {
456-
// Short circuit if no new transaction arrives.
457-
if atomic.LoadInt32(&w.newTxs) == 0 {
458-
timer.Reset(recommit)
459-
continue
460-
}
456+
// Always refresh the timestamp used for the next block template.
457+
timestamp = time.Now().Unix()
458+
// Always (re)commit a fresh template on the timer to avoid hashing
459+
// an old header for minutes and then submitting a stale-timestamp block.
460+
log.Info("Update block header timestamp", "time", timestamp)
461461
commit(true, commitInterruptResubmit)
462462
}
463463

miner/worker_test.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool) {
261261
if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
262262
t.Fatalf("failed to insert new mined block %d: %v", block.NumberU64(), err)
263263
}
264-
case <-time.After(3 * time.Second): // Worker needs 1s to include new changes.
264+
case <-time.After(10 * time.Second): // Worker needs 5s to include new changes.
265265
t.Fatalf("timeout")
266266
}
267267
}
@@ -366,7 +366,7 @@ func testRegenerateMiningBlock(t *testing.T, chainConfig *params.ChainConfig, en
366366
for i := 0; i < 2; i += 1 {
367367
select {
368368
case <-taskCh:
369-
case <-time.NewTimer(time.Second).C:
369+
case <-time.NewTimer(10 * time.Second).C:
370370
t.Error("new task timeout")
371371
}
372372
}
@@ -375,7 +375,7 @@ func testRegenerateMiningBlock(t *testing.T, chainConfig *params.ChainConfig, en
375375

376376
select {
377377
case <-taskCh:
378-
case <-time.NewTimer(time.Second).C:
378+
case <-time.NewTimer(10 * time.Second).C:
379379
t.Error("new task timeout")
380380
}
381381
}
@@ -415,18 +415,26 @@ func testAdjustInterval(t *testing.T, chainConfig *params.ChainConfig, engine co
415415

416416
switch index {
417417
case 0:
418-
wantMinInterval, wantRecommitInterval = 3*time.Second, 3*time.Second
418+
// setRecommitInterval(3s) → clamped to new min (5s)
419+
wantMinInterval, wantRecommitInterval = 5*time.Second, 5*time.Second
419420
case 1:
420-
origin := float64(3 * time.Second.Nanoseconds())
421-
estimate := origin*(1-intervalAdjustRatio) + intervalAdjustRatio*(origin/0.8+intervalAdjustBias)
422-
wantMinInterval, wantRecommitInterval = 3*time.Second, time.Duration(estimate)*time.Nanosecond
421+
// inc=true, ratio=0.8, starting from prev=5s
422+
// recalc: next = prev*(1-a) + a*(prev/ratio + bias)
423+
// where a=intervalAdjustRatio (0.1), bias=intervalAdjustBias (200ms)
424+
prev := float64((5 * time.Second).Nanoseconds())
425+
estimate := prev*(1-intervalAdjustRatio) +
426+
intervalAdjustRatio*(prev/0.8+intervalAdjustBias)
427+
wantMinInterval, wantRecommitInterval = 5*time.Second, time.Duration(estimate)*time.Nanosecond
423428
case 2:
424-
estimate := result[index-1]
425-
min := float64(3 * time.Second.Nanoseconds())
426-
estimate = estimate*(1-intervalAdjustRatio) + intervalAdjustRatio*(min-intervalAdjustBias)
427-
wantMinInterval, wantRecommitInterval = 3*time.Second, time.Duration(estimate)*time.Nanosecond
429+
// dec=false → drift back toward min with negative bias
430+
prev := result[index-1] // nanoseconds from previous hook call
431+
min := float64((5 * time.Second).Nanoseconds())
432+
estimate := prev*(1-intervalAdjustRatio) +
433+
intervalAdjustRatio*(min-intervalAdjustBias)
434+
wantMinInterval, wantRecommitInterval = 5*time.Second, time.Duration(estimate)*time.Nanosecond
428435
case 3:
429-
wantMinInterval, wantRecommitInterval = time.Second, time.Second
436+
// setRecommitInterval(500ms) → clamped to new min (5s)
437+
wantMinInterval, wantRecommitInterval = 5*time.Second, 5*time.Second
430438
}
431439

432440
// Check interval

prl/prlconfig/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ var Defaults = Config{
8585
Miner: miner.Config{
8686
GasCeil: 600000000,
8787
GasPrice: big.NewInt(params.GWei),
88-
Recommit: 3 * time.Second,
88+
Recommit: 20 * time.Second,
8989
},
9090
TxPool: core.DefaultTxPoolConfig,
9191
RPCGasCap: 600000000,

0 commit comments

Comments
 (0)