10 "github.com/tendermint/go-wire"
12 "github.com/vapor/protocol/bc"
13 "github.com/vapor/protocol/bc/types"
18 BlockchainChannel = byte(0x40)
20 BlockRequestByte = byte(0x10)
21 BlockResponseByte = byte(0x11)
22 HeadersRequestByte = byte(0x12)
23 HeadersResponseByte = byte(0x13)
24 BlocksRequestByte = byte(0x14)
25 BlocksResponseByte = byte(0x15)
26 StatusRequestByte = byte(0x20)
27 StatusResponseByte = byte(0x21)
28 NewTransactionByte = byte(0x30)
29 NewMineBlockByte = byte(0x40)
30 FilterLoadByte = byte(0x50)
31 FilterAddByte = byte(0x51)
32 FilterClearByte = byte(0x52)
33 MerkleRequestByte = byte(0x60)
34 MerkleResponseByte = byte(0x61)
36 maxBlockchainResponseSize = 22020096 + 2
39 //BlockchainMessage is a generic message for this reactor.
40 type BlockchainMessage interface {
44 var _ = wire.RegisterInterface(
45 struct{ BlockchainMessage }{},
46 wire.ConcreteType{&GetBlockMessage{}, BlockRequestByte},
47 wire.ConcreteType{&BlockMessage{}, BlockResponseByte},
48 wire.ConcreteType{&GetHeadersMessage{}, HeadersRequestByte},
49 wire.ConcreteType{&HeadersMessage{}, HeadersResponseByte},
50 wire.ConcreteType{&GetBlocksMessage{}, BlocksRequestByte},
51 wire.ConcreteType{&BlocksMessage{}, BlocksResponseByte},
52 wire.ConcreteType{&StatusRequestMessage{}, StatusRequestByte},
53 wire.ConcreteType{&StatusResponseMessage{}, StatusResponseByte},
54 wire.ConcreteType{&TransactionMessage{}, NewTransactionByte},
55 wire.ConcreteType{&MineBlockMessage{}, NewMineBlockByte},
56 wire.ConcreteType{&FilterLoadMessage{}, FilterLoadByte},
57 wire.ConcreteType{&FilterAddMessage{}, FilterAddByte},
58 wire.ConcreteType{&FilterClearMessage{}, FilterClearByte},
59 wire.ConcreteType{&GetMerkleBlockMessage{}, MerkleRequestByte},
60 wire.ConcreteType{&MerkleBlockMessage{}, MerkleResponseByte},
63 //DecodeMessage decode msg
64 func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) {
67 r := bytes.NewReader(bz)
68 msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, maxBlockchainResponseSize, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage
69 if err != nil && n != len(bz) {
70 err = errors.New("DecodeMessage() had bytes left over")
75 //GetBlockMessage request blocks from remote peers by height/hash
76 type GetBlockMessage struct {
81 //GetHash reutrn the hash of the request
82 func (m *GetBlockMessage) GetHash() *bc.Hash {
83 hash := bc.NewHash(m.RawHash)
87 func (m *GetBlockMessage) String() string {
89 return fmt.Sprintf("{height: %d}", m.Height)
91 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
94 //BlockMessage response get block msg
95 type BlockMessage struct {
99 //NewBlockMessage construct bock response msg
100 func NewBlockMessage(block *types.Block) (*BlockMessage, error) {
101 rawBlock, err := block.MarshalText()
105 return &BlockMessage{RawBlock: rawBlock}, nil
108 //GetBlock get block from msg
109 func (m *BlockMessage) GetBlock() (*types.Block, error) {
110 block := &types.Block{
111 BlockHeader: types.BlockHeader{},
112 Transactions: []*types.Tx{},
114 if err := block.UnmarshalText(m.RawBlock); err != nil {
120 func (m *BlockMessage) String() string {
121 return fmt.Sprintf("{block_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 (m *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
143 blockLocator := []*bc.Hash{}
144 for _, rawHash := range m.RawBlockLocator {
145 hash := bc.NewHash(rawHash)
146 blockLocator = append(blockLocator, &hash)
151 func (m *GetHeadersMessage) String() string {
152 return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
155 //GetStopHash return the stop hash of the msg
156 func (m *GetHeadersMessage) GetStopHash() *bc.Hash {
157 hash := bc.NewHash(m.RawStopHash)
161 //HeadersMessage is one of the bytom msg type
162 type HeadersMessage struct {
166 //NewHeadersMessage create a new HeadersMessage
167 func NewHeadersMessage(headers []*types.BlockHeader) (*HeadersMessage, error) {
168 RawHeaders := [][]byte{}
169 for _, header := range headers {
170 data, err := json.Marshal(header)
175 RawHeaders = append(RawHeaders, data)
177 return &HeadersMessage{RawHeaders: RawHeaders}, nil
180 //GetHeaders return the headers in the msg
181 func (m *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
182 headers := []*types.BlockHeader{}
183 for _, data := range m.RawHeaders {
184 header := &types.BlockHeader{}
185 if err := json.Unmarshal(data, header); err != nil {
189 headers = append(headers, header)
194 func (m *HeadersMessage) String() string {
195 return fmt.Sprintf("{header_length: %d}", len(m.RawHeaders))
198 //GetBlocksMessage is one of the bytom msg type
199 type GetBlocksMessage struct {
200 RawBlockLocator [][32]byte
204 //NewGetBlocksMessage create a new GetBlocksMessage
205 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
206 msg := &GetBlocksMessage{
207 RawStopHash: stopHash.Byte32(),
209 for _, hash := range blockLocator {
210 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
215 //GetBlockLocator return the locator of the msg
216 func (m *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
217 blockLocator := []*bc.Hash{}
218 for _, rawHash := range m.RawBlockLocator {
219 hash := bc.NewHash(rawHash)
220 blockLocator = append(blockLocator, &hash)
225 //GetStopHash return the stop hash of the msg
226 func (m *GetBlocksMessage) GetStopHash() *bc.Hash {
227 hash := bc.NewHash(m.RawStopHash)
231 func (m *GetBlocksMessage) String() string {
232 return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
235 //BlocksMessage is one of the bytom msg type
236 type BlocksMessage struct {
240 //NewBlocksMessage create a new BlocksMessage
241 func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) {
242 rawBlocks := [][]byte{}
243 for _, block := range blocks {
244 data, err := json.Marshal(block)
249 rawBlocks = append(rawBlocks, data)
251 return &BlocksMessage{RawBlocks: rawBlocks}, nil
254 //GetBlocks returns the blocks in the msg
255 func (m *BlocksMessage) GetBlocks() ([]*types.Block, error) {
256 blocks := []*types.Block{}
257 for _, data := range m.RawBlocks {
258 block := &types.Block{}
259 if err := json.Unmarshal(data, block); err != nil {
263 blocks = append(blocks, block)
268 func (m *BlocksMessage) String() string {
269 return fmt.Sprintf("{blocks_length: %d}", len(m.RawBlocks))
272 //StatusRequestMessage status request msg
273 type StatusRequestMessage struct{}
275 func (m *StatusRequestMessage) String() string {
279 //StatusResponseMessage get status response msg
280 type StatusResponseMessage struct {
286 //NewStatusResponseMessage construct get status response msg
287 func NewStatusResponseMessage(blockHeader *types.BlockHeader, hash *bc.Hash) *StatusResponseMessage {
288 return &StatusResponseMessage{
289 Height: blockHeader.Height,
290 RawHash: blockHeader.Hash().Byte32(),
291 GenesisHash: hash.Byte32(),
295 //GetHash get hash from msg
296 func (m *StatusResponseMessage) GetHash() *bc.Hash {
297 hash := bc.NewHash(m.RawHash)
301 //GetGenesisHash get hash from msg
302 func (m *StatusResponseMessage) GetGenesisHash() *bc.Hash {
303 hash := bc.NewHash(m.GenesisHash)
307 func (m *StatusResponseMessage) String() string {
308 return fmt.Sprintf("{height: %d, hash: %s}", m.Height, hex.EncodeToString(m.RawHash[:]))
311 //TransactionMessage notify new tx msg
312 type TransactionMessage struct {
316 //NewTransactionMessage construct notify new tx msg
317 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
318 rawTx, err := tx.TxData.MarshalText()
322 return &TransactionMessage{RawTx: rawTx}, nil
325 //GetTransaction get tx from msg
326 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
328 if err := tx.UnmarshalText(m.RawTx); err != nil {
334 func (m *TransactionMessage) String() string {
335 return fmt.Sprintf("{tx_size: %d}", len(m.RawTx))
338 //MineBlockMessage new mined block msg
339 type MineBlockMessage struct {
343 //NewMinedBlockMessage construct new mined block msg
344 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
345 rawBlock, err := block.MarshalText()
349 return &MineBlockMessage{RawBlock: rawBlock}, nil
352 //GetMineBlock get mine block from msg
353 func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) {
354 block := &types.Block{}
355 if err := block.UnmarshalText(m.RawBlock); err != nil {
361 func (m *MineBlockMessage) String() string {
362 return fmt.Sprintf("{block_size: %d}", len(m.RawBlock))
365 //FilterLoadMessage tells the receiving peer to filter the transactions according to address.
366 type FilterLoadMessage struct {
370 func (m *FilterLoadMessage) String() string {
371 return fmt.Sprintf("{addresses_length: %d}", len(m.Addresses))
374 // FilterAddMessage tells the receiving peer to add address to the filter.
375 type FilterAddMessage struct {
379 func (m *FilterAddMessage) String() string {
380 return fmt.Sprintf("{address: %s}", hex.EncodeToString(m.Address))
383 //FilterClearMessage tells the receiving peer to remove a previously-set filter.
384 type FilterClearMessage struct{}
386 func (m *FilterClearMessage) String() string {
390 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
391 type GetMerkleBlockMessage struct {
396 //GetHash reutrn the hash of the request
397 func (m *GetMerkleBlockMessage) GetHash() *bc.Hash {
398 hash := bc.NewHash(m.RawHash)
402 func (m *GetMerkleBlockMessage) String() string {
404 return fmt.Sprintf("{height: %d}", m.Height)
406 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
409 //MerkleBlockMessage return the merkle block to client
410 type MerkleBlockMessage struct {
411 RawBlockHeader []byte
414 StatusHashes [][32]byte
415 RawTxStatuses [][]byte
419 func (m *MerkleBlockMessage) setRawBlockHeader(bh types.BlockHeader) error {
420 rawHeader, err := bh.MarshalText()
425 m.RawBlockHeader = rawHeader
429 func (m *MerkleBlockMessage) setTxInfo(txHashes []*bc.Hash, txFlags []uint8, relatedTxs []*types.Tx) error {
430 for _, txHash := range txHashes {
431 m.TxHashes = append(m.TxHashes, txHash.Byte32())
433 for _, tx := range relatedTxs {
434 rawTxData, err := tx.MarshalText()
439 m.RawTxDatas = append(m.RawTxDatas, rawTxData)
445 func (m *MerkleBlockMessage) setStatusInfo(statusHashes []*bc.Hash, relatedStatuses []*bc.TxVerifyResult) error {
446 for _, statusHash := range statusHashes {
447 m.StatusHashes = append(m.StatusHashes, statusHash.Byte32())
450 for _, status := range relatedStatuses {
451 rawStatusData, err := json.Marshal(status)
456 m.RawTxStatuses = append(m.RawTxStatuses, rawStatusData)
461 func (m *MerkleBlockMessage) String() string {
465 //NewMerkleBlockMessage construct merkle block message
466 func NewMerkleBlockMessage() *MerkleBlockMessage {
467 return &MerkleBlockMessage{}