Exemple #1
0
// Returns whether +2/3 have prevoted/committed for BlockHash.
func (pol *POL) Verify(valSet *sm.ValidatorSet) error {

	if uint(len(pol.Votes)) != valSet.Size() {
		return fmt.Errorf("Invalid POL votes count: Expected %v, got %v",
			valSet.Size(), len(pol.Votes))
	}

	talliedVotingPower := uint64(0)
	prevoteDoc := account.SignBytes(&types.Vote{
		Height: pol.Height, Round: pol.Round, Type: types.VoteTypePrevote,
		BlockHash:  pol.BlockHash,
		BlockParts: pol.BlockParts,
	})
	seenValidators := map[string]struct{}{}

	for idx, vote := range pol.Votes {
		// vote may be zero, in which case skip.
		if vote.Signature.IsZero() {
			continue
		}
		voteDoc := prevoteDoc
		_, val := valSet.GetByIndex(uint(idx))

		// Commit vote?
		if vote.Round < pol.Round {
			voteDoc = account.SignBytes(&types.Vote{
				Height: pol.Height, Round: vote.Round, Type: types.VoteTypeCommit,
				BlockHash:  pol.BlockHash,
				BlockParts: pol.BlockParts,
			})
		} else if vote.Round > pol.Round {
			return fmt.Errorf("Invalid commit round %v for POL %v", vote.Round, pol)
		}

		// Validate
		if _, seen := seenValidators[string(val.Address)]; seen {
			return fmt.Errorf("Duplicate validator for vote %v for POL %v", vote, pol)
		}

		if !val.PubKey.VerifyBytes(voteDoc, vote.Signature) {
			return fmt.Errorf("Invalid signature for vote %v for POL %v", vote, pol)
		}

		// Tally
		seenValidators[string(val.Address)] = struct{}{}
		talliedVotingPower += val.VotingPower
	}

	if talliedVotingPower > valSet.TotalVotingPower()*2/3 {
		return nil
	} else {
		return fmt.Errorf("Invalid POL, insufficient voting power %v, needed %v",
			talliedVotingPower, (valSet.TotalVotingPower()*2/3 + 1))
	}

}