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.5 KiB

  1. package types
  2. import (
  3. "time"
  4. tmtime "github.com/tendermint/tendermint/libs/time"
  5. tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
  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. //-----------------------------------
  11. // Canonicalize the structs
  12. func CanonicalizeBlockID(bid tmproto.BlockID) *tmproto.CanonicalBlockID {
  13. rbid, err := BlockIDFromProto(&bid)
  14. if err != nil {
  15. panic(err)
  16. }
  17. var cbid *tmproto.CanonicalBlockID
  18. if rbid == nil || rbid.IsNil() {
  19. cbid = nil
  20. } else {
  21. cbid = &tmproto.CanonicalBlockID{
  22. Hash: bid.Hash,
  23. PartSetHeader: CanonicalizePartSetHeader(bid.PartSetHeader),
  24. }
  25. }
  26. return cbid
  27. }
  28. // CanonicalizeVote transforms the given PartSetHeader to a CanonicalPartSetHeader.
  29. func CanonicalizePartSetHeader(psh tmproto.PartSetHeader) tmproto.CanonicalPartSetHeader {
  30. return tmproto.CanonicalPartSetHeader(psh)
  31. }
  32. // CanonicalizeVote transforms the given Proposal to a CanonicalProposal.
  33. func CanonicalizeProposal(chainID string, proposal *tmproto.Proposal) tmproto.CanonicalProposal {
  34. return tmproto.CanonicalProposal{
  35. Type: tmproto.ProposalType,
  36. Height: proposal.Height, // encoded as sfixed64
  37. Round: int64(proposal.Round), // encoded as sfixed64
  38. POLRound: int64(proposal.PolRound),
  39. BlockID: CanonicalizeBlockID(proposal.BlockID),
  40. Timestamp: proposal.Timestamp,
  41. ChainID: chainID,
  42. }
  43. }
  44. func GetVoteExtensionToSign(ext *tmproto.VoteExtension) *tmproto.VoteExtensionToSign {
  45. if ext == nil {
  46. return nil
  47. }
  48. return &tmproto.VoteExtensionToSign{
  49. AppDataToSign: ext.AppDataToSign,
  50. }
  51. }
  52. // CanonicalizeVote transforms the given Vote to a CanonicalVote, which does
  53. // not contain ValidatorIndex and ValidatorAddress fields.
  54. func CanonicalizeVote(chainID string, vote *tmproto.Vote) tmproto.CanonicalVote {
  55. return tmproto.CanonicalVote{
  56. Type: vote.Type,
  57. Height: vote.Height, // encoded as sfixed64
  58. Round: int64(vote.Round), // encoded as sfixed64
  59. BlockID: CanonicalizeBlockID(vote.BlockID),
  60. Timestamp: vote.Timestamp,
  61. ChainID: chainID,
  62. VoteExtension: GetVoteExtensionToSign(vote.VoteExtension),
  63. }
  64. }
  65. // CanonicalTime can be used to stringify time in a canonical way.
  66. func CanonicalTime(t time.Time) string {
  67. // Note that sending time over amino resets it to
  68. // local time, we need to force UTC here, so the
  69. // signatures match
  70. return tmtime.Canonical(t).Format(TimeFormat)
  71. }