OSDN Git Service

Format netsync module code directory (#88)
[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/vapor/protocol/bc"
11         "github.com/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 }
121
122 //NewGetHeadersMessage return a new GetHeadersMessage
123 func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetHeadersMessage {
124         msg := &GetHeadersMessage{
125                 RawStopHash: stopHash.Byte32(),
126         }
127         for _, hash := range blockLocator {
128                 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
129         }
130         return msg
131 }
132
133 //GetBlockLocator return the locator of the msg
134 func (m *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
135         blockLocator := []*bc.Hash{}
136         for _, rawHash := range m.RawBlockLocator {
137                 hash := bc.NewHash(rawHash)
138                 blockLocator = append(blockLocator, &hash)
139         }
140         return blockLocator
141 }
142
143 func (m *GetHeadersMessage) String() string {
144         return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
145 }
146
147 //GetStopHash return the stop hash of the msg
148 func (m *GetHeadersMessage) GetStopHash() *bc.Hash {
149         hash := bc.NewHash(m.RawStopHash)
150         return &hash
151 }
152
153 //HeadersMessage is one of the bytom msg type
154 type HeadersMessage struct {
155         RawHeaders [][]byte
156 }
157
158 //NewHeadersMessage create a new HeadersMessage
159 func NewHeadersMessage(headers []*types.BlockHeader) (*HeadersMessage, error) {
160         RawHeaders := [][]byte{}
161         for _, header := range headers {
162                 data, err := json.Marshal(header)
163                 if err != nil {
164                         return nil, err
165                 }
166
167                 RawHeaders = append(RawHeaders, data)
168         }
169         return &HeadersMessage{RawHeaders: RawHeaders}, nil
170 }
171
172 //GetHeaders return the headers in the msg
173 func (m *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
174         headers := []*types.BlockHeader{}
175         for _, data := range m.RawHeaders {
176                 header := &types.BlockHeader{}
177                 if err := json.Unmarshal(data, header); err != nil {
178                         return nil, err
179                 }
180
181                 headers = append(headers, header)
182         }
183         return headers, nil
184 }
185
186 func (m *HeadersMessage) String() string {
187         return fmt.Sprintf("{header_length: %d}", len(m.RawHeaders))
188 }
189
190 //GetBlocksMessage is one of the bytom msg type
191 type GetBlocksMessage struct {
192         RawBlockLocator [][32]byte
193         RawStopHash     [32]byte
194 }
195
196 //NewGetBlocksMessage create a new GetBlocksMessage
197 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
198         msg := &GetBlocksMessage{
199                 RawStopHash: stopHash.Byte32(),
200         }
201         for _, hash := range blockLocator {
202                 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
203         }
204         return msg
205 }
206
207 //GetBlockLocator return the locator of the msg
208 func (m *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
209         blockLocator := []*bc.Hash{}
210         for _, rawHash := range m.RawBlockLocator {
211                 hash := bc.NewHash(rawHash)
212                 blockLocator = append(blockLocator, &hash)
213         }
214         return blockLocator
215 }
216
217 //GetStopHash return the stop hash of the msg
218 func (m *GetBlocksMessage) GetStopHash() *bc.Hash {
219         hash := bc.NewHash(m.RawStopHash)
220         return &hash
221 }
222
223 func (m *GetBlocksMessage) String() string {
224         return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
225 }
226
227 //BlocksMessage is one of the bytom msg type
228 type BlocksMessage struct {
229         RawBlocks [][]byte
230 }
231
232 //NewBlocksMessage create a new BlocksMessage
233 func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) {
234         rawBlocks := [][]byte{}
235         for _, block := range blocks {
236                 data, err := json.Marshal(block)
237                 if err != nil {
238                         return nil, err
239                 }
240
241                 rawBlocks = append(rawBlocks, data)
242         }
243         return &BlocksMessage{RawBlocks: rawBlocks}, nil
244 }
245
246 //GetBlocks returns the blocks in the msg
247 func (m *BlocksMessage) GetBlocks() ([]*types.Block, error) {
248         blocks := []*types.Block{}
249         for _, data := range m.RawBlocks {
250                 block := &types.Block{}
251                 if err := json.Unmarshal(data, block); err != nil {
252                         return nil, err
253                 }
254
255                 blocks = append(blocks, block)
256         }
257         return blocks, nil
258 }
259
260 func (m *BlocksMessage) String() string {
261         return fmt.Sprintf("{blocks_length: %d}", len(m.RawBlocks))
262 }
263
264 //StatusResponseMessage get status response msg
265 type StatusMessage struct {
266         Height  uint64
267         RawHash [32]byte
268 }
269
270 //NewStatusResponseMessage construct get status response msg
271 func NewStatusMessage(blockHeader *types.BlockHeader) *StatusMessage {
272         return &StatusMessage{
273                 Height:  blockHeader.Height,
274                 RawHash: blockHeader.Hash().Byte32(),
275         }
276 }
277
278 //GetHash get hash from msg
279 func (m *StatusMessage) GetHash() *bc.Hash {
280         hash := bc.NewHash(m.RawHash)
281         return &hash
282 }
283
284 func (m *StatusMessage) String() string {
285         return fmt.Sprintf("{height: %d, hash: %s}", m.Height, hex.EncodeToString(m.RawHash[:]))
286 }
287
288 //TransactionMessage notify new tx msg
289 type TransactionMessage struct {
290         RawTx []byte
291 }
292
293 //NewTransactionMessage construct notify new tx msg
294 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
295         rawTx, err := tx.TxData.MarshalText()
296         if err != nil {
297                 return nil, err
298         }
299         return &TransactionMessage{RawTx: rawTx}, nil
300 }
301
302 //GetTransaction get tx from msg
303 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
304         tx := &types.Tx{}
305         if err := tx.UnmarshalText(m.RawTx); err != nil {
306                 return nil, err
307         }
308         return tx, nil
309 }
310
311 func (m *TransactionMessage) String() string {
312         tx, err := m.GetTransaction()
313         if err != nil {
314                 return "{err: wrong message}"
315         }
316         return fmt.Sprintf("{tx_size: %d, tx_hash: %s}", len(m.RawTx), tx.ID.String())
317 }
318
319 //TransactionsMessage notify new txs msg
320 type TransactionsMessage struct {
321         RawTxs [][]byte
322 }
323
324 //NewTransactionsMessage construct notify new txs msg
325 func NewTransactionsMessage(txs []*types.Tx) (*TransactionsMessage, error) {
326         rawTxs := make([][]byte, 0, len(txs))
327         for _, tx := range txs {
328                 rawTx, err := tx.TxData.MarshalText()
329                 if err != nil {
330                         return nil, err
331                 }
332
333                 rawTxs = append(rawTxs, rawTx)
334         }
335         return &TransactionsMessage{RawTxs: rawTxs}, nil
336 }
337
338 //GetTransactions get txs from msg
339 func (m *TransactionsMessage) GetTransactions() ([]*types.Tx, error) {
340         txs := make([]*types.Tx, 0, len(m.RawTxs))
341         for _, rawTx := range m.RawTxs {
342                 tx := &types.Tx{}
343                 if err := tx.UnmarshalText(rawTx); err != nil {
344                         return nil, err
345                 }
346
347                 txs = append(txs, tx)
348         }
349         return txs, nil
350 }
351
352 func (m *TransactionsMessage) String() string {
353         return fmt.Sprintf("{tx_num: %d}", len(m.RawTxs))
354 }
355
356 //MineBlockMessage new mined block msg
357 type MineBlockMessage struct {
358         RawBlock []byte
359 }
360
361 //NewMinedBlockMessage construct new mined block msg
362 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
363         rawBlock, err := block.MarshalText()
364         if err != nil {
365                 return nil, err
366         }
367         return &MineBlockMessage{RawBlock: rawBlock}, nil
368 }
369
370 //GetMineBlock get mine block from msg
371 func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) {
372         block := &types.Block{}
373         if err := block.UnmarshalText(m.RawBlock); err != nil {
374                 return nil, err
375         }
376         return block, nil
377 }
378
379 func (m *MineBlockMessage) String() string {
380         block, err := m.GetMineBlock()
381         if err != nil {
382                 return "{err: wrong message}"
383         }
384         blockHash := block.Hash()
385         return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
386 }
387
388 //FilterLoadMessage tells the receiving peer to filter the transactions according to address.
389 type FilterLoadMessage struct {
390         Addresses [][]byte
391 }
392
393 func (m *FilterLoadMessage) String() string {
394         return fmt.Sprintf("{addresses_length: %d}", len(m.Addresses))
395 }
396
397 // FilterAddMessage tells the receiving peer to add address to the filter.
398 type FilterAddMessage struct {
399         Address []byte
400 }
401
402 func (m *FilterAddMessage) String() string {
403         return fmt.Sprintf("{address: %s}", hex.EncodeToString(m.Address))
404 }
405
406 //FilterClearMessage tells the receiving peer to remove a previously-set filter.
407 type FilterClearMessage struct{}
408
409 func (m *FilterClearMessage) String() string {
410         return "{}"
411 }
412
413 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
414 type GetMerkleBlockMessage struct {
415         Height  uint64
416         RawHash [32]byte
417 }
418
419 //GetHash reutrn the hash of the request
420 func (m *GetMerkleBlockMessage) GetHash() *bc.Hash {
421         hash := bc.NewHash(m.RawHash)
422         return &hash
423 }
424
425 func (m *GetMerkleBlockMessage) String() string {
426         if m.Height > 0 {
427                 return fmt.Sprintf("{height: %d}", m.Height)
428         }
429         return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
430 }
431
432 //MerkleBlockMessage return the merkle block to client
433 type MerkleBlockMessage struct {
434         RawBlockHeader []byte
435         TxHashes       [][32]byte
436         RawTxDatas     [][]byte
437         StatusHashes   [][32]byte
438         RawTxStatuses  [][]byte
439         Flags          []byte
440 }
441
442 func (m *MerkleBlockMessage) SetRawBlockHeader(bh types.BlockHeader) error {
443         rawHeader, err := bh.MarshalText()
444         if err != nil {
445                 return err
446         }
447
448         m.RawBlockHeader = rawHeader
449         return nil
450 }
451
452 func (m *MerkleBlockMessage) SetTxInfo(txHashes []*bc.Hash, txFlags []uint8, relatedTxs []*types.Tx) error {
453         for _, txHash := range txHashes {
454                 m.TxHashes = append(m.TxHashes, txHash.Byte32())
455         }
456         for _, tx := range relatedTxs {
457                 rawTxData, err := tx.MarshalText()
458                 if err != nil {
459                         return err
460                 }
461
462                 m.RawTxDatas = append(m.RawTxDatas, rawTxData)
463         }
464         m.Flags = txFlags
465         return nil
466 }
467
468 func (m *MerkleBlockMessage) SetStatusInfo(statusHashes []*bc.Hash, relatedStatuses []*bc.TxVerifyResult) error {
469         for _, statusHash := range statusHashes {
470                 m.StatusHashes = append(m.StatusHashes, statusHash.Byte32())
471         }
472
473         for _, status := range relatedStatuses {
474                 rawStatusData, err := json.Marshal(status)
475                 if err != nil {
476                         return err
477                 }
478
479                 m.RawTxStatuses = append(m.RawTxStatuses, rawStatusData)
480         }
481         return nil
482 }
483
484 func (m *MerkleBlockMessage) String() string {
485         return "{}"
486 }
487
488 //NewMerkleBlockMessage construct merkle block message
489 func NewMerkleBlockMessage() *MerkleBlockMessage {
490         return &MerkleBlockMessage{}
491 }