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 StatusByte = 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 {
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{&MineBlockMessage{}, NewMineBlockByte},
54 wire.ConcreteType{&FilterLoadMessage{}, FilterLoadByte},
55 wire.ConcreteType{&FilterAddMessage{}, FilterAddByte},
56 wire.ConcreteType{&FilterClearMessage{}, FilterClearByte},
57 wire.ConcreteType{&GetMerkleBlockMessage{}, MerkleRequestByte},
58 wire.ConcreteType{&MerkleBlockMessage{}, MerkleResponseByte},
61 //DecodeMessage decode msg
62 func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) {
65 r := bytes.NewReader(bz)
66 msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, maxBlockchainResponseSize, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage
67 if err != nil && n != len(bz) {
68 err = errors.New("DecodeMessage() had bytes left over")
73 //GetBlockMessage request blocks from remote peers by height/hash
74 type GetBlockMessage struct {
79 //GetHash reutrn the hash of the request
80 func (m *GetBlockMessage) GetHash() *bc.Hash {
81 hash := bc.NewHash(m.RawHash)
85 func (m *GetBlockMessage) String() string {
87 return fmt.Sprintf("{height: %d}", m.Height)
89 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
92 //BlockMessage response get block msg
93 type BlockMessage struct {
97 //NewBlockMessage construct bock response msg
98 func NewBlockMessage(block *types.Block) (*BlockMessage, error) {
99 rawBlock, err := block.MarshalText()
103 return &BlockMessage{RawBlock: rawBlock}, nil
106 //GetBlock get block from msg
107 func (m *BlockMessage) GetBlock() (*types.Block, error) {
108 block := &types.Block{
109 BlockHeader: types.BlockHeader{},
110 Transactions: []*types.Tx{},
112 if err := block.UnmarshalText(m.RawBlock); err != nil {
118 func (m *BlockMessage) String() string {
119 block, err := m.GetBlock()
121 return "{err: wrong message}"
123 blockHash := block.Hash()
124 return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
127 //GetHeadersMessage is one of the bytom msg type
128 type GetHeadersMessage struct {
129 RawBlockLocator [][32]byte
133 //NewGetHeadersMessage return a new GetHeadersMessage
134 func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetHeadersMessage {
135 msg := &GetHeadersMessage{
136 RawStopHash: stopHash.Byte32(),
138 for _, hash := range blockLocator {
139 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
144 //GetBlockLocator return the locator of the msg
145 func (m *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
146 blockLocator := []*bc.Hash{}
147 for _, rawHash := range m.RawBlockLocator {
148 hash := bc.NewHash(rawHash)
149 blockLocator = append(blockLocator, &hash)
154 func (m *GetHeadersMessage) String() string {
155 return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
158 //GetStopHash return the stop hash of the msg
159 func (m *GetHeadersMessage) GetStopHash() *bc.Hash {
160 hash := bc.NewHash(m.RawStopHash)
164 //HeadersMessage is one of the bytom msg type
165 type HeadersMessage struct {
169 //NewHeadersMessage create a new HeadersMessage
170 func NewHeadersMessage(headers []*types.BlockHeader) (*HeadersMessage, error) {
171 RawHeaders := [][]byte{}
172 for _, header := range headers {
173 data, err := json.Marshal(header)
178 RawHeaders = append(RawHeaders, data)
180 return &HeadersMessage{RawHeaders: RawHeaders}, nil
183 //GetHeaders return the headers in the msg
184 func (m *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
185 headers := []*types.BlockHeader{}
186 for _, data := range m.RawHeaders {
187 header := &types.BlockHeader{}
188 if err := json.Unmarshal(data, header); err != nil {
192 headers = append(headers, header)
197 func (m *HeadersMessage) String() string {
198 return fmt.Sprintf("{header_length: %d}", len(m.RawHeaders))
201 //GetBlocksMessage is one of the bytom msg type
202 type GetBlocksMessage struct {
203 RawBlockLocator [][32]byte
207 //NewGetBlocksMessage create a new GetBlocksMessage
208 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
209 msg := &GetBlocksMessage{
210 RawStopHash: stopHash.Byte32(),
212 for _, hash := range blockLocator {
213 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
218 //GetBlockLocator return the locator of the msg
219 func (m *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
220 blockLocator := []*bc.Hash{}
221 for _, rawHash := range m.RawBlockLocator {
222 hash := bc.NewHash(rawHash)
223 blockLocator = append(blockLocator, &hash)
228 //GetStopHash return the stop hash of the msg
229 func (m *GetBlocksMessage) GetStopHash() *bc.Hash {
230 hash := bc.NewHash(m.RawStopHash)
234 func (m *GetBlocksMessage) String() string {
235 return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
238 //BlocksMessage is one of the bytom msg type
239 type BlocksMessage struct {
243 //NewBlocksMessage create a new BlocksMessage
244 func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) {
245 rawBlocks := [][]byte{}
246 for _, block := range blocks {
247 data, err := json.Marshal(block)
252 rawBlocks = append(rawBlocks, data)
254 return &BlocksMessage{RawBlocks: rawBlocks}, nil
257 //GetBlocks returns the blocks in the msg
258 func (m *BlocksMessage) GetBlocks() ([]*types.Block, error) {
259 blocks := []*types.Block{}
260 for _, data := range m.RawBlocks {
261 block := &types.Block{}
262 if err := json.Unmarshal(data, block); err != nil {
266 blocks = append(blocks, block)
271 func (m *BlocksMessage) String() string {
272 return fmt.Sprintf("{blocks_length: %d}", len(m.RawBlocks))
275 //StatusResponseMessage get status response msg
276 type StatusMessage struct {
281 //NewStatusResponseMessage construct get status response msg
282 func NewStatusMessage(blockHeader *types.BlockHeader) *StatusMessage {
283 return &StatusMessage{
284 Height: blockHeader.Height,
285 RawHash: blockHeader.Hash().Byte32(),
289 //GetHash get hash from msg
290 func (m *StatusMessage) GetHash() *bc.Hash {
291 hash := bc.NewHash(m.RawHash)
295 func (m *StatusMessage) String() string {
296 return fmt.Sprintf("{height: %d, hash: %s}", m.Height, hex.EncodeToString(m.RawHash[:]))
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 {
322 func (m *TransactionMessage) String() string {
323 tx, err := m.GetTransaction()
325 return "{err: wrong message}"
327 return fmt.Sprintf("{tx_size: %d, tx_hash: %s}", len(m.RawTx), tx.ID.String())
330 //MineBlockMessage new mined block msg
331 type MineBlockMessage struct {
335 //NewMinedBlockMessage construct new mined block msg
336 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
337 rawBlock, err := block.MarshalText()
341 return &MineBlockMessage{RawBlock: rawBlock}, nil
344 //GetMineBlock get mine block from msg
345 func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) {
346 block := &types.Block{}
347 if err := block.UnmarshalText(m.RawBlock); err != nil {
353 func (m *MineBlockMessage) String() string {
354 block, err := m.GetMineBlock()
356 return "{err: wrong message}"
358 blockHash := block.Hash()
359 return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
362 //FilterLoadMessage tells the receiving peer to filter the transactions according to address.
363 type FilterLoadMessage struct {
367 func (m *FilterLoadMessage) String() string {
368 return fmt.Sprintf("{addresses_length: %d}", len(m.Addresses))
371 // FilterAddMessage tells the receiving peer to add address to the filter.
372 type FilterAddMessage struct {
376 func (m *FilterAddMessage) String() string {
377 return fmt.Sprintf("{address: %s}", hex.EncodeToString(m.Address))
380 //FilterClearMessage tells the receiving peer to remove a previously-set filter.
381 type FilterClearMessage struct{}
383 func (m *FilterClearMessage) String() string {
387 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
388 type GetMerkleBlockMessage struct {
393 //GetHash reutrn the hash of the request
394 func (m *GetMerkleBlockMessage) GetHash() *bc.Hash {
395 hash := bc.NewHash(m.RawHash)
399 func (m *GetMerkleBlockMessage) String() string {
401 return fmt.Sprintf("{height: %d}", m.Height)
403 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
406 //MerkleBlockMessage return the merkle block to client
407 type MerkleBlockMessage struct {
408 RawBlockHeader []byte
411 StatusHashes [][32]byte
412 RawTxStatuses [][]byte
416 func (m *MerkleBlockMessage) setRawBlockHeader(bh types.BlockHeader) error {
417 rawHeader, err := bh.MarshalText()
422 m.RawBlockHeader = rawHeader
426 func (m *MerkleBlockMessage) setTxInfo(txHashes []*bc.Hash, txFlags []uint8, relatedTxs []*types.Tx) error {
427 for _, txHash := range txHashes {
428 m.TxHashes = append(m.TxHashes, txHash.Byte32())
430 for _, tx := range relatedTxs {
431 rawTxData, err := tx.MarshalText()
436 m.RawTxDatas = append(m.RawTxDatas, rawTxData)
442 func (m *MerkleBlockMessage) setStatusInfo(statusHashes []*bc.Hash, relatedStatuses []*bc.TxVerifyResult) error {
443 for _, statusHash := range statusHashes {
444 m.StatusHashes = append(m.StatusHashes, statusHash.Byte32())
447 for _, status := range relatedStatuses {
448 rawStatusData, err := json.Marshal(status)
453 m.RawTxStatuses = append(m.RawTxStatuses, rawStatusData)
458 func (m *MerkleBlockMessage) String() string {
462 //NewMerkleBlockMessage construct merkle block message
463 func NewMerkleBlockMessage() *MerkleBlockMessage {
464 return &MerkleBlockMessage{}