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 MerkleRequestByte = byte(0x60)
32 MerkleResponseByte = byte(0x61)
34 maxBlockchainResponseSize = 22020096 + 2
37 //BlockchainMessage is a generic message for this reactor.
38 type BlockchainMessage interface{}
40 var _ = wire.RegisterInterface(
41 struct{ BlockchainMessage }{},
42 wire.ConcreteType{&GetBlockMessage{}, BlockRequestByte},
43 wire.ConcreteType{&BlockMessage{}, BlockResponseByte},
44 wire.ConcreteType{&GetHeadersMessage{}, HeadersRequestByte},
45 wire.ConcreteType{&HeadersMessage{}, HeadersResponseByte},
46 wire.ConcreteType{&GetBlocksMessage{}, BlocksRequestByte},
47 wire.ConcreteType{&BlocksMessage{}, BlocksResponseByte},
48 wire.ConcreteType{&StatusRequestMessage{}, StatusRequestByte},
49 wire.ConcreteType{&StatusResponseMessage{}, StatusResponseByte},
50 wire.ConcreteType{&TransactionMessage{}, NewTransactionByte},
51 wire.ConcreteType{&MineBlockMessage{}, NewMineBlockByte},
52 wire.ConcreteType{&FilterLoadMessage{}, FilterLoadByte},
53 wire.ConcreteType{&FilterClearMessage{}, FilterClearByte},
54 wire.ConcreteType{&GetMerkleBlockMessage{}, MerkleRequestByte},
55 wire.ConcreteType{&MerkleBlockMessage{}, MerkleResponseByte},
58 //DecodeMessage decode msg
59 func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) {
62 r := bytes.NewReader(bz)
63 msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, maxBlockchainResponseSize, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage
64 if err != nil && n != len(bz) {
65 err = errors.New("DecodeMessage() had bytes left over")
70 //GetBlockMessage request blocks from remote peers by height/hash
71 type GetBlockMessage struct {
76 //GetHash reutrn the hash of the request
77 func (m *GetBlockMessage) GetHash() *bc.Hash {
78 hash := bc.NewHash(m.RawHash)
82 //String convert msg to string
83 func (m *GetBlockMessage) String() string {
85 return fmt.Sprintf("GetBlockMessage{Height: %d}", m.Height)
88 return fmt.Sprintf("GetBlockMessage{Hash: %s}", hash.String())
91 //BlockMessage response get block msg
92 type BlockMessage struct {
96 //NewBlockMessage construct bock response msg
97 func NewBlockMessage(block *types.Block) (*BlockMessage, error) {
98 rawBlock, err := block.MarshalText()
102 return &BlockMessage{RawBlock: rawBlock}, nil
105 //GetBlock get block from msg
106 func (m *BlockMessage) GetBlock() *types.Block {
107 block := &types.Block{
108 BlockHeader: types.BlockHeader{},
109 Transactions: []*types.Tx{},
111 block.UnmarshalText(m.RawBlock)
115 //String convert msg to string
116 func (m *BlockMessage) String() string {
117 return fmt.Sprintf("BlockMessage{Size: %d}", len(m.RawBlock))
120 //GetHeadersMessage is one of the bytom msg type
121 type GetHeadersMessage struct {
122 RawBlockLocator [][32]byte
126 //NewGetHeadersMessage return a new GetHeadersMessage
127 func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetHeadersMessage {
128 msg := &GetHeadersMessage{
129 RawStopHash: stopHash.Byte32(),
131 for _, hash := range blockLocator {
132 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
137 //GetBlockLocator return the locator of the msg
138 func (msg *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
139 blockLocator := []*bc.Hash{}
140 for _, rawHash := range msg.RawBlockLocator {
141 hash := bc.NewHash(rawHash)
142 blockLocator = append(blockLocator, &hash)
147 //GetStopHash return the stop hash of the msg
148 func (msg *GetHeadersMessage) GetStopHash() *bc.Hash {
149 hash := bc.NewHash(msg.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 (msg *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
174 headers := []*types.BlockHeader{}
175 for _, data := range msg.RawHeaders {
176 header := &types.BlockHeader{}
177 if err := json.Unmarshal(data, header); err != nil {
181 headers = append(headers, header)
186 //GetBlocksMessage is one of the bytom msg type
187 type GetBlocksMessage struct {
188 RawBlockLocator [][32]byte
192 //NewGetBlocksMessage create a new GetBlocksMessage
193 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
194 msg := &GetBlocksMessage{
195 RawStopHash: stopHash.Byte32(),
197 for _, hash := range blockLocator {
198 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
203 //GetBlockLocator return the locator of the msg
204 func (msg *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
205 blockLocator := []*bc.Hash{}
206 for _, rawHash := range msg.RawBlockLocator {
207 hash := bc.NewHash(rawHash)
208 blockLocator = append(blockLocator, &hash)
213 //GetStopHash return the stop hash of the msg
214 func (msg *GetBlocksMessage) GetStopHash() *bc.Hash {
215 hash := bc.NewHash(msg.RawStopHash)
219 //BlocksMessage is one of the bytom msg type
220 type BlocksMessage struct {
224 //NewBlocksMessage create a new BlocksMessage
225 func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) {
226 rawBlocks := [][]byte{}
227 for _, block := range blocks {
228 data, err := json.Marshal(block)
233 rawBlocks = append(rawBlocks, data)
235 return &BlocksMessage{RawBlocks: rawBlocks}, nil
238 //GetBlocks returns the blocks in the msg
239 func (msg *BlocksMessage) GetBlocks() ([]*types.Block, error) {
240 blocks := []*types.Block{}
241 for _, data := range msg.RawBlocks {
242 block := &types.Block{}
243 if err := json.Unmarshal(data, block); err != nil {
247 blocks = append(blocks, block)
252 //StatusRequestMessage status request msg
253 type StatusRequestMessage struct{}
256 func (m *StatusRequestMessage) String() string {
257 return "StatusRequestMessage"
260 //StatusResponseMessage get status response msg
261 type StatusResponseMessage struct {
267 //NewStatusResponseMessage construct get status response msg
268 func NewStatusResponseMessage(blockHeader *types.BlockHeader, hash *bc.Hash) *StatusResponseMessage {
269 return &StatusResponseMessage{
270 Height: blockHeader.Height,
271 RawHash: blockHeader.Hash().Byte32(),
272 GenesisHash: hash.Byte32(),
276 //GetHash get hash from msg
277 func (m *StatusResponseMessage) GetHash() *bc.Hash {
278 hash := bc.NewHash(m.RawHash)
282 //GetGenesisHash get hash from msg
283 func (m *StatusResponseMessage) GetGenesisHash() *bc.Hash {
284 hash := bc.NewHash(m.GenesisHash)
288 //String convert msg to string
289 func (m *StatusResponseMessage) String() string {
291 genesisHash := m.GetGenesisHash()
292 return fmt.Sprintf("StatusResponseMessage{Height: %d, Best hash: %s, Genesis hash: %s}", m.Height, hash.String(), genesisHash.String())
295 //TransactionMessage notify new tx msg
296 type TransactionMessage struct {
300 //NewTransactionMessage construct notify new tx msg
301 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
302 rawTx, err := tx.TxData.MarshalText()
306 return &TransactionMessage{RawTx: rawTx}, nil
309 //GetTransaction get tx from msg
310 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
312 if err := tx.UnmarshalText(m.RawTx); err != nil {
319 func (m *TransactionMessage) String() string {
320 return fmt.Sprintf("TransactionMessage{Size: %d}", len(m.RawTx))
323 //MineBlockMessage new mined block msg
324 type MineBlockMessage struct {
328 //NewMinedBlockMessage construct new mined block msg
329 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
330 rawBlock, err := block.MarshalText()
334 return &MineBlockMessage{RawBlock: rawBlock}, nil
337 //GetMineBlock get mine block from msg
338 func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) {
339 block := &types.Block{}
340 if err := block.UnmarshalText(m.RawBlock); err != nil {
346 //String convert msg to string
347 func (m *MineBlockMessage) String() string {
348 return fmt.Sprintf("NewMineBlockMessage{Size: %d}", len(m.RawBlock))
351 //FilterLoadMessage tells the receiving peer to filter the transactions according to address.
352 type FilterLoadMessage struct {
356 //FilterClearMessage tells the receiving peer to remove a previously-set filter.
357 type FilterClearMessage struct{}
359 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
360 type GetMerkleBlockMessage struct {
365 //MerkleBlockMessage return the merkle block to client
366 type MerkleBlockMessage struct {
367 RawBlockHeader []byte
368 TransactionCount uint64
372 StatusHashes [][32]byte
374 RawTxStatuses [][]byte