github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/netsync/messages/chain_msg.go (about)

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