diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 05d8fbabc3..08189b0c93 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -374,6 +374,19 @@ func (c *Clique) GetSnapshot(chain consensus.ChainReader, header *types.Header) return snap, nil } +func position(list []common.Address, x common.Address) int { + for i, item := range list { + if item == x { + return i + } + } + return -1 +} + +func YourTurn(snap *Snapshot, pre, cur common.Address) bool { + return (position(snap.signers(), pre)+1) % len(snap.signers()) == position(snap.signers(), cur) +} + // snapshot retrieves the authorization snapshot at a given point in time. func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { // Search for a snapshot in memory or on disk for checkpoints diff --git a/miner/worker.go b/miner/worker.go index 4f9ce13d70..5646fe82be 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -397,6 +397,24 @@ func (self *worker) commitNewWork() { tstart := time.Now() parent := self.chain.CurrentBlock() + // Only try to commit new work if we are mining + if atomic.LoadInt32(&self.mining) == 1 { + // check if we are right after parent's coinbase in the list + // only go with Clique + if self.config.Clique != nil { + c := self.engine.(*clique.Clique) + snap, err := c.GetSnapshot(self.chain, parent.Header()) + if err != nil { + log.Error("Failed when trying to commit new work", "err", err) + return + } + if !clique.YourTurn(snap, parent.Coinbase(), self.coinbase) { + log.Info("Not our turn to commit block", "wait") + return + } + } + } + tstamp := tstart.Unix() if parent.Time().Cmp(new(big.Int).SetInt64(tstamp)) >= 0 { tstamp = parent.Time().Int64() + 1