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.

87 lines
2.6 KiB

  1. package lite
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "github.com/tendermint/tendermint/types"
  7. )
  8. // FullCommit is a signed header (the block header and a commit that signs it),
  9. // the validator set which signed the commit, and the next validator set. The
  10. // next validator set (which is proven from the block header) allows us to
  11. // revert to block-by-block updating of lite certifier's latest validator set,
  12. // even in the face of arbitrarily large power changes.
  13. type FullCommit struct {
  14. SignedHeader types.SignedHeader `json:"signed_header"`
  15. Validators *types.ValidatorSet `json:"validator_set"`
  16. NextValidators *types.ValidatorSet `json:"next_validator_set"`
  17. }
  18. // NewFullCommit returns a new FullCommit.
  19. func NewFullCommit(signedHeader types.SignedHeader, valset, nextValset *types.ValidatorSet) FullCommit {
  20. return FullCommit{
  21. SignedHeader: signedHeader,
  22. Validators: valset,
  23. NextValidators: nextValset,
  24. }
  25. }
  26. // Validate the components and check for consistency.
  27. // This also checks to make sure that Validators actually
  28. // signed the SignedHeader.Commit.
  29. // If > 2/3 did not sign the Commit from fc.Validators, it
  30. // is not a valid commit!
  31. func (fc FullCommit) ValidateFull(chainID string) error {
  32. // Ensure that Validators exists and matches the header.
  33. if fc.Validators.Size() == 0 {
  34. return errors.New("need FullCommit.Validators")
  35. }
  36. if !bytes.Equal(
  37. fc.SignedHeader.ValidatorsHash,
  38. fc.Validators.Hash()) {
  39. return fmt.Errorf("header has vhash %X but valset hash is %X",
  40. fc.SignedHeader.ValidatorsHash,
  41. fc.Validators.Hash(),
  42. )
  43. }
  44. // Ensure that NextValidators exists and matches the header.
  45. if fc.NextValidators.Size() == 0 {
  46. return errors.New("need FullCommit.NextValidators")
  47. }
  48. if !bytes.Equal(
  49. fc.SignedHeader.NextValidatorsHash,
  50. fc.NextValidators.Hash()) {
  51. return fmt.Errorf("header has next vhash %X but next valset hash is %X",
  52. fc.SignedHeader.NextValidatorsHash,
  53. fc.NextValidators.Hash(),
  54. )
  55. }
  56. // Validate the header.
  57. err := fc.SignedHeader.ValidateBasic(chainID)
  58. if err != nil {
  59. return err
  60. }
  61. // Validate the signatures on the commit.
  62. hdr, cmt := fc.SignedHeader.Header, fc.SignedHeader.Commit
  63. return fc.Validators.VerifyCommit(
  64. hdr.ChainID, cmt.BlockID,
  65. hdr.Height, cmt)
  66. }
  67. // Height returns the height of the header.
  68. func (fc FullCommit) Height() int64 {
  69. if fc.SignedHeader.Header == nil {
  70. panic("should not happen")
  71. }
  72. return fc.SignedHeader.Height
  73. }
  74. // ChainID returns the chainID of the header.
  75. func (fc FullCommit) ChainID() string {
  76. if fc.SignedHeader.Header == nil {
  77. panic("should not happen")
  78. }
  79. return fc.SignedHeader.ChainID
  80. }