diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 58754c59417882fb95d433439e64f92a9217cb72..a32543f087494a444337916ffbe2dde63c3a4169 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -201,8 +201,8 @@ func encodeSigHeader(w io.Writer, header *types.Header) { // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty // that a new block should have based on the previous blocks in the chain and the // current signer. -func CalcDifficulty(snap *Snapshot, signer common.Address, epoch uint64) *big.Int { - return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, epoch)) +func CalcDifficulty(snap *Snapshot, signer common.Address, sprint uint64) *big.Int { + return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, sprint)) } // CalcProducerDelay is the block delay algorithm based on block time and period / producerDelay values in genesis @@ -439,15 +439,6 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H for i, validator := range currentValidators { copy(validatorsBytes[i*validatorHeaderBytesLength:], validator.HeaderBytes()) } - - extraSuffix := len(header.Extra) - extraSeal - - // fmt.Println("validatorsBytes ==> verify seal ==> ", hex.EncodeToString(validatorsBytes)) - // fmt.Println("header.Extra ==> verify seal ==> ", hex.EncodeToString(header.Extra[extraVanity:extraSuffix])) - - if !bytes.Equal(header.Extra[extraVanity:extraSuffix], validatorsBytes) { - // return errMismatchingSprintValidators - } } // All basic checks passed, verify the seal and return @@ -591,27 +582,9 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare return errUnauthorizedSigner } - // check if signer is correct - validators := snap.ValidatorSet.Validators - // proposer will be the last signer if block is not epoch block proposer := snap.ValidatorSet.GetProposer().Address - if number%c.config.Sprint != 0 { - // proposer = snap.Recents[number-1] - } - proposerIndex, _ := snap.ValidatorSet.GetByAddress(proposer) - signerIndex, _ := snap.ValidatorSet.GetByAddress(signer) - limit := len(validators)/2 + 1 - - // temp index - tempIndex := signerIndex - if proposerIndex != tempIndex && limit > 0 { - if tempIndex < proposerIndex { - tempIndex = tempIndex + len(validators) - } - - if tempIndex-proposerIndex > limit { - return errRecentlySigned - } + if _, err = snap.getSignerSuccessionNumber(signer, proposer); err != nil { + return err } // Ensure that the difficulty corresponds to the turn-ness of the signer @@ -775,31 +748,15 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan return errUnauthorizedSigner } - validators := snap.ValidatorSet.Validators - // proposer will be the last signer if block is not epoch block proposer := snap.ValidatorSet.GetProposer().Address - if number%c.config.Sprint != 0 { - // proposer = snap.Recents[number-1] - } - - proposerIndex, _ := snap.ValidatorSet.GetByAddress(proposer) - signerIndex, _ := snap.ValidatorSet.GetByAddress(signer) - limit := len(validators)/2 + 1 - - // temp index - tempIndex := signerIndex - if tempIndex < proposerIndex { - tempIndex = tempIndex + len(validators) - } - - if limit > 0 && tempIndex-proposerIndex > limit { - log.Info("Signed recently, must wait for others") - return nil + successionNumber, err := snap.getSignerSuccessionNumber(signer, proposer) + if err != nil { + return err } // Sweet, the protocol permits us to sign the block, wait for our time delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple - wiggle := time.Duration(2*c.config.Period) * time.Second * time.Duration(tempIndex-proposerIndex) + wiggle := time.Duration(2*c.config.Period) * time.Second * time.Duration(successionNumber) delay += wiggle log.Info("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) @@ -863,7 +820,7 @@ func (c *Bor) Close() error { return nil } -// Checks if new span is pending +// Checks if "force" proposeSpan has been set func (c *Bor) isSpanPending(snapshotNumber uint64) (bool, error) { blockNr := rpc.BlockNumber(snapshotNumber) method := "spanProposalPending" @@ -875,14 +832,10 @@ func (c *Bor) isSpanPending(snapshotNumber uint64) (bool, error) { return false, err } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // cancel when we are finished consuming integers - - // call msgData := (hexutil.Bytes)(data) toAddress := common.HexToAddress(c.config.ValidatorContract) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{ + result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ Gas: &gas, To: &toAddress, Data: &msgData, @@ -913,14 +866,10 @@ func (c *Bor) GetCurrentSpan(snapshotNumber uint64) (*Span, error) { return nil, err } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // cancel when we are finished consuming integers - - // call msgData := (hexutil.Bytes)(data) toAddress := common.HexToAddress(c.config.ValidatorContract) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{ + result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ Gas: &gas, To: &toAddress, Data: &msgData, @@ -963,14 +912,11 @@ func (c *Bor) GetCurrentValidators(snapshotNumber uint64, blockNumber uint64) ([ return nil, err } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // cancel when we are finished consuming integers - // call msgData := (hexutil.Bytes)(data) toAddress := common.HexToAddress(c.config.ValidatorContract) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{ + result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ Gas: &gas, To: &toAddress, Data: &msgData, @@ -1153,13 +1099,10 @@ func (c *Bor) GetPendingStateProposals(snapshotNumber uint64) ([]*big.Int, error return nil, err } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // cancel when we are finished consuming integers - msgData := (hexutil.Bytes)(data) toAddress := common.HexToAddress(c.config.StateReceiverContract) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{ + result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ Gas: &gas, To: &toAddress, Data: &msgData, diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 7707719462af995356549c8847b4ce2fd21f7eb1..f0bd723ef54b4cca69aa237f0117a24917c5562f 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -158,34 +158,9 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { return nil, errUnauthorizedSigner } - // - // Check validator - // - - validators := snap.ValidatorSet.Validators - // proposer will be the last signer if block is not epoch block proposer := snap.ValidatorSet.GetProposer().Address - proposerIndex, _ := snap.ValidatorSet.GetByAddress(proposer) - if proposerIndex == -1 { - return nil, &ProposerNotFoundError{proposer} - } - signerIndex, _ := snap.ValidatorSet.GetByAddress(signer) - if signerIndex == -1 { - return nil, &SignerNotFoundError{signer} - } - limit := len(validators)/2 + 1 - - // temp index - tempIndex := signerIndex - if proposerIndex != tempIndex && limit > 0 { - if tempIndex < proposerIndex { - tempIndex = tempIndex + len(validators) - } - - if tempIndex-proposerIndex > limit { - log.Info("Invalid signer: error while applying headers", "proposerIndex", validators[proposerIndex].Address.Hex(), "signerIndex", validators[signerIndex].Address.Hex()) - return nil, errRecentlySigned - } + if _, err = snap.getSignerSuccessionNumber(signer, proposer); err != nil { + return nil, err } // add recents @@ -211,6 +186,40 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { return snap, nil } +// getSignerSuccessionNumber returns the relative position of signer in terms of the in-turn proposer +func (s *Snapshot) getSignerSuccessionNumber(signer common.Address, proposer common.Address) (int, error) { + validators := s.ValidatorSet.Validators + // bor.verifySeal and bor.Seal has the following commented out. + // TODO DISCUSS WITH JD if this is required + // If it is, we will also need to send in header.Number as parameter + // if number%c.config.Sprint != 0 { + // proposer = snap.Recents[number-1] + // } + + proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer) + if proposerIndex == -1 { + return -1, &ProposerNotFoundError{proposer} + } + signerIndex, _ := s.ValidatorSet.GetByAddress(signer) + if signerIndex == -1 { + return -1, &SignerNotFoundError{signer} + } + limit := len(validators)/2 + 1 + + tempIndex := signerIndex + if proposerIndex != tempIndex && limit > 0 { + if tempIndex < proposerIndex { + tempIndex = tempIndex + len(validators) + } + + if tempIndex-proposerIndex > limit { + log.Info("errRecentlySigned", "proposerIndex", validators[proposerIndex].Address.Hex(), "signerIndex", validators[signerIndex].Address.Hex()) + return -1, errRecentlySigned + } + } + return tempIndex - proposerIndex, nil +} + // signers retrieves the list of authorized signers in ascending order. func (s *Snapshot) signers() []common.Address { sigs := make([]common.Address, 0, len(s.ValidatorSet.Validators))