You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.3 KiB

  1. # Light Client Verificaiton
  2. #### **[LCV-FUNC-VERIFYCOMMITLIGHT.1]**
  3. VerifyCommitLight verifies that 2/3+ of the signatures for a validator set were for
  4. a given blockID. The function will finish early and thus may not check all signatures.
  5. ```go
  6. func VerifyCommitLight(chainID string, vals *ValidatorSet, blockID BlockID,
  7. height int64, commit *Commit) error {
  8. // run a basic validation of the arguments
  9. if err := verifyBasicValsAndCommit(vals, commit, height, blockID); err != nil {
  10. return err
  11. }
  12. // calculate voting power needed
  13. votingPowerNeeded := vals.TotalVotingPower() * 2 / 3
  14. var (
  15. val *Validator
  16. valIdx int32
  17. seenVals = make(map[int32]int, len(commit.Signatures))
  18. talliedVotingPower int64 = 0
  19. voteSignBytes []byte
  20. )
  21. for idx, commitSig := range commit.Signatures {
  22. // ignore all commit signatures that are not for the block
  23. if !commitSig.ForBlock() {
  24. continue
  25. }
  26. // If the vals and commit have a 1-to-1 correspondance we can retrieve
  27. // them by index else we need to retrieve them by address
  28. if lookUpByIndex {
  29. val = vals.Validators[idx]
  30. } else {
  31. valIdx, val = vals.GetByAddress(commitSig.ValidatorAddress)
  32. // if the signature doesn't belong to anyone in the validator set
  33. // then we just skip over it
  34. if val == nil {
  35. continue
  36. }
  37. // because we are getting validators by address we need to make sure
  38. // that the same validator doesn't commit twice
  39. if firstIndex, ok := seenVals[valIdx]; ok {
  40. secondIndex := idx
  41. return fmt.Errorf("double vote from %v (%d and %d)", val, firstIndex, secondIndex)
  42. }
  43. seenVals[valIdx] = idx
  44. }
  45. voteSignBytes = commit.VoteSignBytes(chainID, int32(idx))
  46. if !val.PubKey.VerifySignature(voteSignBytes, commitSig.Signature) {
  47. return fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)
  48. }
  49. // Add the voting power of the validator
  50. // to the tally
  51. talliedVotingPower += val.VotingPower
  52. // check if we have enough signatures and can thus exit early
  53. if talliedVotingPower > votingPowerNeeded {
  54. return nil
  55. }
  56. }
  57. if got, needed := talliedVotingPower, votingPowerNeeded; got <= needed {
  58. return ErrNotEnoughVotingPowerSigned{Got: got, Needed: needed}
  59. }
  60. return nil
  61. }
  62. ```