diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index a1eaf83a30..3baa25bafc 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -754,13 +754,8 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea return errUnauthorizedValidator } - for seen, recent := range snap.Recents { - if recent == signer { - // Signer is among recents, only fail if the current block doesn't shift it out - if limit := uint64(len(snap.Validators)/2 + 1); seen > number-limit { - return errRecentlySigned - } - } + if snap.SignRecently(signer) { + return errRecentlySigned } // Ensure that the difficulty corresponds to the turn-ness of the signer @@ -1065,12 +1060,17 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade if header.Difficulty.Cmp(diffInTurn) != 0 { spoiledVal := snap.supposeValidator() signedRecently := false - for _, recent := range snap.Recents { - if recent == spoiledVal { - signedRecently = true - break + if p.chainConfig.IsPlato(header.Number) { + signedRecently = snap.SignRecently(spoiledVal) + } else { + for _, recent := range snap.Recents { + if recent == spoiledVal { + signedRecently = true + break + } } } + if !signedRecently { log.Trace("slash validator", "block hash", header.Hash(), "address", spoiledVal) err = p.slash(spoiledVal, state, header, cx, txs, receipts, systemTxs, usedGas, false) @@ -1123,10 +1123,14 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header * } spoiledVal := snap.supposeValidator() signedRecently := false - for _, recent := range snap.Recents { - if recent == spoiledVal { - signedRecently = true - break + if p.chainConfig.IsPlato(header.Number) { + signedRecently = snap.SignRecently(spoiledVal) + } else { + for _, recent := range snap.Recents { + if recent == spoiledVal { + signedRecently = true + break + } } } if !signedRecently { @@ -1294,14 +1298,8 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res } // If we're amongst the recent signers, wait for the next block - for seen, recent := range snap.Recents { - if recent == val { - // Signer is among recents, only wait if the current block doesn't shift it out - if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit { - log.Info("Signed recently, must wait for others") - return nil - } - } + if snap.SignRecently(val) { + return nil } // Sweet, the protocol permits us to sign the block, wait for our time @@ -1408,19 +1406,7 @@ func (p *Parlia) SignRecently(chain consensus.ChainReader, parent *types.Block) return true, errUnauthorizedValidator } - // If we're amongst the recent signers, wait for the next block - number := parent.NumberU64() + 1 - for seen, recent := range snap.Recents { - if recent != p.val { - continue - } - - // Signer is among recents, only wait if the current block doesn't shift it out - if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit { - return true, nil - } - } - return false, nil + return snap.SignRecently(p.val), nil } // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty diff --git a/consensus/parlia/snapshot.go b/consensus/parlia/snapshot.go index e7a9dea460..162f39d2cd 100644 --- a/consensus/parlia/snapshot.go +++ b/consensus/parlia/snapshot.go @@ -207,6 +207,17 @@ func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *params.C } } +func (s *Snapshot) SignRecently(validator common.Address) bool { + for seen, recent := range s.Recents { + if recent == validator { + if limit := uint64(len(s.Validators)/2 + 1); s.Number+1 < limit || seen > s.Number+1-limit { + return true + } + } + } + return false +} + func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderReader, parents []*types.Header, chainConfig *params.ChainConfig) (*Snapshot, error) { // Allow passing in no headers for cleaner code if len(headers) == 0 {