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.

72 lines
1.9 KiB

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