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.

120 lines
3.5 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. Version uint64 `binary:"fixed64"`
  20. Height int64 `binary:"fixed64"`
  21. Round int64 `binary:"fixed64"`
  22. Type SignedMsgType // type alias for byte
  23. POLRound int64 `binary:"fixed64"`
  24. Timestamp time.Time
  25. BlockPartsHeader CanonicalPartSetHeader
  26. POLBlockID CanonicalBlockID
  27. ChainID string
  28. }
  29. type CanonicalVote struct {
  30. Version uint64 `binary:"fixed64"`
  31. Height int64 `binary:"fixed64"`
  32. Round int64 `binary:"fixed64"`
  33. Type SignedMsgType // type alias for byte
  34. Timestamp time.Time
  35. BlockID CanonicalBlockID
  36. ChainID string
  37. }
  38. type CanonicalHeartbeat struct {
  39. Version uint64 `binary:"fixed64"`
  40. Height int64 `binary:"fixed64"`
  41. Round int `binary:"fixed64"`
  42. Type byte
  43. Sequence int `binary:"fixed64"`
  44. ValidatorAddress Address
  45. ValidatorIndex int
  46. ChainID string
  47. }
  48. //-----------------------------------
  49. // Canonicalize the structs
  50. func CanonicalizeBlockID(blockID BlockID) CanonicalBlockID {
  51. return CanonicalBlockID{
  52. Hash: blockID.Hash,
  53. PartsHeader: CanonicalizePartSetHeader(blockID.PartsHeader),
  54. }
  55. }
  56. func CanonicalizePartSetHeader(psh PartSetHeader) CanonicalPartSetHeader {
  57. return CanonicalPartSetHeader{
  58. psh.Hash,
  59. psh.Total,
  60. }
  61. }
  62. func CanonicalizeProposal(chainID string, proposal *Proposal) CanonicalProposal {
  63. return CanonicalProposal{
  64. Version: 0, // TODO
  65. Height: proposal.Height,
  66. Round: int64(proposal.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int)
  67. Type: ProposalType,
  68. POLRound: int64(proposal.POLRound),
  69. Timestamp: proposal.Timestamp,
  70. BlockPartsHeader: CanonicalizePartSetHeader(proposal.BlockPartsHeader),
  71. POLBlockID: CanonicalizeBlockID(proposal.POLBlockID),
  72. ChainID: chainID,
  73. }
  74. }
  75. func CanonicalizeVote(chainID string, vote *Vote) CanonicalVote {
  76. return CanonicalVote{
  77. Version: 0, // TODO
  78. Height: vote.Height,
  79. Round: int64(vote.Round), // cast int->int64 to make amino encode it fixed64 (does not work for int)
  80. Type: vote.Type,
  81. Timestamp: vote.Timestamp,
  82. BlockID: CanonicalizeBlockID(vote.BlockID),
  83. ChainID: chainID,
  84. }
  85. }
  86. func CanonicalizeHeartbeat(chainID string, heartbeat *Heartbeat) CanonicalHeartbeat {
  87. return CanonicalHeartbeat{
  88. Version: 0, // TODO
  89. Height: heartbeat.Height,
  90. Round: heartbeat.Round,
  91. Type: byte(HeartbeatType),
  92. Sequence: heartbeat.Sequence,
  93. ValidatorAddress: heartbeat.ValidatorAddress,
  94. ValidatorIndex: heartbeat.ValidatorIndex,
  95. ChainID: chainID,
  96. }
  97. }
  98. // CanonicalTime can be used to stringify time in a canonical way.
  99. func CanonicalTime(t time.Time) string {
  100. // Note that sending time over amino resets it to
  101. // local time, we need to force UTC here, so the
  102. // signatures match
  103. return tmtime.Canonical(t).Format(TimeFormat)
  104. }