|
|
|
@ -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() { |
|
|
|
|