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 FilterClearByte = byte(0x51)
31 FilterAddByte = 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{&FilterClearMessage{}, FilterClearByte},
55 wire.ConcreteType{&FilterAddMessage{}, FilterAddByte},
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 {
109 block := &types.Block{
110 BlockHeader: types.BlockHeader{},
111 Transactions: []*types.Tx{},
113 block.UnmarshalText(m.RawBlock)
117 //String convert msg to string
118 func (m *BlockMessage) String() string {
119 return fmt.Sprintf("BlockMessage{Size: %d}", len(m.RawBlock))
122 //GetHeadersMessage is one of the bytom msg type
123 type GetHeadersMessage struct {
124 RawBlockLocator [][32]byte
128 //NewGetHeadersMessage return a new GetHeadersMessage
129 func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetHeadersMessage {
130 msg := &GetHeadersMessage{
131 RawStopHash: stopHash.Byte32(),
133 for _, hash := range blockLocator {
134 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
139 //GetBlockLocator return the locator of the msg
140 func (msg *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
141 blockLocator := []*bc.Hash{}
142 for _, rawHash := range msg.RawBlockLocator {
143 hash := bc.NewHash(rawHash)
144 blockLocator = append(blockLocator, &hash)
149 //GetStopHash return the stop hash of the msg
150 func (msg *GetHeadersMessage) GetStopHash() *bc.Hash {
151 hash := bc.NewHash(msg.RawStopHash)
155 //HeadersMessage is one of the bytom msg type
156 type HeadersMessage struct {
160 //NewHeadersMessage create a new HeadersMessage
161 func NewHeadersMessage(headers []*types.BlockHeader) (*HeadersMessage, error) {
162 RawHeaders := [][]byte{}
163 for _, header := range headers {
164 data, err := json.Marshal(header)
169 RawHeaders = append(RawHeaders, data)
171 return &HeadersMessage{RawHeaders: RawHeaders}, nil
174 //GetHeaders return the headers in the msg
175 func (msg *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
176 headers := []*types.BlockHeader{}
177 for _, data := range msg.RawHeaders {
178 header := &types.BlockHeader{}
179 if err := json.Unmarshal(data, header); err != nil {
183 headers = append(headers, header)
188 //GetBlocksMessage is one of the bytom msg type
189 type GetBlocksMessage struct {
190 RawBlockLocator [][32]byte
194 //NewGetBlocksMessage create a new GetBlocksMessage
195 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
196 msg := &GetBlocksMessage{
197 RawStopHash: stopHash.Byte32(),
199 for _, hash := range blockLocator {
200 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
205 //GetBlockLocator return the locator of the msg
206 func (msg *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
207 blockLocator := []*bc.Hash{}
208 for _, rawHash := range msg.RawBlockLocator {
209 hash := bc.NewHash(rawHash)
210 blockLocator = append(blockLocator, &hash)
215 //GetStopHash return the stop hash of the msg
216 func (msg *GetBlocksMessage) GetStopHash() *bc.Hash {
217 hash := bc.NewHash(msg.RawStopHash)
221 //BlocksMessage is one of the bytom msg type
222 type BlocksMessage struct {
226 //NewBlocksMessage create a new BlocksMessage
227 func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) {
228 rawBlocks := [][]byte{}
229 for _, block := range blocks {
230 data, err := json.Marshal(block)
235 rawBlocks = append(rawBlocks, data)
237 return &BlocksMessage{RawBlocks: rawBlocks}, nil
240 //GetBlocks returns the blocks in the msg
241 func (msg *BlocksMessage) GetBlocks() ([]*types.Block, error) {
242 blocks := []*types.Block{}
243 for _, data := range msg.RawBlocks {
244 block := &types.Block{}
245 if err := json.Unmarshal(data, block); err != nil {
249 blocks = append(blocks, block)
254 //StatusRequestMessage status request msg
255 type StatusRequestMessage struct{}
258 func (m *StatusRequestMessage) String() string {
259 return "StatusRequestMessage"
262 //StatusResponseMessage get status response msg
263 type StatusResponseMessage struct {
269 //NewStatusResponseMessage construct get status response msg
270 func NewStatusResponseMessage(blockHeader *types.BlockHeader, hash *bc.Hash) *StatusResponseMessage {
271 return &StatusResponseMessage{
272 Height: blockHeader.Height,
273 RawHash: blockHeader.Hash().Byte32(),
274 GenesisHash: hash.Byte32(),
278 //GetHash get hash from msg
279 func (m *StatusResponseMessage) GetHash() *bc.Hash {
280 hash := bc.NewHash(m.RawHash)
284 //GetGenesisHash get hash from msg
285 func (m *StatusResponseMessage) GetGenesisHash() *bc.Hash {
286 hash := bc.NewHash(m.GenesisHash)
290 //String convert msg to string
291 func (m *StatusResponseMessage) String() string {
293 genesisHash := m.GetGenesisHash()
294 return fmt.Sprintf("StatusResponseMessage{Height: %d, Best hash: %s, Genesis hash: %s}", m.Height, hash.String(), genesisHash.String())
297 //TransactionMessage notify new tx msg
298 type TransactionMessage struct {
302 //NewTransactionMessage construct notify new tx msg
303 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
304 rawTx, err := tx.TxData.MarshalText()
308 return &TransactionMessage{RawTx: rawTx}, nil
311 //GetTransaction get tx from msg
312 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
314 if err := tx.UnmarshalText(m.RawTx); err != nil {
321 func (m *TransactionMessage) String() string {
322 return fmt.Sprintf("TransactionMessage{Size: %d}", len(m.RawTx))
325 //MineBlockMessage new mined block msg
326 type MineBlockMessage struct {
330 //NewMinedBlockMessage construct new mined block msg
331 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
332 rawBlock, err := block.MarshalText()
336 return &MineBlockMessage{RawBlock: rawBlock}, nil
339 //GetMineBlock get mine block from msg
340 func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) {
341 block := &types.Block{}
342 if err := block.UnmarshalText(m.RawBlock); err != nil {
348 //String convert msg to string
349 func (m *MineBlockMessage) String() string {
350 return fmt.Sprintf("NewMineBlockMessage{Size: %d}", len(m.RawBlock))
353 //FilterLoadMessage new load addresses msg
354 type FilterLoadMessage struct {
358 //NewMinedBlockMessage construct new mined block msg
359 func NewFilterLoadMessage(addresses [][]byte) (*FilterLoadMessage, error) {
360 return &FilterLoadMessage{Addresses: addresses}, nil
363 //FilterLoadMessage new load addresses msg
364 type FilterAddMessage struct {
368 //NewMinedBlockMessage construct new mined block msg
369 func NewFilterAddMessage(addresse []byte) (*FilterAddMessage, error) {
370 return &FilterAddMessage{Addresse: addresse}, nil
373 //FilterClearMessage tells the receiving peer to remove a previously-set filter.
374 type FilterClearMessage struct{}
376 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
377 type GetMerkleBlockMessage struct {
382 //NewMinedBlockMessage construct new mined block msg
383 func NewGetMerkleBlockMessage(height uint64, rawHash [32]byte) *GetMerkleBlockMessage {
384 return &GetMerkleBlockMessage{Height: height, RawHash: rawHash}
387 //MerkleBlockMessage return the merkle block to client
388 type MerkleBlockMessage struct {
389 RawBlockHeader []byte
390 TransactionCount uint64
394 StatusHashes [][32]byte
396 RawTxStatuses [][]byte
399 //GetBlock get block from msg
400 func (m *MerkleBlockMessage) GetMerkleBlock() *types.MerkleBlock {
401 merkleBlock := &types.MerkleBlock{
402 BlockHeader: types.BlockHeader{},
403 Transactions: []*types.Tx{},
406 merkleBlock.BlockHeader.UnmarshalText(m.RawBlockHeader)
407 for _, rawTx := range m.RawTxDatas {
409 tx.UnmarshalText(rawTx)
410 merkleBlock.Transactions = append(merkleBlock.Transactions, tx)