github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/types/canonical.go (about)

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