diff --git a/miner/worker.go b/miner/worker.go index 629ce5bd2..3500ca4c2 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -111,6 +111,7 @@ const ( type newWorkReq struct { interrupt *int32 noempty bool + timestamp int64 } // intervalAdjust represents a resubmitting interval adjustment. @@ -285,6 +286,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) { var ( interrupt *int32 minRecommit = recommit // minimal resubmit interval specified by user. + timestamp int64 // timestamp for each round of mining. ) timer := time.NewTimer(0) @@ -296,7 +298,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) { atomic.StoreInt32(interrupt, s) } interrupt = new(int32) - w.newWorkCh <- &newWorkReq{interrupt: interrupt, noempty: noempty} + w.newWorkCh <- &newWorkReq{interrupt: interrupt, noempty: noempty, timestamp: timestamp} timer.Reset(recommit) atomic.StoreInt32(&w.newTxs, 0) } @@ -336,10 +338,12 @@ func (w *worker) newWorkLoop(recommit time.Duration) { select { case <-w.startCh: clearPending(w.chain.CurrentBlock().NumberU64()) + timestamp = time.Now().Unix() commit(false, commitInterruptNewHead) case head := <-w.chainHeadCh: clearPending(head.Block.NumberU64()) + timestamp = time.Now().Unix() commit(false, commitInterruptNewHead) case <-timer.C: @@ -398,7 +402,7 @@ func (w *worker) mainLoop() { for { select { case req := <-w.newWorkCh: - w.commitNewWork(req.interrupt, req.noempty) + w.commitNewWork(req.interrupt, req.noempty, req.timestamp) case ev := <-w.chainSideCh: if _, exist := w.possibleUncles[ev.Block.Hash()]; exist { @@ -450,7 +454,7 @@ func (w *worker) mainLoop() { } else { // If we're mining, but nothing is being processed, wake on new transactions if w.config.Clique != nil && w.config.Clique.Period == 0 { - w.commitNewWork(nil, false) + w.commitNewWork(nil, false, time.Now().Unix()) } } atomic.AddInt32(&w.newTxs, int32(len(ev.Txs))) @@ -793,20 +797,19 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin } // commitNewWork generates several new sealing tasks based on the parent block. -func (w *worker) commitNewWork(interrupt *int32, noempty bool) { +func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) { w.mu.RLock() defer w.mu.RUnlock() tstart := time.Now() parent := w.chain.CurrentBlock() - tstamp := tstart.Unix() - if parent.Time().Cmp(new(big.Int).SetInt64(tstamp)) >= 0 { - tstamp = parent.Time().Int64() + 1 + if parent.Time().Cmp(new(big.Int).SetInt64(timestamp)) >= 0 { + timestamp = parent.Time().Int64() + 1 } // this will ensure we're not going off too far in the future - if now := time.Now().Unix(); tstamp > now+1 { - wait := time.Duration(tstamp-now) * time.Second + if now := time.Now().Unix(); timestamp > now+1 { + wait := time.Duration(timestamp-now) * time.Second log.Info("Mining too far in the future", "wait", common.PrettyDuration(wait)) time.Sleep(wait) } @@ -817,7 +820,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool) { Number: num.Add(num, common.Big1), GasLimit: core.CalcGasLimit(parent, w.gasFloor, w.gasCeil), Extra: w.extra, - Time: big.NewInt(tstamp), + Time: big.NewInt(timestamp), } // Only set the coinbase if our consensus engine is running (avoid spurious block rewards) if w.isRunning() {