OSDN Git Service

versoin1.1.9 (#594)
[bytom/vapor.git] / netsync / messages / chain_msg.go
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/vapor/protocol/bc"
11         "github.com/bytom/vapor/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         IrreversibleHeight uint64
276         IrreversibleHash   [32]byte
277 }
278
279 //NewStatusResponseMessage construct get status response msg
280 func NewStatusMessage(bestHeader, irreversibleHeader *types.BlockHeader) *StatusMessage {
281         return &StatusMessage{
282                 BestHeight:         bestHeader.Height,
283                 BestHash:           bestHeader.Hash().Byte32(),
284                 IrreversibleHeight: irreversibleHeader.Height,
285                 IrreversibleHash:   irreversibleHeader.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.IrreversibleHash)
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.IrreversibleHash[:]))
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         StatusHashes   [][32]byte
454         RawTxStatuses  [][]byte
455         Flags          []byte
456 }
457
458 func (m *MerkleBlockMessage) SetRawBlockHeader(bh types.BlockHeader) error {
459         rawHeader, err := bh.MarshalText()
460         if err != nil {
461                 return err
462         }
463
464         m.RawBlockHeader = rawHeader
465         return nil
466 }
467
468 func (m *MerkleBlockMessage) SetTxInfo(txHashes []*bc.Hash, txFlags []uint8, relatedTxs []*types.Tx) error {
469         for _, txHash := range txHashes {
470                 m.TxHashes = append(m.TxHashes, txHash.Byte32())
471         }
472         for _, tx := range relatedTxs {
473                 rawTxData, err := tx.MarshalText()
474                 if err != nil {
475                         return err
476                 }
477
478                 m.RawTxDatas = append(m.RawTxDatas, rawTxData)
479         }
480         m.Flags = txFlags
481         return nil
482 }
483
484 func (m *MerkleBlockMessage) SetStatusInfo(statusHashes []*bc.Hash, relatedStatuses []*bc.TxVerifyResult) error {
485         for _, statusHash := range statusHashes {
486                 m.StatusHashes = append(m.StatusHashes, statusHash.Byte32())
487         }
488
489         for _, status := range relatedStatuses {
490                 rawStatusData, err := json.Marshal(status)
491                 if err != nil {
492                         return err
493                 }
494
495                 m.RawTxStatuses = append(m.RawTxStatuses, rawStatusData)
496         }
497         return nil
498 }
499
500 func (m *MerkleBlockMessage) String() string {
501         return "{}"
502 }
503
504 //NewMerkleBlockMessage construct merkle block message
505 func NewMerkleBlockMessage() *MerkleBlockMessage {
506         return &MerkleBlockMessage{}
507 }