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.

80 lines
2.1 KiB

  1. package lite
  2. import (
  3. "bytes"
  4. "github.com/pkg/errors"
  5. cmn "github.com/tendermint/tendermint/libs/common"
  6. lerr "github.com/tendermint/tendermint/lite/errors"
  7. "github.com/tendermint/tendermint/types"
  8. )
  9. var _ Verifier = (*BaseVerifier)(nil)
  10. // BaseVerifier lets us check the validity of SignedHeaders at height or
  11. // later, requiring sufficient votes (> 2/3) from the given valset.
  12. // To verify blocks produced by a blockchain with mutable validator sets,
  13. // use the DynamicVerifier.
  14. // TODO: Handle unbonding time.
  15. type BaseVerifier struct {
  16. chainID string
  17. height int64
  18. valset *types.ValidatorSet
  19. }
  20. // NewBaseVerifier returns a new Verifier initialized with a validator set at
  21. // some height.
  22. func NewBaseVerifier(chainID string, height int64, valset *types.ValidatorSet) *BaseVerifier {
  23. if valset.IsNilOrEmpty() {
  24. panic("NewBaseVerifier requires a valid valset")
  25. }
  26. return &BaseVerifier{
  27. chainID: chainID,
  28. height: height,
  29. valset: valset,
  30. }
  31. }
  32. // Implements Verifier.
  33. func (bv *BaseVerifier) ChainID() string {
  34. return bv.chainID
  35. }
  36. // Implements Verifier.
  37. func (bv *BaseVerifier) Verify(signedHeader types.SignedHeader) error {
  38. // We can't verify commits for a different chain.
  39. if signedHeader.ChainID != bv.chainID {
  40. return cmn.NewError("BaseVerifier chainID is %v, cannot verify chainID %v",
  41. bv.chainID, signedHeader.ChainID)
  42. }
  43. // We can't verify commits older than bv.height.
  44. if signedHeader.Height < bv.height {
  45. return cmn.NewError("BaseVerifier height is %v, cannot verify height %v",
  46. bv.height, signedHeader.Height)
  47. }
  48. // We can't verify with the wrong validator set.
  49. if !bytes.Equal(signedHeader.ValidatorsHash,
  50. bv.valset.Hash()) {
  51. return lerr.ErrUnexpectedValidators(signedHeader.ValidatorsHash, bv.valset.Hash())
  52. }
  53. // Do basic sanity checks.
  54. err := signedHeader.ValidateBasic(bv.chainID)
  55. if err != nil {
  56. return errors.Wrap(err, "in verify")
  57. }
  58. // Check commit signatures.
  59. err = bv.valset.VerifyCommit(
  60. bv.chainID, signedHeader.Commit.BlockID,
  61. signedHeader.Height, signedHeader.Commit)
  62. if err != nil {
  63. return errors.Wrap(err, "in verify")
  64. }
  65. return nil
  66. }