github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/netsync/message.go (about)

     1  package netsync
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  
    10  	"github.com/tendermint/go-wire"
    11  
    12  	"github.com/bytom/bytom/protocol/bc"
    13  	"github.com/bytom/bytom/protocol/bc/types"
    14  )
    15  
    16  //protocol msg byte
    17  const (
    18  	BlockchainChannel = byte(0x40)
    19  
    20  	BlockRequestByte    = byte(0x10)
    21  	BlockResponseByte   = byte(0x11)
    22  	HeadersRequestByte  = byte(0x12)
    23  	HeadersResponseByte = byte(0x13)
    24  	BlocksRequestByte   = byte(0x14)
    25  	BlocksResponseByte  = byte(0x15)
    26  	StatusRequestByte   = byte(0x20)
    27  	StatusResponseByte  = byte(0x21)
    28  	NewTransactionByte  = byte(0x30)
    29  	NewMineBlockByte    = byte(0x40)
    30  	FilterLoadByte      = byte(0x50)
    31  	FilterAddByte       = byte(0x51)
    32  	FilterClearByte     = byte(0x52)
    33  	MerkleRequestByte   = byte(0x60)
    34  	MerkleResponseByte  = byte(0x61)
    35  
    36  	maxBlockchainResponseSize = 22020096 + 2
    37  )
    38  
    39  //BlockchainMessage is a generic message for this reactor.
    40  type BlockchainMessage interface {
    41  	String() string
    42  }
    43  
    44  var _ = wire.RegisterInterface(
    45  	struct{ BlockchainMessage }{},
    46  	wire.ConcreteType{&GetBlockMessage{}, BlockRequestByte},
    47  	wire.ConcreteType{&BlockMessage{}, BlockResponseByte},
    48  	wire.ConcreteType{&GetHeadersMessage{}, HeadersRequestByte},
    49  	wire.ConcreteType{&HeadersMessage{}, HeadersResponseByte},
    50  	wire.ConcreteType{&GetBlocksMessage{}, BlocksRequestByte},
    51  	wire.ConcreteType{&BlocksMessage{}, BlocksResponseByte},
    52  	wire.ConcreteType{&StatusRequestMessage{}, StatusRequestByte},
    53  	wire.ConcreteType{&StatusResponseMessage{}, StatusResponseByte},
    54  	wire.ConcreteType{&TransactionMessage{}, NewTransactionByte},
    55  	wire.ConcreteType{&MineBlockMessage{}, NewMineBlockByte},
    56  	wire.ConcreteType{&FilterLoadMessage{}, FilterLoadByte},
    57  	wire.ConcreteType{&FilterAddMessage{}, FilterAddByte},
    58  	wire.ConcreteType{&FilterClearMessage{}, FilterClearByte},
    59  	wire.ConcreteType{&GetMerkleBlockMessage{}, MerkleRequestByte},
    60  	wire.ConcreteType{&MerkleBlockMessage{}, MerkleResponseByte},
    61  )
    62  
    63  //DecodeMessage decode msg
    64  func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) {
    65  	msgType = bz[0]
    66  	n := int(0)
    67  	r := bytes.NewReader(bz)
    68  	msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, maxBlockchainResponseSize, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage
    69  	if err != nil && n != len(bz) {
    70  		err = errors.New("DecodeMessage() had bytes left over")
    71  	}
    72  	return
    73  }
    74  
    75  //GetBlockMessage request blocks from remote peers by height/hash
    76  type GetBlockMessage struct {
    77  	Height  uint64
    78  	RawHash [32]byte
    79  }
    80  
    81  //GetHash reutrn the hash of the request
    82  func (m *GetBlockMessage) GetHash() *bc.Hash {
    83  	hash := bc.NewHash(m.RawHash)
    84  	return &hash
    85  }
    86  
    87  func (m *GetBlockMessage) String() string {
    88  	if m.Height > 0 {
    89  		return fmt.Sprintf("{height: %d}", m.Height)
    90  	}
    91  	return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
    92  }
    93  
    94  //BlockMessage response get block msg
    95  type BlockMessage struct {
    96  	RawBlock []byte
    97  }
    98  
    99  //NewBlockMessage construct bock response msg
   100  func NewBlockMessage(block *types.Block) (*BlockMessage, error) {
   101  	rawBlock, err := block.MarshalText()
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  	return &BlockMessage{RawBlock: rawBlock}, nil
   106  }
   107  
   108  //GetBlock get block from msg
   109  func (m *BlockMessage) GetBlock() (*types.Block, error) {
   110  	block := &types.Block{
   111  		BlockHeader:  types.BlockHeader{},
   112  		Transactions: []*types.Tx{},
   113  	}
   114  	if err := block.UnmarshalText(m.RawBlock); err != nil {
   115  		return nil, err
   116  	}
   117  	return block, nil
   118  }
   119  
   120  func (m *BlockMessage) String() string {
   121  	block, err := m.GetBlock()
   122  	if err != nil {
   123  		return "{err: wrong message}"
   124  	}
   125  	blockHash := block.Hash()
   126  	return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
   127  }
   128  
   129  //GetHeadersMessage is one of the bytom msg type
   130  type GetHeadersMessage struct {
   131  	RawBlockLocator [][32]byte
   132  	RawStopHash     [32]byte
   133  }
   134  
   135  //NewGetHeadersMessage return a new GetHeadersMessage
   136  func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetHeadersMessage {
   137  	msg := &GetHeadersMessage{
   138  		RawStopHash: stopHash.Byte32(),
   139  	}
   140  	for _, hash := range blockLocator {
   141  		msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
   142  	}
   143  	return msg
   144  }
   145  
   146  //GetBlockLocator return the locator of the msg
   147  func (m *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
   148  	blockLocator := []*bc.Hash{}
   149  	for _, rawHash := range m.RawBlockLocator {
   150  		hash := bc.NewHash(rawHash)
   151  		blockLocator = append(blockLocator, &hash)
   152  	}
   153  	return blockLocator
   154  }
   155  
   156  func (m *GetHeadersMessage) String() string {
   157  	return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
   158  }
   159  
   160  //GetStopHash return the stop hash of the msg
   161  func (m *GetHeadersMessage) GetStopHash() *bc.Hash {
   162  	hash := bc.NewHash(m.RawStopHash)
   163  	return &hash
   164  }
   165  
   166  //HeadersMessage is one of the bytom msg type
   167  type HeadersMessage struct {
   168  	RawHeaders [][]byte
   169  }
   170  
   171  //NewHeadersMessage create a new HeadersMessage
   172  func NewHeadersMessage(headers []*types.BlockHeader) (*HeadersMessage, error) {
   173  	RawHeaders := [][]byte{}
   174  	for _, header := range headers {
   175  		data, err := json.Marshal(header)
   176  		if err != nil {
   177  			return nil, err
   178  		}
   179  
   180  		RawHeaders = append(RawHeaders, data)
   181  	}
   182  	return &HeadersMessage{RawHeaders: RawHeaders}, nil
   183  }
   184  
   185  //GetHeaders return the headers in the msg
   186  func (m *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
   187  	headers := []*types.BlockHeader{}
   188  	for _, data := range m.RawHeaders {
   189  		header := &types.BlockHeader{}
   190  		if err := json.Unmarshal(data, header); err != nil {
   191  			return nil, err
   192  		}
   193  
   194  		headers = append(headers, header)
   195  	}
   196  	return headers, nil
   197  }
   198  
   199  func (m *HeadersMessage) String() string {
   200  	return fmt.Sprintf("{header_length: %d}", len(m.RawHeaders))
   201  }
   202  
   203  //GetBlocksMessage is one of the bytom msg type
   204  type GetBlocksMessage struct {
   205  	RawBlockLocator [][32]byte
   206  	RawStopHash     [32]byte
   207  }
   208  
   209  //NewGetBlocksMessage create a new GetBlocksMessage
   210  func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
   211  	msg := &GetBlocksMessage{
   212  		RawStopHash: stopHash.Byte32(),
   213  	}
   214  	for _, hash := range blockLocator {
   215  		msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
   216  	}
   217  	return msg
   218  }
   219  
   220  //GetBlockLocator return the locator of the msg
   221  func (m *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
   222  	blockLocator := []*bc.Hash{}
   223  	for _, rawHash := range m.RawBlockLocator {
   224  		hash := bc.NewHash(rawHash)
   225  		blockLocator = append(blockLocator, &hash)
   226  	}
   227  	return blockLocator
   228  }
   229  
   230  //GetStopHash return the stop hash of the msg
   231  func (m *GetBlocksMessage) GetStopHash() *bc.Hash {
   232  	hash := bc.NewHash(m.RawStopHash)
   233  	return &hash
   234  }
   235  
   236  func (m *GetBlocksMessage) String() string {
   237  	return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
   238  }
   239  
   240  //BlocksMessage is one of the bytom msg type
   241  type BlocksMessage struct {
   242  	RawBlocks [][]byte
   243  }
   244  
   245  //NewBlocksMessage create a new BlocksMessage
   246  func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) {
   247  	rawBlocks := [][]byte{}
   248  	for _, block := range blocks {
   249  		data, err := json.Marshal(block)
   250  		if err != nil {
   251  			return nil, err
   252  		}
   253  
   254  		rawBlocks = append(rawBlocks, data)
   255  	}
   256  	return &BlocksMessage{RawBlocks: rawBlocks}, nil
   257  }
   258  
   259  //GetBlocks returns the blocks in the msg
   260  func (m *BlocksMessage) GetBlocks() ([]*types.Block, error) {
   261  	blocks := []*types.Block{}
   262  	for _, data := range m.RawBlocks {
   263  		block := &types.Block{}
   264  		if err := json.Unmarshal(data, block); err != nil {
   265  			return nil, err
   266  		}
   267  
   268  		blocks = append(blocks, block)
   269  	}
   270  	return blocks, nil
   271  }
   272  
   273  func (m *BlocksMessage) String() string {
   274  	return fmt.Sprintf("{blocks_length: %d}", len(m.RawBlocks))
   275  }
   276  
   277  //StatusRequestMessage status request msg
   278  type StatusRequestMessage struct{}
   279  
   280  func (m *StatusRequestMessage) String() string {
   281  	return "{}"
   282  }
   283  
   284  //StatusResponseMessage get status response msg
   285  type StatusResponseMessage struct {
   286  	Height      uint64
   287  	RawHash     [32]byte
   288  	GenesisHash [32]byte
   289  }
   290  
   291  //NewStatusResponseMessage construct get status response msg
   292  func NewStatusResponseMessage(blockHeader *types.BlockHeader, hash *bc.Hash) *StatusResponseMessage {
   293  	return &StatusResponseMessage{
   294  		Height:      blockHeader.Height,
   295  		RawHash:     blockHeader.Hash().Byte32(),
   296  		GenesisHash: hash.Byte32(),
   297  	}
   298  }
   299  
   300  //GetHash get hash from msg
   301  func (m *StatusResponseMessage) GetHash() *bc.Hash {
   302  	hash := bc.NewHash(m.RawHash)
   303  	return &hash
   304  }
   305  
   306  //GetGenesisHash get hash from msg
   307  func (m *StatusResponseMessage) GetGenesisHash() *bc.Hash {
   308  	hash := bc.NewHash(m.GenesisHash)
   309  	return &hash
   310  }
   311  
   312  func (m *StatusResponseMessage) String() string {
   313  	return fmt.Sprintf("{height: %d, hash: %s}", m.Height, hex.EncodeToString(m.RawHash[:]))
   314  }
   315  
   316  //TransactionMessage notify new tx msg
   317  type TransactionMessage struct {
   318  	RawTx []byte
   319  }
   320  
   321  //NewTransactionMessage construct notify new tx msg
   322  func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
   323  	rawTx, err := tx.TxData.MarshalText()
   324  	if err != nil {
   325  		return nil, err
   326  	}
   327  	return &TransactionMessage{RawTx: rawTx}, nil
   328  }
   329  
   330  //GetTransaction get tx from msg
   331  func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
   332  	tx := &types.Tx{}
   333  	if err := tx.UnmarshalText(m.RawTx); err != nil {
   334  		return nil, err
   335  	}
   336  	return tx, nil
   337  }
   338  
   339  func (m *TransactionMessage) String() string {
   340  	tx, err := m.GetTransaction()
   341  	if err != nil {
   342  		return "{err: wrong message}"
   343  	}
   344  	return fmt.Sprintf("{tx_size: %d, tx_hash: %s}", len(m.RawTx), tx.ID.String())
   345  }
   346  
   347  //MineBlockMessage new mined block msg
   348  type MineBlockMessage struct {
   349  	RawBlock []byte
   350  }
   351  
   352  //NewMinedBlockMessage construct new mined block msg
   353  func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
   354  	rawBlock, err := block.MarshalText()
   355  	if err != nil {
   356  		return nil, err
   357  	}
   358  	return &MineBlockMessage{RawBlock: rawBlock}, nil
   359  }
   360  
   361  //GetMineBlock get mine block from msg
   362  func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) {
   363  	block := &types.Block{}
   364  	if err := block.UnmarshalText(m.RawBlock); err != nil {
   365  		return nil, err
   366  	}
   367  	return block, nil
   368  }
   369  
   370  func (m *MineBlockMessage) String() string {
   371  	block, err := m.GetMineBlock()
   372  	if err != nil {
   373  		return "{err: wrong message}"
   374  	}
   375  	blockHash := block.Hash()
   376  	return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
   377  }
   378  
   379  //FilterLoadMessage tells the receiving peer to filter the transactions according to address.
   380  type FilterLoadMessage struct {
   381  	Addresses [][]byte
   382  }
   383  
   384  func (m *FilterLoadMessage) String() string {
   385  	return fmt.Sprintf("{addresses_length: %d}", len(m.Addresses))
   386  }
   387  
   388  // FilterAddMessage tells the receiving peer to add address to the filter.
   389  type FilterAddMessage struct {
   390  	Address []byte
   391  }
   392  
   393  func (m *FilterAddMessage) String() string {
   394  	return fmt.Sprintf("{address: %s}", hex.EncodeToString(m.Address))
   395  }
   396  
   397  //FilterClearMessage tells the receiving peer to remove a previously-set filter.
   398  type FilterClearMessage struct{}
   399  
   400  func (m *FilterClearMessage) String() string {
   401  	return "{}"
   402  }
   403  
   404  //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
   405  type GetMerkleBlockMessage struct {
   406  	Height  uint64
   407  	RawHash [32]byte
   408  }
   409  
   410  //GetHash reutrn the hash of the request
   411  func (m *GetMerkleBlockMessage) GetHash() *bc.Hash {
   412  	hash := bc.NewHash(m.RawHash)
   413  	return &hash
   414  }
   415  
   416  func (m *GetMerkleBlockMessage) String() string {
   417  	if m.Height > 0 {
   418  		return fmt.Sprintf("{height: %d}", m.Height)
   419  	}
   420  	return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
   421  }
   422  
   423  //MerkleBlockMessage return the merkle block to client
   424  type MerkleBlockMessage struct {
   425  	RawBlockHeader []byte
   426  	TxHashes       [][32]byte
   427  	RawTxDatas     [][]byte
   428  	StatusHashes   [][32]byte
   429  	RawTxStatuses  [][]byte
   430  	Flags          []byte
   431  }
   432  
   433  func (m *MerkleBlockMessage) setRawBlockHeader(bh types.BlockHeader) error {
   434  	rawHeader, err := bh.MarshalText()
   435  	if err != nil {
   436  		return err
   437  	}
   438  
   439  	m.RawBlockHeader = rawHeader
   440  	return nil
   441  }
   442  
   443  func (m *MerkleBlockMessage) setTxInfo(txHashes []*bc.Hash, txFlags []uint8, relatedTxs []*types.Tx) error {
   444  	for _, txHash := range txHashes {
   445  		m.TxHashes = append(m.TxHashes, txHash.Byte32())
   446  	}
   447  	for _, tx := range relatedTxs {
   448  		rawTxData, err := tx.MarshalText()
   449  		if err != nil {
   450  			return err
   451  		}
   452  
   453  		m.RawTxDatas = append(m.RawTxDatas, rawTxData)
   454  	}
   455  	m.Flags = txFlags
   456  	return nil
   457  }
   458  
   459  func (m *MerkleBlockMessage) setStatusInfo(statusHashes []*bc.Hash, relatedStatuses []*bc.TxVerifyResult) error {
   460  	for _, statusHash := range statusHashes {
   461  		m.StatusHashes = append(m.StatusHashes, statusHash.Byte32())
   462  	}
   463  
   464  	for _, status := range relatedStatuses {
   465  		rawStatusData, err := json.Marshal(status)
   466  		if err != nil {
   467  			return err
   468  		}
   469  
   470  		m.RawTxStatuses = append(m.RawTxStatuses, rawStatusData)
   471  	}
   472  	return nil
   473  }
   474  
   475  func (m *MerkleBlockMessage) String() string {
   476  	return "{}"
   477  }
   478  
   479  //NewMerkleBlockMessage construct merkle block message
   480  func NewMerkleBlockMessage() *MerkleBlockMessage {
   481  	return &MerkleBlockMessage{}
   482  }