From db6e6950029e97be34b9aa27c5a05ba44495091d Mon Sep 17 00:00:00 2001 From: "mark.lin" Date: Wed, 14 Jun 2017 16:49:33 +0800 Subject: [PATCH 1/2] consensus/clique: choose valid votes --- consensus/clique/clique.go | 24 +++++++++++++++--------- consensus/clique/snapshot.go | 10 ++++++++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 87a983377..7af881ab8 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -504,14 +504,23 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro header.Nonce = types.BlockNonce{} number := header.Number.Uint64() + // Assemble the voting snapshot + snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + return err + } if number%c.config.Epoch != 0 { + // Get valid votes c.lock.RLock() - if len(c.proposals) > 0 { - addresses := make([]common.Address, 0, len(c.proposals)) - for address := range c.proposals { + var addresses []common.Address + for address, authorize := range c.proposals { + if snap.validVote(address, authorize) { addresses = append(addresses, address) } - header.Coinbase = addresses[rand.Intn(len(addresses))] + } + if len(addresses) > 0 { + index := rand.Intn(len(addresses)) + header.Coinbase = addresses[index] if c.proposals[header.Coinbase] { copy(header.Nonce[:], nonceAuthVote) } else { @@ -520,11 +529,8 @@ 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 diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go index fb86bc5e6..a17395f3c 100644 --- a/consensus/clique/snapshot.go +++ b/consensus/clique/snapshot.go @@ -126,11 +126,17 @@ func (s *Snapshot) copy() *Snapshot { return cpy } +// validVote returns whether it makes sense to cast the specified vote in the +// given snapshot context (e.g. don't try to add an already authorized signer). +func (s *Snapshot) validVote(address common.Address, authorize bool) bool { + _, signer := s.Signers[address] + return (signer && !authorize) || (!signer && authorize) +} + // cast adds a new vote into the tally. func (s *Snapshot) cast(address common.Address, authorize bool) bool { // Ensure the vote is meaningful - _, signer := s.Signers[address] - if (signer && authorize) || (!signer && !authorize) { + if !s.validVote(address, authorize) { return false } // Cast the vote into an existing or new tally From 514659a023dc5d7bf8bac002d72c38a1ad1e3bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 23 Jun 2017 11:05:20 +0300 Subject: [PATCH 2/2] consensus/clique: minor cleanups --- consensus/clique/clique.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 7af881ab8..b3bb1b290 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -504,23 +504,25 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro header.Nonce = types.BlockNonce{} number := header.Number.Uint64() - // Assemble the voting snapshot + + // 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 { - // Get valid votes c.lock.RLock() - var addresses []common.Address + + // 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 { - index := rand.Intn(len(addresses)) - header.Coinbase = addresses[index] + header.Coinbase = addresses[rand.Intn(len(addresses))] if c.proposals[header.Coinbase] { copy(header.Nonce[:], nonceAuthVote) } else { @@ -529,7 +531,6 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro } c.lock.RUnlock() } - // Set the correct difficulty header.Difficulty = diffNoTurn if snap.inturn(header.Number.Uint64(), c.signer) {