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.

112 lines
3.1 KiB

  1. package types
  2. import (
  3. "time"
  4. cmn "github.com/tendermint/tendermint/libs/common"
  5. tmtime "github.com/tendermint/tendermint/types/time"
  6. )
  7. // Canonical* wraps the structs in types for amino encoding them for use in SignBytes / the Signable interface.
  8. // TimeFormat is used for generating the sigs
  9. const TimeFormat = time.RFC3339Nano
  10. type CanonicalBlockID struct {
  11. Hash cmn.HexBytes
  12. PartsHeader CanonicalPartSetHeader
  13. }
  14. type CanonicalPartSetHeader struct {
  15. Hash cmn.HexBytes
  16. Total int
  17. }
  18. type CanonicalProposal struct {
  19. Type SignedMsgType // type alias for byte
  20. Height int64 `binary:"fixed64"`
  21. Round int64 `binary:"fixed64"`
  22. POLRound int64 `binary:"fixed64"`
  23. BlockID CanonicalBlockID
  24. Timestamp time.Time
  25. ChainID string
  26. }
  27. type CanonicalVote struct {
  28. Type SignedMsgType // type alias for byte
  29. Height int64 `binary:"fixed64"`
  30. Round int64 `binary:"fixed64"`
  31. Timestamp time.Time
  32. BlockID CanonicalBlockID
  33. ChainID string
  34. }
  35. type CanonicalHeartbeat struct {
  36. Type byte
  37. Height int64 `binary:"fixed64"`
  38. Round int `binary:"fixed64"`
  39. Sequence int `binary:"fixed64"`
  40. ValidatorAddress Address
  41. ValidatorIndex int
  42. ChainID string
  43. }
  44. //-----------------------------------
  45. // Canonicalize the structs
  46. func CanonicalizeBlockID(blockID BlockID) CanonicalBlockID {
  47. return CanonicalBlockID{
  48. Hash: blockID.Hash,
  49. PartsHeader: CanonicalizePartSetHeader(blockID.PartsHeader),
  50. }
  51. }
  52. func CanonicalizePartSetHeader(psh PartSetHeader) CanonicalPartSetHeader {
  53. return CanonicalPartSetHeader{
  54. psh.Hash,
  55. psh.Total,
  56. }
  57. }
  58. func CanonicalizeProposal(chainID string, proposal *Proposal) CanonicalProposal {
  59. return CanonicalProposal{
  60. Type: ProposalType,
  61. Height: proposal.Height,
  62. Round: int64(proposal.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int)
  63. POLRound: int64(proposal.POLRound),
  64. BlockID: CanonicalizeBlockID(proposal.BlockID),
  65. Timestamp: proposal.Timestamp,
  66. ChainID: chainID,
  67. }
  68. }
  69. func CanonicalizeVote(chainID string, vote *Vote) CanonicalVote {
  70. return CanonicalVote{
  71. Type: vote.Type,
  72. Height: vote.Height,
  73. Round: int64(vote.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int)
  74. Timestamp: vote.Timestamp,
  75. BlockID: CanonicalizeBlockID(vote.BlockID),
  76. ChainID: chainID,
  77. }
  78. }
  79. func CanonicalizeHeartbeat(chainID string, heartbeat *Heartbeat) CanonicalHeartbeat {
  80. return CanonicalHeartbeat{
  81. Type: byte(HeartbeatType),
  82. Height: heartbeat.Height,
  83. Round: heartbeat.Round,
  84. Sequence: heartbeat.Sequence,
  85. ValidatorAddress: heartbeat.ValidatorAddress,
  86. ValidatorIndex: heartbeat.ValidatorIndex,
  87. ChainID: chainID,
  88. }
  89. }
  90. // CanonicalTime can be used to stringify time in a canonical way.
  91. func CanonicalTime(t time.Time) string {
  92. // Note that sending time over amino resets it to
  93. // local time, we need to force UTC here, so the
  94. // signatures match
  95. return tmtime.Canonical(t).Format(TimeFormat)
  96. }