aboutsummaryrefslogtreecommitdiffstats
path: root/consensus/clique/clique.go
diff options
context:
space:
mode:
Diffstat (limited to 'consensus/clique/clique.go')
-rw-r--r--consensus/clique/clique.go39
1 files changed, 23 insertions, 16 deletions
diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go
index 3730c91f6..547290984 100644
--- a/consensus/clique/clique.go
+++ b/consensus/clique/clique.go
@@ -590,17 +590,17 @@ func (c *Clique) Authorize(signer common.Address, signFn SignerFn) {
// Seal implements consensus.Engine, attempting to create a sealed block using
// the local signing credentials.
-func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
+func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
header := block.Header()
// Sealing the genesis block is not supported
number := header.Number.Uint64()
if number == 0 {
- return nil, errUnknownBlock
+ return errUnknownBlock
}
// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
if c.config.Period == 0 && len(block.Transactions()) == 0 {
- return nil, errWaitTransactions
+ return errWaitTransactions
}
// Don't hold the signer fields for the entire sealing procedure
c.lock.RLock()
@@ -610,10 +610,10 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch
// Bail out if we're unauthorized to sign a block
snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
if err != nil {
- return nil, err
+ return err
}
if _, authorized := snap.Signers[signer]; !authorized {
- return nil, errUnauthorized
+ return errUnauthorized
}
// If we're amongst the recent signers, wait for the next block
for seen, recent := range snap.Recents {
@@ -621,8 +621,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch
// Signer is among recents, only wait if the current block doesn't shift it out
if limit := uint64(len(snap.Signers)/2 + 1); number < limit || seen > number-limit {
log.Info("Signed recently, must wait for others")
- <-stop
- return nil, nil
+ return nil
}
}
}
@@ -635,21 +634,29 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch
log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
}
- log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay))
-
- select {
- case <-stop:
- return nil, nil
- case <-time.After(delay):
- }
// Sign all the things!
sighash, err := signFn(accounts.Account{Address: signer}, sigHash(header).Bytes())
if err != nil {
- return nil, err
+ return err
}
copy(header.Extra[len(header.Extra)-extraSeal:], sighash)
+ // Wait until sealing is terminated or delay timeout.
+ log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay))
+ go func() {
+ select {
+ case <-stop:
+ return
+ case <-time.After(delay):
+ }
- return block.WithSeal(header), nil
+ select {
+ case results <- block.WithSeal(header):
+ default:
+ log.Warn("Sealing result is not read by miner", "sealhash", c.SealHash(header))
+ }
+ }()
+
+ return nil
}
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty