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.

115 lines
3.6 KiB

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