github.com/aakash4dev/cometbft@v0.38.2/types/canonical.go (about)

     1  package types
     2  
     3  import (
     4  	"time"
     5  
     6  	cmtproto "github.com/aakash4dev/cometbft/proto/tendermint/types"
     7  	cmttime "github.com/aakash4dev/cometbft/types/time"
     8  )
     9  
    10  // Canonical* wraps the structs in types for amino encoding them for use in SignBytes / the Signable interface.
    11  
    12  // TimeFormat is used for generating the sigs
    13  const TimeFormat = time.RFC3339Nano
    14  
    15  //-----------------------------------
    16  // Canonicalize the structs
    17  
    18  func CanonicalizeBlockID(bid cmtproto.BlockID) *cmtproto.CanonicalBlockID {
    19  	rbid, err := BlockIDFromProto(&bid)
    20  	if err != nil {
    21  		panic(err)
    22  	}
    23  	var cbid *cmtproto.CanonicalBlockID
    24  	if rbid == nil || rbid.IsZero() {
    25  		cbid = nil
    26  	} else {
    27  		cbid = &cmtproto.CanonicalBlockID{
    28  			Hash:          bid.Hash,
    29  			PartSetHeader: CanonicalizePartSetHeader(bid.PartSetHeader),
    30  		}
    31  	}
    32  
    33  	return cbid
    34  }
    35  
    36  // CanonicalizeVote transforms the given PartSetHeader to a CanonicalPartSetHeader.
    37  func CanonicalizePartSetHeader(psh cmtproto.PartSetHeader) cmtproto.CanonicalPartSetHeader {
    38  	return cmtproto.CanonicalPartSetHeader(psh)
    39  }
    40  
    41  // CanonicalizeVote transforms the given Proposal to a CanonicalProposal.
    42  func CanonicalizeProposal(chainID string, proposal *cmtproto.Proposal) cmtproto.CanonicalProposal {
    43  	return cmtproto.CanonicalProposal{
    44  		Type:      cmtproto.ProposalType,
    45  		Height:    proposal.Height,       // encoded as sfixed64
    46  		Round:     int64(proposal.Round), // encoded as sfixed64
    47  		POLRound:  int64(proposal.PolRound),
    48  		BlockID:   CanonicalizeBlockID(proposal.BlockID),
    49  		Timestamp: proposal.Timestamp,
    50  		ChainID:   chainID,
    51  	}
    52  }
    53  
    54  // CanonicalizeVote transforms the given Vote to a CanonicalVote, which does
    55  // not contain ValidatorIndex and ValidatorAddress fields, or any fields
    56  // relating to vote extensions.
    57  func CanonicalizeVote(chainID string, vote *cmtproto.Vote) cmtproto.CanonicalVote {
    58  	return cmtproto.CanonicalVote{
    59  		Type:      vote.Type,
    60  		Height:    vote.Height,       // encoded as sfixed64
    61  		Round:     int64(vote.Round), // encoded as sfixed64
    62  		BlockID:   CanonicalizeBlockID(vote.BlockID),
    63  		Timestamp: vote.Timestamp,
    64  		ChainID:   chainID,
    65  	}
    66  }
    67  
    68  // CanonicalizeVoteExtension extracts the vote extension from the given vote
    69  // and constructs a CanonicalizeVoteExtension struct, whose representation in
    70  // bytes is what is signed in order to produce the vote extension's signature.
    71  func CanonicalizeVoteExtension(chainID string, vote *cmtproto.Vote) cmtproto.CanonicalVoteExtension {
    72  	return cmtproto.CanonicalVoteExtension{
    73  		Extension: vote.Extension,
    74  		Height:    vote.Height,
    75  		Round:     int64(vote.Round),
    76  		ChainId:   chainID,
    77  	}
    78  }
    79  
    80  // CanonicalTime can be used to stringify time in a canonical way.
    81  func CanonicalTime(t time.Time) string {
    82  	// Note that sending time over amino resets it to
    83  	// local time, we need to force UTC here, so the
    84  	// signatures match
    85  	return cmttime.Canonical(t).Format(TimeFormat)
    86  }