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
122 //NewGetHeadersMessage return a new GetHeadersMessage
123 func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetHeadersMessage {
124 msg := &GetHeadersMessage{
125 RawStopHash: stopHash.Byte32(),
127 for _, hash := range blockLocator {
128 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
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)
143 func (m *GetHeadersMessage) String() string {
144 return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
147 //GetStopHash return the stop hash of the msg
148 func (m *GetHeadersMessage) GetStopHash() *bc.Hash {
149 hash := bc.NewHash(m.RawStopHash)
153 //HeadersMessage is one of the bytom msg type
154 type HeadersMessage struct {
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)
167 RawHeaders = append(RawHeaders, data)
169 return &HeadersMessage{RawHeaders: RawHeaders}, nil
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 {
181 headers = append(headers, header)
186 func (m *HeadersMessage) String() string {
187 return fmt.Sprintf("{header_length: %d}", len(m.RawHeaders))
190 //GetBlocksMessage is one of the bytom msg type
191 type GetBlocksMessage struct {
192 RawBlockLocator [][32]byte
196 //NewGetBlocksMessage create a new GetBlocksMessage
197 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
198 msg := &GetBlocksMessage{
199 RawStopHash: stopHash.Byte32(),
201 for _, hash := range blockLocator {
202 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
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)
217 //GetStopHash return the stop hash of the msg
218 func (m *GetBlocksMessage) GetStopHash() *bc.Hash {
219 hash := bc.NewHash(m.RawStopHash)
223 func (m *GetBlocksMessage) String() string {
224 return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
227 //BlocksMessage is one of the bytom msg type
228 type BlocksMessage struct {
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)
241 rawBlocks = append(rawBlocks, data)
243 return &BlocksMessage{RawBlocks: rawBlocks}, nil
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 {
255 blocks = append(blocks, block)
260 func (m *BlocksMessage) String() string {
261 return fmt.Sprintf("{blocks_length: %d}", len(m.RawBlocks))
264 //StatusResponseMessage get status response msg
265 type StatusMessage struct {
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(),
278 //GetHash get hash from msg
279 func (m *StatusMessage) GetHash() *bc.Hash {
280 hash := bc.NewHash(m.RawHash)
284 func (m *StatusMessage) String() string {
285 return fmt.Sprintf("{height: %d, hash: %s}", m.Height, hex.EncodeToString(m.RawHash[:]))
288 //TransactionMessage notify new tx msg
289 type TransactionMessage struct {
293 //NewTransactionMessage construct notify new tx msg
294 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
295 rawTx, err := tx.TxData.MarshalText()
299 return &TransactionMessage{RawTx: rawTx}, nil
302 //GetTransaction get tx from msg
303 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
305 if err := tx.UnmarshalText(m.RawTx); err != nil {
311 func (m *TransactionMessage) String() string {
312 tx, err := m.GetTransaction()
314 return "{err: wrong message}"
316 return fmt.Sprintf("{tx_size: %d, tx_hash: %s}", len(m.RawTx), tx.ID.String())
319 //TransactionsMessage notify new txs msg
320 type TransactionsMessage struct {
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()
333 rawTxs = append(rawTxs, rawTx)
335 return &TransactionsMessage{RawTxs: rawTxs}, nil
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 {
343 if err := tx.UnmarshalText(rawTx); err != nil {
347 txs = append(txs, tx)
352 func (m *TransactionsMessage) String() string {
353 return fmt.Sprintf("{tx_num: %d}", len(m.RawTxs))
356 //MineBlockMessage new mined block msg
357 type MineBlockMessage struct {
361 //NewMinedBlockMessage construct new mined block msg
362 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
363 rawBlock, err := block.MarshalText()
367 return &MineBlockMessage{RawBlock: rawBlock}, nil
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 {
379 func (m *MineBlockMessage) String() string {
380 block, err := m.GetMineBlock()
382 return "{err: wrong message}"
384 blockHash := block.Hash()
385 return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
388 //FilterLoadMessage tells the receiving peer to filter the transactions according to address.
389 type FilterLoadMessage struct {
393 func (m *FilterLoadMessage) String() string {
394 return fmt.Sprintf("{addresses_length: %d}", len(m.Addresses))
397 // FilterAddMessage tells the receiving peer to add address to the filter.
398 type FilterAddMessage struct {
402 func (m *FilterAddMessage) String() string {
403 return fmt.Sprintf("{address: %s}", hex.EncodeToString(m.Address))
406 //FilterClearMessage tells the receiving peer to remove a previously-set filter.
407 type FilterClearMessage struct{}
409 func (m *FilterClearMessage) String() string {
413 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
414 type GetMerkleBlockMessage struct {
419 //GetHash reutrn the hash of the request
420 func (m *GetMerkleBlockMessage) GetHash() *bc.Hash {
421 hash := bc.NewHash(m.RawHash)
425 func (m *GetMerkleBlockMessage) String() string {
427 return fmt.Sprintf("{height: %d}", m.Height)
429 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
432 //MerkleBlockMessage return the merkle block to client
433 type MerkleBlockMessage struct {
434 RawBlockHeader []byte
437 StatusHashes [][32]byte
438 RawTxStatuses [][]byte
442 func (m *MerkleBlockMessage) SetRawBlockHeader(bh types.BlockHeader) error {
443 rawHeader, err := bh.MarshalText()
448 m.RawBlockHeader = rawHeader
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())
456 for _, tx := range relatedTxs {
457 rawTxData, err := tx.MarshalText()
462 m.RawTxDatas = append(m.RawTxDatas, rawTxData)
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())
473 for _, status := range relatedStatuses {
474 rawStatusData, err := json.Marshal(status)
479 m.RawTxStatuses = append(m.RawTxStatuses, rawStatusData)
484 func (m *MerkleBlockMessage) String() string {
488 //NewMerkleBlockMessage construct merkle block message
489 func NewMerkleBlockMessage() *MerkleBlockMessage {
490 return &MerkleBlockMessage{}