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.

83 lines
2.4 KiB

  1. package types
  2. import (
  3. "fmt"
  4. "github.com/pkg/errors"
  5. "github.com/tendermint/tendermint/crypto"
  6. cmn "github.com/tendermint/tendermint/libs/common"
  7. )
  8. // Heartbeat is a simple vote-like structure so validators can
  9. // alert others that they are alive and waiting for transactions.
  10. // Note: We aren't adding ",omitempty" to Heartbeat's
  11. // json field tags because we always want the JSON
  12. // representation to be in its canonical form.
  13. type Heartbeat struct {
  14. ValidatorAddress Address `json:"validator_address"`
  15. ValidatorIndex int `json:"validator_index"`
  16. Height int64 `json:"height"`
  17. Round int `json:"round"`
  18. Sequence int `json:"sequence"`
  19. Signature []byte `json:"signature"`
  20. }
  21. // SignBytes returns the Heartbeat bytes for signing.
  22. // It panics if the Heartbeat is nil.
  23. func (heartbeat *Heartbeat) SignBytes(chainID string) []byte {
  24. bz, err := cdc.MarshalBinaryLengthPrefixed(CanonicalizeHeartbeat(chainID, heartbeat))
  25. if err != nil {
  26. panic(err)
  27. }
  28. return bz
  29. }
  30. // Copy makes a copy of the Heartbeat.
  31. func (heartbeat *Heartbeat) Copy() *Heartbeat {
  32. if heartbeat == nil {
  33. return nil
  34. }
  35. heartbeatCopy := *heartbeat
  36. return &heartbeatCopy
  37. }
  38. // String returns a string representation of the Heartbeat.
  39. func (heartbeat *Heartbeat) String() string {
  40. if heartbeat == nil {
  41. return "nil-heartbeat"
  42. }
  43. return fmt.Sprintf("Heartbeat{%v:%X %v/%02d (%v) %v}",
  44. heartbeat.ValidatorIndex, cmn.Fingerprint(heartbeat.ValidatorAddress),
  45. heartbeat.Height, heartbeat.Round, heartbeat.Sequence,
  46. fmt.Sprintf("/%X.../", cmn.Fingerprint(heartbeat.Signature[:])))
  47. }
  48. // ValidateBasic performs basic validation.
  49. func (heartbeat *Heartbeat) ValidateBasic() error {
  50. if len(heartbeat.ValidatorAddress) != crypto.AddressSize {
  51. return fmt.Errorf("Expected ValidatorAddress size to be %d bytes, got %d bytes",
  52. crypto.AddressSize,
  53. len(heartbeat.ValidatorAddress),
  54. )
  55. }
  56. if heartbeat.ValidatorIndex < 0 {
  57. return errors.New("Negative ValidatorIndex")
  58. }
  59. if heartbeat.Height < 0 {
  60. return errors.New("Negative Height")
  61. }
  62. if heartbeat.Round < 0 {
  63. return errors.New("Negative Round")
  64. }
  65. if heartbeat.Sequence < 0 {
  66. return errors.New("Negative Sequence")
  67. }
  68. if len(heartbeat.Signature) == 0 {
  69. return errors.New("Signature is missing")
  70. }
  71. if len(heartbeat.Signature) > MaxSignatureSize {
  72. return fmt.Errorf("Signature is too big (max: %d)", MaxSignatureSize)
  73. }
  74. return nil
  75. }