github.com/supragya/TendermintConnector@v0.0.0-20210619045051-113e32b84fb1/chains/cosmos/structsTendermint.go (about)

     1  package cosmos
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/supragya/TendermintConnector/chains/cosmos/crypto"
     7  	"github.com/supragya/TendermintConnector/chains/cosmos/crypto/merkle"
     8  	"github.com/supragya/TendermintConnector/chains/cosmos/libs/bits"
     9  	tmjson "github.com/supragya/TendermintConnector/chains/cosmos/libs/json"
    10  	"github.com/supragya/TendermintConnector/chains/cosmos/libs/protoio"
    11  	tmproto "github.com/supragya/TendermintConnector/chains/cosmos/proto/tendermint/types"
    12  )
    13  
    14  const (
    15  	channelBc   = byte(0x40) //bc.BlockchainChannel,
    16  	channelCsSt = byte(0x20) //cs.StateChannel,
    17  	channelCsDc = byte(0x21) //cs.DataChannel,
    18  	channelCsVo = byte(0x22) //cs.VoteChannel,
    19  	channelCsVs = byte(0x23) //cs.VoteSetBitsChannel,
    20  	channelMm   = byte(0x30) //mempl.MempoolChannel,
    21  	channelEv   = byte(0x38) //evidence.EvidenceChannel,
    22  )
    23  
    24  func init() {
    25  	tmjson.RegisterType(&NewRoundStepMessage{}, "tendermint/NewRoundStepMessage")
    26  	tmjson.RegisterType(&NewValidBlockMessage{}, "tendermint/NewValidBlockMessage")
    27  	tmjson.RegisterType(&ProposalMessage{}, "tendermint/Proposal")
    28  	tmjson.RegisterType(&ProposalPOLMessage{}, "tendermint/ProposalPOL")
    29  	tmjson.RegisterType(&BlockPartMessage{}, "tendermint/BlockPart")
    30  	tmjson.RegisterType(&VoteMessage{}, "tendermint/Vote")
    31  	tmjson.RegisterType(&HasVoteMessage{}, "tendermint/HasVote")
    32  	tmjson.RegisterType(&VoteSetMaj23Message{}, "tendermint/VoteSetMaj23")
    33  	tmjson.RegisterType(&VoteSetBitsMessage{}, "tendermint/VoteSetBits")
    34  }
    35  
    36  //-------------------------------------
    37  
    38  // NewRoundStepMessage is sent for every step taken in the ConsensusState.
    39  // For every height/round/step transition
    40  type NewRoundStepMessage struct {
    41  	Height                int64
    42  	Round                 int32
    43  	Step                  int8
    44  	SecondsSinceStartTime int64
    45  	LastCommitRound       int32
    46  }
    47  
    48  //-------------------------------------
    49  type PartSetHeader struct {
    50  	Total uint32 `json:"total"`
    51  	Hash  []byte `json:"hash"`
    52  }
    53  
    54  // ToProto converts PartSetHeader to protobuf
    55  func (psh *PartSetHeader) ToProto() tmproto.PartSetHeader {
    56  	if psh == nil {
    57  		return tmproto.PartSetHeader{}
    58  	}
    59  
    60  	return tmproto.PartSetHeader{
    61  		Total: psh.Total,
    62  		Hash:  psh.Hash,
    63  	}
    64  }
    65  
    66  // NewValidBlockMessage is sent when a validator observes a valid block B in some round r,
    67  // i.e., there is a Proposal for block B and 2/3+ prevotes for the block B in the round r.
    68  // In case the block is also committed, then IsCommit flag is set to true.
    69  type NewValidBlockMessage struct {
    70  	Height             int64
    71  	Round              int32
    72  	BlockPartSetHeader PartSetHeader
    73  	BlockParts         *bits.BitArray
    74  	IsCommit           bool
    75  }
    76  
    77  //-------------------------------------
    78  type BlockID struct {
    79  	Hash          []byte        `json:"hash"`
    80  	PartSetHeader PartSetHeader `json:"parts"`
    81  }
    82  
    83  func (blockID *BlockID) ToProto() tmproto.BlockID {
    84  	if blockID == nil {
    85  		return tmproto.BlockID{}
    86  	}
    87  
    88  	return tmproto.BlockID{
    89  		Hash:          blockID.Hash,
    90  		PartSetHeader: blockID.PartSetHeader.ToProto(),
    91  	}
    92  }
    93  
    94  type Proposal struct {
    95  	Type      tmproto.SignedMsgType
    96  	Height    int64     `json:"height"`
    97  	Round     int32     `json:"round"`     // there can not be greater than 2_147_483_647 rounds
    98  	POLRound  int32     `json:"pol_round"` // -1 if null.
    99  	BlockID   BlockID   `json:"block_id"`
   100  	Timestamp time.Time `json:"timestamp"`
   101  	Signature []byte    `json:"signature"`
   102  }
   103  
   104  // ToProto converts Proposal to protobuf
   105  func (p *Proposal) ToProto() *tmproto.Proposal {
   106  	if p == nil {
   107  		return &tmproto.Proposal{}
   108  	}
   109  	pb := new(tmproto.Proposal)
   110  
   111  	pb.BlockID = p.BlockID.ToProto()
   112  	pb.Type = p.Type
   113  	pb.Height = p.Height
   114  	pb.Round = p.Round
   115  	pb.PolRound = p.POLRound
   116  	pb.Timestamp = p.Timestamp
   117  	pb.Signature = p.Signature
   118  
   119  	return pb
   120  }
   121  
   122  // ProposalMessage is sent when a new block is proposed.
   123  type ProposalMessage struct {
   124  	Proposal *Proposal
   125  }
   126  
   127  // ProposalSignBytes returns the proto-encoding of the canonicalized Proposal,
   128  // for signing. Panics if the marshaling fails.
   129  //
   130  // The encoded Protobuf message is varint length-prefixed (using MarshalDelimited)
   131  // for backwards-compatibility with the Amino encoding, due to e.g. hardware
   132  // devices that rely on this encoding.
   133  //
   134  // See CanonicalizeProposal
   135  func ProposalSignBytes(chainID string, p *tmproto.Proposal) []byte {
   136  	pb := CanonicalizeProposal(chainID, p)
   137  	bz, err := protoio.MarshalDelimited(&pb)
   138  	if err != nil {
   139  		panic(err)
   140  	}
   141  
   142  	return bz
   143  }
   144  
   145  // CanonicalizeVote transforms the given Proposal to a CanonicalProposal.
   146  func CanonicalizeProposal(chainID string, proposal *tmproto.Proposal) tmproto.CanonicalProposal {
   147  	return tmproto.CanonicalProposal{
   148  		Type:      tmproto.ProposalType,
   149  		Height:    proposal.Height,       // encoded as sfixed64
   150  		Round:     int64(proposal.Round), // encoded as sfixed64
   151  		POLRound:  int64(proposal.PolRound),
   152  		BlockID:   CanonicalizeBlockID(proposal.BlockID),
   153  		Timestamp: proposal.Timestamp,
   154  		ChainID:   chainID,
   155  	}
   156  }
   157  
   158  //-------------------------------------
   159  
   160  // ProposalPOLMessage is sent when a previous proposal is re-proposed.
   161  type ProposalPOLMessage struct {
   162  	Height           int64
   163  	ProposalPOLRound int32
   164  	ProposalPOL      *bits.BitArray
   165  }
   166  
   167  //-------------------------------------
   168  type Part struct {
   169  	Index uint32       `json:"index"`
   170  	Bytes []byte       `json:"bytes"`
   171  	Proof merkle.Proof `json:"proof"`
   172  }
   173  
   174  // BlockPartMessage is sent when gossipping a piece of the proposed block.
   175  type BlockPartMessage struct {
   176  	Height int64
   177  	Round  int32
   178  	Part   *Part
   179  }
   180  
   181  //-------------------------------------
   182  type Vote struct {
   183  	Type             tmproto.SignedMsgType `json:"type"`
   184  	Height           int64                 `json:"height"`
   185  	Round            int32                 `json:"round"`    // assume there will not be greater than 2_147_483_647 rounds
   186  	BlockID          BlockID               `json:"block_id"` // zero if vote is nil.
   187  	Timestamp        time.Time             `json:"timestamp"`
   188  	ValidatorAddress crypto.Address        `json:"validator_address"`
   189  	ValidatorIndex   int32                 `json:"validator_index"`
   190  	Signature        []byte                `json:"signature"`
   191  }
   192  
   193  // VoteMessage is sent when voting for a proposal (or lack thereof).
   194  type VoteMessage struct {
   195  	Vote *Vote
   196  }
   197  
   198  // ToProto converts the handwritten type to proto generated type
   199  // return type, nil if everything converts safely, otherwise nil, error
   200  func (vote *Vote) ToProto() *tmproto.Vote {
   201  	if vote == nil {
   202  		return nil
   203  	}
   204  
   205  	return &tmproto.Vote{
   206  		Type:             vote.Type,
   207  		Height:           vote.Height,
   208  		Round:            vote.Round,
   209  		BlockID:          vote.BlockID.ToProto(),
   210  		Timestamp:        vote.Timestamp,
   211  		ValidatorAddress: vote.ValidatorAddress,
   212  		ValidatorIndex:   vote.ValidatorIndex,
   213  		Signature:        vote.Signature,
   214  	}
   215  }
   216  
   217  //-------------------------------------
   218  
   219  // HasVoteMessage is sent to indicate that a particular vote has been received.
   220  type HasVoteMessage struct {
   221  	Height int64
   222  	Round  int32
   223  	Type   tmproto.SignedMsgType
   224  	Index  int32
   225  }
   226  
   227  //-------------------------------------
   228  
   229  // VoteSetMaj23Message is sent to indicate that a given BlockID has seen +2/3 votes.
   230  type VoteSetMaj23Message struct {
   231  	Height  int64
   232  	Round   int32
   233  	Type    tmproto.SignedMsgType
   234  	BlockID BlockID
   235  }
   236  
   237  //-------------------------------------
   238  
   239  // VoteSetBitsMessage is sent to communicate the bit-array of votes seen for the BlockID.
   240  type VoteSetBitsMessage struct {
   241  	Height  int64
   242  	Round   int32
   243  	Type    tmproto.SignedMsgType
   244  	BlockID BlockID
   245  	Votes   *bits.BitArray
   246  }
   247  
   248  //-------------------------------------
   249  
   250  // CanonicalizeVote transforms the given PartSetHeader to a CanonicalPartSetHeader.
   251  func CanonicalizePartSetHeader(psh tmproto.PartSetHeader) tmproto.CanonicalPartSetHeader {
   252  	return tmproto.CanonicalPartSetHeader(psh)
   253  }
   254  
   255  func CanonicalizeBlockID(bid tmproto.BlockID) *tmproto.CanonicalBlockID {
   256  	rbid, err := BlockIDFromProto(&bid)
   257  	if err != nil {
   258  		panic(err)
   259  	}
   260  	var cbid *tmproto.CanonicalBlockID
   261  	if rbid == nil {
   262  		cbid = nil
   263  	} else {
   264  		cbid = &tmproto.CanonicalBlockID{
   265  			Hash:          bid.Hash,
   266  			PartSetHeader: CanonicalizePartSetHeader(bid.PartSetHeader),
   267  		}
   268  	}
   269  
   270  	return cbid
   271  }
   272  
   273  // CanonicalizeVote transforms the given Vote to a CanonicalVote, which does
   274  // not contain ValidatorIndex and ValidatorAddress fields.
   275  func CanonicalizeVote(chainID string, vote *tmproto.Vote) tmproto.CanonicalVote {
   276  	return tmproto.CanonicalVote{
   277  		Type:      vote.Type,
   278  		Height:    vote.Height,       // encoded as sfixed64
   279  		Round:     int64(vote.Round), // encoded as sfixed64
   280  		BlockID:   CanonicalizeBlockID(vote.BlockID),
   281  		Timestamp: vote.Timestamp,
   282  		ChainID:   chainID,
   283  	}
   284  }
   285  
   286  func VoteSignBytes(chainID string, vote *tmproto.Vote) []byte {
   287  	pb := CanonicalizeVote(chainID, vote)
   288  	bz, err := protoio.MarshalDelimited(&pb)
   289  	if err != nil {
   290  		panic(err)
   291  	}
   292  
   293  	return bz
   294  }