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.

114 lines
3.5 KiB

  1. package types
  2. import (
  3. "time"
  4. cmn "github.com/tendermint/tendermint/libs/common"
  5. )
  6. // Canonical json is amino's json for structs with fields in alphabetical order
  7. // TimeFormat is used for generating the sigs
  8. const TimeFormat = time.RFC3339Nano
  9. type CanonicalJSONBlockID struct {
  10. Hash cmn.HexBytes `json:"hash,omitempty"`
  11. PartsHeader CanonicalJSONPartSetHeader `json:"parts,omitempty"`
  12. }
  13. type CanonicalJSONPartSetHeader struct {
  14. Hash cmn.HexBytes `json:"hash,omitempty"`
  15. Total int `json:"total,omitempty"`
  16. }
  17. type CanonicalJSONProposal struct {
  18. ChainID string `json:"@chain_id"`
  19. Type string `json:"@type"`
  20. BlockPartsHeader CanonicalJSONPartSetHeader `json:"block_parts_header"`
  21. Height int64 `json:"height"`
  22. POLBlockID CanonicalJSONBlockID `json:"pol_block_id"`
  23. POLRound int `json:"pol_round"`
  24. Round int `json:"round"`
  25. Timestamp string `json:"timestamp"`
  26. }
  27. type CanonicalJSONVote struct {
  28. ChainID string `json:"@chain_id"`
  29. Type string `json:"@type"`
  30. BlockID CanonicalJSONBlockID `json:"block_id"`
  31. Height int64 `json:"height"`
  32. Round int `json:"round"`
  33. Timestamp string `json:"timestamp"`
  34. VoteType byte `json:"type"`
  35. }
  36. type CanonicalJSONHeartbeat struct {
  37. ChainID string `json:"@chain_id"`
  38. Type string `json:"@type"`
  39. Height int64 `json:"height"`
  40. Round int `json:"round"`
  41. Sequence int `json:"sequence"`
  42. ValidatorAddress Address `json:"validator_address"`
  43. ValidatorIndex int `json:"validator_index"`
  44. }
  45. //-----------------------------------
  46. // Canonicalize the structs
  47. func CanonicalBlockID(blockID BlockID) CanonicalJSONBlockID {
  48. return CanonicalJSONBlockID{
  49. Hash: blockID.Hash,
  50. PartsHeader: CanonicalPartSetHeader(blockID.PartsHeader),
  51. }
  52. }
  53. func CanonicalPartSetHeader(psh PartSetHeader) CanonicalJSONPartSetHeader {
  54. return CanonicalJSONPartSetHeader{
  55. psh.Hash,
  56. psh.Total,
  57. }
  58. }
  59. func CanonicalProposal(chainID string, proposal *Proposal) CanonicalJSONProposal {
  60. return CanonicalJSONProposal{
  61. ChainID: chainID,
  62. Type: "proposal",
  63. BlockPartsHeader: CanonicalPartSetHeader(proposal.BlockPartsHeader),
  64. Height: proposal.Height,
  65. Timestamp: CanonicalTime(proposal.Timestamp),
  66. POLBlockID: CanonicalBlockID(proposal.POLBlockID),
  67. POLRound: proposal.POLRound,
  68. Round: proposal.Round,
  69. }
  70. }
  71. func CanonicalVote(chainID string, vote *Vote) CanonicalJSONVote {
  72. return CanonicalJSONVote{
  73. ChainID: chainID,
  74. Type: "vote",
  75. BlockID: CanonicalBlockID(vote.BlockID),
  76. Height: vote.Height,
  77. Round: vote.Round,
  78. Timestamp: CanonicalTime(vote.Timestamp),
  79. VoteType: vote.Type,
  80. }
  81. }
  82. func CanonicalHeartbeat(chainID string, heartbeat *Heartbeat) CanonicalJSONHeartbeat {
  83. return CanonicalJSONHeartbeat{
  84. ChainID: chainID,
  85. Type: "heartbeat",
  86. Height: heartbeat.Height,
  87. Round: heartbeat.Round,
  88. Sequence: heartbeat.Sequence,
  89. ValidatorAddress: heartbeat.ValidatorAddress,
  90. ValidatorIndex: heartbeat.ValidatorIndex,
  91. }
  92. }
  93. func CanonicalTime(t time.Time) string {
  94. // Note that sending time over amino resets it to
  95. // local time, we need to force UTC here, so the
  96. // signatures match
  97. return t.Round(0).UTC().Format(TimeFormat)
  98. }