diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 51174c4789..d4279a5465 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -395,6 +395,16 @@ func position(list []common.Address, x common.Address) int { return -1 } +func (c *Clique) GetMasternodes(chain consensus.ChainReader, header *types.Header) []common.Address { + lastCheckpointNumber := header.Number.Uint64() - (header.Number.Uint64() % c.config.Epoch) + preCheckpointHeader := chain.GetHeaderByNumber(lastCheckpointNumber) + masternodes := make([]common.Address, (len(preCheckpointHeader.Extra)-extraVanity-extraSeal)/common.AddressLength) + for i := 0; i < len(masternodes); i++ { + copy(masternodes[i][:], preCheckpointHeader.Extra[extraVanity+i*common.AddressLength:]) + } + return masternodes +} + func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header, cur common.Address) (bool, error) { if header.Number.Uint64() == 0 { // Not check signer for genesis block. @@ -414,14 +424,6 @@ func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header return (preIndex+1)%len(masternodes) == curIndex, nil } -func GetExtraVanity() int { - return extraVanity -} - -func GetExtraSeal() int { - return extraSeal -} - // 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 @@ -536,7 +538,17 @@ func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, p return err } if _, ok := snap.Signers[signer]; !ok { - return errUnauthorized + valid := false + masternodes := c.GetMasternodes(chain, header) + for _, m := range masternodes { + if m == signer { + valid = true + break + } + } + if !valid { + return errUnauthorized + } } for seen, recent := range snap.Recents { if recent == signer { @@ -702,7 +714,17 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, stop <-ch return nil, err } if _, authorized := snap.Signers[signer]; !authorized { - return nil, errUnauthorized + valid := false + masternodes := c.GetMasternodes(chain, header) + for _, m := range masternodes { + if m == signer { + valid = true + break + } + } + if !valid { + return nil, errUnauthorized + } } // If we're amongst the recent signers, wait for the next block for seen, recent := range snap.Recents { diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go index 9ebdb8df15..1121f2443a 100644 --- a/consensus/clique/snapshot.go +++ b/consensus/clique/snapshot.go @@ -205,14 +205,15 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { if err != nil { return nil, err } - if _, ok := snap.Signers[signer]; !ok { - return nil, errUnauthorized - } - for _, recent := range snap.Recents { - if recent == signer { - return nil, errUnauthorized - } - } + //FIXME: skip signer checking at this step until a good solution found + //if _, ok := snap.Signers[signer]; !ok { + // return nil, errUnauthorized + //} + //for _, recent := range snap.Recents { + // if recent == signer { + // return nil, errUnauthorized + // } + //} snap.Recents[number] = signer // Header authorized, discard any previous votes from the signer @@ -307,4 +308,4 @@ func (s *Snapshot) inturn(number uint64, signer common.Address) bool { offset++ } return (number % uint64(len(signers))) == uint64(offset) -} +} \ No newline at end of file diff --git a/miner/worker.go b/miner/worker.go index 557f915b91..6292468098 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -348,8 +348,18 @@ func (self *worker) wait() { return } if _, authorized := snap.Signers[self.coinbase]; !authorized { - log.Error("Coinbase address not in snapshot signers.") - return + valid := false + masternodes := c.GetMasternodes(self.chain, block.Header()) + for _, m := range masternodes { + if m == self.coinbase { + valid = true + break + } + } + if !valid { + log.Error("Coinbase address not in snapshot signers.") + return + } } // Send tx sign to smart contract blockSigners. if err := contracts.CreateTransactionSign(self.config, self.eth.TxPool(), self.eth.AccountManager(), block); err != nil { @@ -422,15 +432,8 @@ func (self *worker) commitNewWork() { // only go with Clique if self.config.Clique != nil { // get masternodes set from latest checkpoint - lastCheckpointNumber := parent.NumberU64() - (parent.NumberU64() % self.config.Clique.Epoch) - preCheckpointHeader := self.chain.GetHeaderByNumber(lastCheckpointNumber) - extraVanity := clique.GetExtraVanity() - extraSeal := clique.GetExtraSeal() - masternodes := make([]common.Address, (len(preCheckpointHeader.Extra)-extraVanity-extraSeal)/common.AddressLength) - for i := 0; i < len(masternodes); i++ { - copy(masternodes[i][:], preCheckpointHeader.Extra[extraVanity+i*common.AddressLength:]) - } c := self.engine.(*clique.Clique) + masternodes := c.GetMasternodes(self.chain, parent.Header()) snap, err := c.GetSnapshot(self.chain, parent.Header()) if err != nil { log.Error("Failed when trying to commit new work", "err", err)