8 "github.com/tendermint/go-wire"
10 "github.com/vapor/protocol/bc"
11 "github.com/vapor/protocol/bc/types"
16 BlockchainChannel = byte(0x40)
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)
34 MaxBlockchainResponseSize = 22020096 + 2
38 //BlockchainMessage is a generic message for this reactor.
39 type BlockchainMessage interface {
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},
62 //GetBlockMessage request blocks from remote peers by height/hash
63 type GetBlockMessage struct {
68 //GetHash reutrn the hash of the request
69 func (m *GetBlockMessage) GetHash() *bc.Hash {
70 hash := bc.NewHash(m.RawHash)
74 func (m *GetBlockMessage) String() string {
76 return fmt.Sprintf("{height: %d}", m.Height)
78 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
81 //BlockMessage response get block msg
82 type BlockMessage struct {
86 //NewBlockMessage construct bock response msg
87 func NewBlockMessage(block *types.Block) (*BlockMessage, error) {
88 rawBlock, err := block.MarshalText()
92 return &BlockMessage{RawBlock: rawBlock}, nil
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{},
101 if err := block.UnmarshalText(m.RawBlock); err != nil {
107 func (m *BlockMessage) String() string {
108 block, err := m.GetBlock()
110 return "{err: wrong message}"
112 blockHash := block.Hash()
113 return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
116 //GetHeadersMessage is one of the bytom msg type
117 type GetHeadersMessage struct {
118 RawBlockLocator [][32]byte
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(),
129 for _, hash := range blockLocator {
130 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
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)
145 func (m *GetHeadersMessage) String() string {
146 stopHash := bc.NewHash(m.RawStopHash)
147 return fmt.Sprintf("{skip:%d,stopHash:%s}", m.Skip, stopHash.String())
150 //GetStopHash return the stop hash of the msg
151 func (m *GetHeadersMessage) GetStopHash() *bc.Hash {
152 hash := bc.NewHash(m.RawStopHash)
156 func (m *GetHeadersMessage) GetSkip() uint64 {
160 //HeadersMessage is one of the bytom msg type
161 type HeadersMessage struct {
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)
174 RawHeaders = append(RawHeaders, data)
176 return &HeadersMessage{RawHeaders: RawHeaders}, nil
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 {
188 headers = append(headers, header)
193 func (m *HeadersMessage) String() string {
194 return fmt.Sprintf("{header_length: %d}", len(m.RawHeaders))
197 //GetBlocksMessage is one of the bytom msg type
198 type GetBlocksMessage struct {
199 RawBlockLocator [][32]byte
203 //NewGetBlocksMessage create a new GetBlocksMessage
204 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
205 msg := &GetBlocksMessage{
206 RawStopHash: stopHash.Byte32(),
208 for _, hash := range blockLocator {
209 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
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)
224 //GetStopHash return the stop hash of the msg
225 func (m *GetBlocksMessage) GetStopHash() *bc.Hash {
226 hash := bc.NewHash(m.RawStopHash)
230 func (m *GetBlocksMessage) String() string {
231 return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
234 //BlocksMessage is one of the bytom msg type
235 type BlocksMessage struct {
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)
248 rawBlocks = append(rawBlocks, data)
250 return &BlocksMessage{RawBlocks: rawBlocks}, nil
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 {
262 blocks = append(blocks, block)
267 func (m *BlocksMessage) String() string {
268 return fmt.Sprintf("{blocks_length: %d}", len(m.RawBlocks))
271 //StatusResponseMessage get status response msg
272 type StatusMessage struct {
275 IrreversibleHeight uint64
276 IrreversibleHash [32]byte
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(),
289 //GetHash get hash from msg
290 func (m *StatusMessage) GetBestHash() *bc.Hash {
291 hash := bc.NewHash(m.BestHash)
295 func (m *StatusMessage) GetIrreversibleHash() *bc.Hash {
296 hash := bc.NewHash(m.IrreversibleHash)
300 func (m *StatusMessage) String() string {
301 return fmt.Sprintf("{best hash: %s, irreversible hash: %s}", hex.EncodeToString(m.BestHash[:]), hex.EncodeToString(m.IrreversibleHash[:]))
304 //TransactionMessage notify new tx msg
305 type TransactionMessage struct {
309 //NewTransactionMessage construct notify new tx msg
310 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
311 rawTx, err := tx.TxData.MarshalText()
315 return &TransactionMessage{RawTx: rawTx}, nil
318 //GetTransaction get tx from msg
319 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
321 if err := tx.UnmarshalText(m.RawTx); err != nil {
327 func (m *TransactionMessage) String() string {
328 tx, err := m.GetTransaction()
330 return "{err: wrong message}"
332 return fmt.Sprintf("{tx_size: %d, tx_hash: %s}", len(m.RawTx), tx.ID.String())
335 //TransactionsMessage notify new txs msg
336 type TransactionsMessage struct {
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()
349 rawTxs = append(rawTxs, rawTx)
351 return &TransactionsMessage{RawTxs: rawTxs}, nil
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 {
359 if err := tx.UnmarshalText(rawTx); err != nil {
363 txs = append(txs, tx)
368 func (m *TransactionsMessage) String() string {
369 return fmt.Sprintf("{tx_num: %d}", len(m.RawTxs))
372 //MineBlockMessage new mined block msg
373 type MineBlockMessage struct {
377 //NewMinedBlockMessage construct new mined block msg
378 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
379 rawBlock, err := block.MarshalText()
383 return &MineBlockMessage{RawBlock: rawBlock}, nil
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 {
395 func (m *MineBlockMessage) String() string {
396 block, err := m.GetMineBlock()
398 return "{err: wrong message}"
400 blockHash := block.Hash()
401 return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
404 //FilterLoadMessage tells the receiving peer to filter the transactions according to address.
405 type FilterLoadMessage struct {
409 func (m *FilterLoadMessage) String() string {
410 return fmt.Sprintf("{addresses_length: %d}", len(m.Addresses))
413 // FilterAddMessage tells the receiving peer to add address to the filter.
414 type FilterAddMessage struct {
418 func (m *FilterAddMessage) String() string {
419 return fmt.Sprintf("{address: %s}", hex.EncodeToString(m.Address))
422 //FilterClearMessage tells the receiving peer to remove a previously-set filter.
423 type FilterClearMessage struct{}
425 func (m *FilterClearMessage) String() string {
429 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
430 type GetMerkleBlockMessage struct {
435 //GetHash reutrn the hash of the request
436 func (m *GetMerkleBlockMessage) GetHash() *bc.Hash {
437 hash := bc.NewHash(m.RawHash)
441 func (m *GetMerkleBlockMessage) String() string {
443 return fmt.Sprintf("{height: %d}", m.Height)
445 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
448 //MerkleBlockMessage return the merkle block to client
449 type MerkleBlockMessage struct {
450 RawBlockHeader []byte
453 StatusHashes [][32]byte
454 RawTxStatuses [][]byte
458 func (m *MerkleBlockMessage) SetRawBlockHeader(bh types.BlockHeader) error {
459 rawHeader, err := bh.MarshalText()
464 m.RawBlockHeader = rawHeader
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())
472 for _, tx := range relatedTxs {
473 rawTxData, err := tx.MarshalText()
478 m.RawTxDatas = append(m.RawTxDatas, rawTxData)
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())
489 for _, status := range relatedStatuses {
490 rawStatusData, err := json.Marshal(status)
495 m.RawTxStatuses = append(m.RawTxStatuses, rawStatusData)
500 func (m *MerkleBlockMessage) String() string {
504 //NewMerkleBlockMessage construct merkle block message
505 func NewMerkleBlockMessage() *MerkleBlockMessage {
506 return &MerkleBlockMessage{}