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.go50
1 files changed, 28 insertions, 22 deletions
diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go
index 87a983377..d2fb6934b 100644
--- a/consensus/clique/clique.go
+++ b/consensus/clique/clique.go
@@ -76,7 +76,7 @@ var (
errUnknownBlock = errors.New("unknown block")
// errInvalidCheckpointBeneficiary is returned if a checkpoint/epoch transition
- // block has a beneficiary set to non zeroes.
+ // block has a beneficiary set to non-zeroes.
errInvalidCheckpointBeneficiary = errors.New("beneficiary in checkpoint block non-zero")
// errInvalidVote is returned if a nonce value is something else that the two
@@ -84,7 +84,7 @@ var (
errInvalidVote = errors.New("vote nonce not 0x00..0 or 0xff..f")
// errInvalidCheckpointVote is returned if a checkpoint/epoch transition block
- // has a vote nonce set to non zeroes.
+ // has a vote nonce set to non-zeroes.
errInvalidCheckpointVote = errors.New("vote nonce in checkpoint block non-zero")
// errMissingVanity is returned if a block's extra-data section is shorter than
@@ -99,12 +99,12 @@ var (
// their extra-data fields.
errExtraSigners = errors.New("non-checkpoint block contains extra signer list")
- // drrInvalidCheckpointSigners is returned if a checkpoint block contains an
+ // errInvalidCheckpointSigners is returned if a checkpoint block contains an
// invalid list of signers (i.e. non divisible by 20 bytes, or not the correct
// ones).
- drrInvalidCheckpointSigners = errors.New("invalid signer list on checkpoint block")
+ errInvalidCheckpointSigners = errors.New("invalid signer list on checkpoint block")
- // errInvalidMixDigest is returned if a block's mix digest is non zero.
+ // errInvalidMixDigest is returned if a block's mix digest is non-zero.
errInvalidMixDigest = errors.New("non-zero mix digest")
// errInvalidUncleHash is returned if a block contains an non-empty uncle list.
@@ -122,7 +122,7 @@ var (
// be modified via out-of-range or non-contiguous headers.
errInvalidVotingChain = errors.New("invalid voting chain")
- // errUnauthorized is returned if a header is signed by a non authorized entity.
+ // errUnauthorized is returned if a header is signed by a non-authorized entity.
errUnauthorized = errors.New("unauthorized")
)
@@ -297,7 +297,7 @@ func (c *Clique) verifyHeader(chain consensus.ChainReader, header *types.Header,
return errExtraSigners
}
if checkpoint && signersBytes%common.AddressLength != 0 {
- return drrInvalidCheckpointSigners
+ return errInvalidCheckpointSigners
}
// Ensure that the mix digest is zero as we don't have fork protection currently
if header.MixDigest != (common.Hash{}) {
@@ -353,7 +353,7 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainReader, header *type
}
extraSuffix := len(header.Extra) - extraSeal
if !bytes.Equal(header.Extra[extraVanity:extraSuffix], signers) {
- return drrInvalidCheckpointSigners
+ return errInvalidCheckpointSigners
}
}
// All basic checks passed, verify the seal and return
@@ -467,7 +467,6 @@ func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, p
if err != nil {
return err
}
- c.recents.Add(snap.Hash, snap)
// Resolve the authorization key and check against signers
signer, err := ecrecover(header, c.signatures)
@@ -479,13 +478,13 @@ func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, p
}
for seen, recent := range snap.Recents {
if recent == signer {
- // Signer is among recents, only fail if the current block doens't shift it out
+ // Signer is among recents, only fail if the current block doesn't shift it out
if limit := uint64(len(snap.Signers)/2 + 1); seen > number-limit {
return errUnauthorized
}
}
}
- // Ensure that the difficulty corresponts to the turn-ness of the signer
+ // Ensure that the difficulty corresponds to the turn-ness of the signer
inturn := snap.inturn(header.Number.Uint64(), signer)
if inturn && header.Difficulty.Cmp(diffInTurn) != 0 {
return errInvalidDifficulty
@@ -499,18 +498,29 @@ func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, p
// Prepare implements consensus.Engine, preparing all the consensus fields of the
// header for running the transactions on top.
func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) error {
- // If the block isn't a checkpoint, cast a random vote (good enough fror now)
+ // If the block isn't a checkpoint, cast a random vote (good enough for now)
header.Coinbase = common.Address{}
header.Nonce = types.BlockNonce{}
number := header.Number.Uint64()
+
+ // Assemble the voting snapshot to check which votes make sense
+ snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
+ if err != nil {
+ return err
+ }
if number%c.config.Epoch != 0 {
c.lock.RLock()
- if len(c.proposals) > 0 {
- addresses := make([]common.Address, 0, len(c.proposals))
- for address := range c.proposals {
+
+ // Gather all the proposals that make sense voting on
+ addresses := make([]common.Address, 0, len(c.proposals))
+ for address, authorize := range c.proposals {
+ if snap.validVote(address, authorize) {
addresses = append(addresses, address)
}
+ }
+ // If there's pending proposals, cast a vote on them
+ if len(addresses) > 0 {
header.Coinbase = addresses[rand.Intn(len(addresses))]
if c.proposals[header.Coinbase] {
copy(header.Nonce[:], nonceAuthVote)
@@ -520,11 +530,7 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
}
c.lock.RUnlock()
}
- // Assemble the voting snapshot and set the correct difficulty
- snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
- if err != nil {
- return err
- }
+ // Set the correct difficulty
header.Difficulty = diffNoTurn
if snap.inturn(header.Number.Uint64(), c.signer) {
header.Difficulty = diffInTurn
@@ -601,10 +607,10 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch
if _, authorized := snap.Signers[signer]; !authorized {
return nil, errUnauthorized
}
- // If we're amongs the recent signers, wait for the next block
+ // If we're amongst the recent signers, wait for the next block
for seen, recent := range snap.Recents {
if recent == signer {
- // Signer is among recents, only wait if the current block doens't shift it out
+ // 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