consensus/clique: choose valid votes

This commit is contained in:
mark.lin 2017-06-14 16:49:33 +08:00
parent 6171d01b11
commit db6e695002
2 changed files with 23 additions and 11 deletions

View File

@ -504,14 +504,23 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
header.Nonce = types.BlockNonce{} header.Nonce = types.BlockNonce{}
number := header.Number.Uint64() 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 { if number%c.config.Epoch != 0 {
// Get valid votes
c.lock.RLock() c.lock.RLock()
if len(c.proposals) > 0 { var addresses []common.Address
addresses := make([]common.Address, 0, len(c.proposals)) for address, authorize := range c.proposals {
for address := range c.proposals { if snap.validVote(address, authorize) {
addresses = append(addresses, address) 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] { if c.proposals[header.Coinbase] {
copy(header.Nonce[:], nonceAuthVote) copy(header.Nonce[:], nonceAuthVote)
} else { } else {
@ -520,11 +529,8 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
} }
c.lock.RUnlock() c.lock.RUnlock()
} }
// Assemble the voting snapshot and set the correct difficulty
snap, err := c.snapshot(chain, number-1, header.ParentHash, nil) // Set the correct difficulty
if err != nil {
return err
}
header.Difficulty = diffNoTurn header.Difficulty = diffNoTurn
if snap.inturn(header.Number.Uint64(), c.signer) { if snap.inturn(header.Number.Uint64(), c.signer) {
header.Difficulty = diffInTurn header.Difficulty = diffInTurn

View File

@ -126,11 +126,17 @@ func (s *Snapshot) copy() *Snapshot {
return cpy 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. // cast adds a new vote into the tally.
func (s *Snapshot) cast(address common.Address, authorize bool) bool { func (s *Snapshot) cast(address common.Address, authorize bool) bool {
// Ensure the vote is meaningful // Ensure the vote is meaningful
_, signer := s.Signers[address] if !s.validVote(address, authorize) {
if (signer && authorize) || (!signer && !authorize) {
return false return false
} }
// Cast the vote into an existing or new tally // Cast the vote into an existing or new tally