9 "github.com/tendermint/go-wire"
11 "github.com/bytom/protocol/bc"
12 "github.com/bytom/protocol/bc/types"
17 BlockchainChannel = byte(0x40)
19 BlockRequestByte = byte(0x10)
20 BlockResponseByte = byte(0x11)
21 HeadersRequestByte = byte(0x12)
22 HeadersResponseByte = byte(0x13)
23 BlocksRequestByte = byte(0x14)
24 BlocksResponseByte = byte(0x15)
25 StatusRequestByte = byte(0x20)
26 StatusResponseByte = byte(0x21)
27 NewTransactionByte = byte(0x30)
28 NewMineBlockByte = byte(0x40)
29 FilterLoadByte = byte(0x50)
30 FilterAddByte = byte(0x51)
31 FilterClearByte = byte(0x52)
32 MerkleRequestByte = byte(0x60)
33 MerkleResponseByte = byte(0x61)
35 maxBlockchainResponseSize = 22020096 + 2
38 //BlockchainMessage is a generic message for this reactor.
39 type BlockchainMessage interface{}
41 var _ = wire.RegisterInterface(
42 struct{ BlockchainMessage }{},
43 wire.ConcreteType{&GetBlockMessage{}, BlockRequestByte},
44 wire.ConcreteType{&BlockMessage{}, BlockResponseByte},
45 wire.ConcreteType{&GetHeadersMessage{}, HeadersRequestByte},
46 wire.ConcreteType{&HeadersMessage{}, HeadersResponseByte},
47 wire.ConcreteType{&GetBlocksMessage{}, BlocksRequestByte},
48 wire.ConcreteType{&BlocksMessage{}, BlocksResponseByte},
49 wire.ConcreteType{&StatusRequestMessage{}, StatusRequestByte},
50 wire.ConcreteType{&StatusResponseMessage{}, StatusResponseByte},
51 wire.ConcreteType{&TransactionMessage{}, NewTransactionByte},
52 wire.ConcreteType{&MineBlockMessage{}, NewMineBlockByte},
53 wire.ConcreteType{&FilterLoadMessage{}, FilterLoadByte},
54 wire.ConcreteType{&FilterAddMessage{}, FilterAddByte},
55 wire.ConcreteType{&FilterClearMessage{}, FilterClearByte},
56 wire.ConcreteType{&GetMerkleBlockMessage{}, MerkleRequestByte},
57 wire.ConcreteType{&MerkleBlockMessage{}, MerkleResponseByte},
60 //DecodeMessage decode msg
61 func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) {
64 r := bytes.NewReader(bz)
65 msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, maxBlockchainResponseSize, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage
66 if err != nil && n != len(bz) {
67 err = errors.New("DecodeMessage() had bytes left over")
72 //GetBlockMessage request blocks from remote peers by height/hash
73 type GetBlockMessage struct {
78 //GetHash reutrn the hash of the request
79 func (m *GetBlockMessage) GetHash() *bc.Hash {
80 hash := bc.NewHash(m.RawHash)
84 //String convert msg to string
85 func (m *GetBlockMessage) String() string {
87 return fmt.Sprintf("GetBlockMessage{Height: %d}", m.Height)
90 return fmt.Sprintf("GetBlockMessage{Hash: %s}", hash.String())
93 //BlockMessage response get block msg
94 type BlockMessage struct {
98 //NewBlockMessage construct bock response msg
99 func NewBlockMessage(block *types.Block) (*BlockMessage, error) {
100 rawBlock, err := block.MarshalText()
104 return &BlockMessage{RawBlock: rawBlock}, nil
107 //GetBlock get block from msg
108 func (m *BlockMessage) GetBlock() (*types.Block, error) {
109 block := &types.Block{
110 BlockHeader: types.BlockHeader{},
111 Transactions: []*types.Tx{},
113 if err := block.UnmarshalText(m.RawBlock); err != nil {
119 //String convert msg to string
120 func (m *BlockMessage) String() string {
121 return fmt.Sprintf("BlockMessage{Size: %d}", len(m.RawBlock))
124 //GetHeadersMessage is one of the bytom msg type
125 type GetHeadersMessage struct {
126 RawBlockLocator [][32]byte
130 //NewGetHeadersMessage return a new GetHeadersMessage
131 func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetHeadersMessage {
132 msg := &GetHeadersMessage{
133 RawStopHash: stopHash.Byte32(),
135 for _, hash := range blockLocator {
136 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
141 //GetBlockLocator return the locator of the msg
142 func (msg *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
143 blockLocator := []*bc.Hash{}
144 for _, rawHash := range msg.RawBlockLocator {
145 hash := bc.NewHash(rawHash)
146 blockLocator = append(blockLocator, &hash)
151 //GetStopHash return the stop hash of the msg
152 func (msg *GetHeadersMessage) GetStopHash() *bc.Hash {
153 hash := bc.NewHash(msg.RawStopHash)
157 //HeadersMessage is one of the bytom msg type
158 type HeadersMessage struct {
162 //NewHeadersMessage create a new HeadersMessage
163 func NewHeadersMessage(headers []*types.BlockHeader) (*HeadersMessage, error) {
164 RawHeaders := [][]byte{}
165 for _, header := range headers {
166 data, err := json.Marshal(header)
171 RawHeaders = append(RawHeaders, data)
173 return &HeadersMessage{RawHeaders: RawHeaders}, nil
176 //GetHeaders return the headers in the msg
177 func (msg *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
178 headers := []*types.BlockHeader{}
179 for _, data := range msg.RawHeaders {
180 header := &types.BlockHeader{}
181 if err := json.Unmarshal(data, header); err != nil {
185 headers = append(headers, header)
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 (msg *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
209 blockLocator := []*bc.Hash{}
210 for _, rawHash := range msg.RawBlockLocator {
211 hash := bc.NewHash(rawHash)
212 blockLocator = append(blockLocator, &hash)
217 //GetStopHash return the stop hash of the msg
218 func (msg *GetBlocksMessage) GetStopHash() *bc.Hash {
219 hash := bc.NewHash(msg.RawStopHash)
223 //BlocksMessage is one of the bytom msg type
224 type BlocksMessage struct {
228 //NewBlocksMessage create a new BlocksMessage
229 func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) {
230 rawBlocks := [][]byte{}
231 for _, block := range blocks {
232 data, err := json.Marshal(block)
237 rawBlocks = append(rawBlocks, data)
239 return &BlocksMessage{RawBlocks: rawBlocks}, nil
242 //GetBlocks returns the blocks in the msg
243 func (msg *BlocksMessage) GetBlocks() ([]*types.Block, error) {
244 blocks := []*types.Block{}
245 for _, data := range msg.RawBlocks {
246 block := &types.Block{}
247 if err := json.Unmarshal(data, block); err != nil {
251 blocks = append(blocks, block)
256 //StatusRequestMessage status request msg
257 type StatusRequestMessage struct{}
260 func (m *StatusRequestMessage) String() string {
261 return "StatusRequestMessage"
264 //StatusResponseMessage get status response msg
265 type StatusResponseMessage struct {
271 //NewStatusResponseMessage construct get status response msg
272 func NewStatusResponseMessage(blockHeader *types.BlockHeader, hash *bc.Hash) *StatusResponseMessage {
273 return &StatusResponseMessage{
274 Height: blockHeader.Height,
275 RawHash: blockHeader.Hash().Byte32(),
276 GenesisHash: hash.Byte32(),
280 //GetHash get hash from msg
281 func (m *StatusResponseMessage) GetHash() *bc.Hash {
282 hash := bc.NewHash(m.RawHash)
286 //GetGenesisHash get hash from msg
287 func (m *StatusResponseMessage) GetGenesisHash() *bc.Hash {
288 hash := bc.NewHash(m.GenesisHash)
292 //String convert msg to string
293 func (m *StatusResponseMessage) String() string {
295 genesisHash := m.GetGenesisHash()
296 return fmt.Sprintf("StatusResponseMessage{Height: %d, Best hash: %s, Genesis hash: %s}", m.Height, hash.String(), genesisHash.String())
299 //TransactionMessage notify new tx msg
300 type TransactionMessage struct {
304 //NewTransactionMessage construct notify new tx msg
305 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
306 rawTx, err := tx.TxData.MarshalText()
310 return &TransactionMessage{RawTx: rawTx}, nil
313 //GetTransaction get tx from msg
314 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
316 if err := tx.UnmarshalText(m.RawTx); err != nil {
323 func (m *TransactionMessage) String() string {
324 return fmt.Sprintf("TransactionMessage{Size: %d}", len(m.RawTx))
327 //MineBlockMessage new mined block msg
328 type MineBlockMessage struct {
332 //NewMinedBlockMessage construct new mined block msg
333 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
334 rawBlock, err := block.MarshalText()
338 return &MineBlockMessage{RawBlock: rawBlock}, nil
341 //GetMineBlock get mine block from msg
342 func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) {
343 block := &types.Block{}
344 if err := block.UnmarshalText(m.RawBlock); err != nil {
350 //String convert msg to string
351 func (m *MineBlockMessage) String() string {
352 return fmt.Sprintf("NewMineBlockMessage{Size: %d}", len(m.RawBlock))
355 //FilterLoadMessage tells the receiving peer to filter the transactions according to address.
356 type FilterLoadMessage struct {
360 // FilterAddMessage tells the receiving peer to add address to the filter.
361 type FilterAddMessage struct {
365 //FilterClearMessage tells the receiving peer to remove a previously-set filter.
366 type FilterClearMessage struct{}
368 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
369 type GetMerkleBlockMessage struct {
374 //GetHash reutrn the hash of the request
375 func (m *GetMerkleBlockMessage) GetHash() *bc.Hash {
376 hash := bc.NewHash(m.RawHash)
380 //MerkleBlockMessage return the merkle block to client
381 type MerkleBlockMessage struct {
382 RawBlockHeader []byte
385 StatusHashes [][32]byte
386 RawTxStatuses [][]byte
390 func (msg *MerkleBlockMessage) setRawBlockHeader(bh types.BlockHeader) error {
391 rawHeader, err := bh.MarshalText()
396 msg.RawBlockHeader = rawHeader
400 func (msg *MerkleBlockMessage) setTxInfo(txHashes []*bc.Hash, txFlags []uint8, relatedTxs []*types.Tx) error {
401 for _, txHash := range txHashes {
402 msg.TxHashes = append(msg.TxHashes, txHash.Byte32())
404 for _, tx := range relatedTxs {
405 rawTxData, err := tx.MarshalText()
410 msg.RawTxDatas = append(msg.RawTxDatas, rawTxData)
416 func (msg *MerkleBlockMessage) setStatusInfo(statusHashes []*bc.Hash, relatedStatuses []*bc.TxVerifyResult) error {
417 for _, statusHash := range statusHashes {
418 msg.StatusHashes = append(msg.StatusHashes, statusHash.Byte32())
421 for _, status := range relatedStatuses {
422 rawStatusData, err := json.Marshal(status)
427 msg.RawTxStatuses = append(msg.RawTxStatuses, rawStatusData)
432 //NewMerkleBlockMessage construct merkle block message
433 func NewMerkleBlockMessage() *MerkleBlockMessage {
434 return &MerkleBlockMessage{}