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)
30 maxBlockchainResponseSize = 22020096 + 2
33 //BlockchainMessage is a generic message for this reactor.
34 type BlockchainMessage interface{}
36 var _ = wire.RegisterInterface(
37 struct{ BlockchainMessage }{},
38 wire.ConcreteType{&GetBlockMessage{}, BlockRequestByte},
39 wire.ConcreteType{&BlockMessage{}, BlockResponseByte},
40 wire.ConcreteType{&GetHeadersMessage{}, HeadersRequestByte},
41 wire.ConcreteType{&HeadersMessage{}, HeadersResponseByte},
42 wire.ConcreteType{&GetBlocksMessage{}, BlocksRequestByte},
43 wire.ConcreteType{&BlocksMessage{}, BlocksResponseByte},
44 wire.ConcreteType{&StatusRequestMessage{}, StatusRequestByte},
45 wire.ConcreteType{&StatusResponseMessage{}, StatusResponseByte},
46 wire.ConcreteType{&TransactionMessage{}, NewTransactionByte},
47 wire.ConcreteType{&MineBlockMessage{}, NewMineBlockByte},
50 //DecodeMessage decode msg
51 func DecodeMessage(bz []byte) (msgType byte, msg BlockchainMessage, err error) {
54 r := bytes.NewReader(bz)
55 msg = wire.ReadBinary(struct{ BlockchainMessage }{}, r, maxBlockchainResponseSize, &n, &err).(struct{ BlockchainMessage }).BlockchainMessage
56 if err != nil && n != len(bz) {
57 err = errors.New("DecodeMessage() had bytes left over")
62 //GetBlockMessage request blocks from remote peers by height/hash
63 type GetBlockMessage struct {
68 //GetHash reutrn the hash of the request
69 func (m *GetBlockMessage) GetHash() *bc.Hash {
70 hash := bc.NewHash(m.RawHash)
74 //String convert msg to string
75 func (m *GetBlockMessage) String() string {
77 return fmt.Sprintf("GetBlockMessage{Height: %d}", m.Height)
80 return fmt.Sprintf("GetBlockMessage{Hash: %s}", hash.String())
83 //BlockMessage response get block msg
84 type BlockMessage struct {
88 //NewBlockMessage construct bock response msg
89 func NewBlockMessage(block *types.Block) (*BlockMessage, error) {
90 rawBlock, err := block.MarshalText()
94 return &BlockMessage{RawBlock: rawBlock}, nil
97 //GetBlock get block from msg
98 func (m *BlockMessage) GetBlock() *types.Block {
99 block := &types.Block{
100 BlockHeader: types.BlockHeader{},
101 Transactions: []*types.Tx{},
103 block.UnmarshalText(m.RawBlock)
107 //String convert msg to string
108 func (m *BlockMessage) String() string {
109 return fmt.Sprintf("BlockMessage{Size: %d}", len(m.RawBlock))
112 //GetHeadersMessage is one of the bytom msg type
113 type GetHeadersMessage struct {
114 RawBlockLocator [][32]byte
118 //NewGetHeadersMessage return a new GetHeadersMessage
119 func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetHeadersMessage {
120 msg := &GetHeadersMessage{
121 RawStopHash: stopHash.Byte32(),
123 for _, hash := range blockLocator {
124 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
129 //GetBlockLocator return the locator of the msg
130 func (msg *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
131 blockLocator := []*bc.Hash{}
132 for _, rawHash := range msg.RawBlockLocator {
133 hash := bc.NewHash(rawHash)
134 blockLocator = append(blockLocator, &hash)
139 //GetStopHash return the stop hash of the msg
140 func (msg *GetHeadersMessage) GetStopHash() *bc.Hash {
141 hash := bc.NewHash(msg.RawStopHash)
145 //HeadersMessage is one of the bytom msg type
146 type HeadersMessage struct {
150 //NewHeadersMessage create a new HeadersMessage
151 func NewHeadersMessage(headers []*types.BlockHeader) (*HeadersMessage, error) {
152 RawHeaders := [][]byte{}
153 for _, header := range headers {
154 data, err := json.Marshal(header)
159 RawHeaders = append(RawHeaders, data)
161 return &HeadersMessage{RawHeaders: RawHeaders}, nil
164 //GetHeaders return the headers in the msg
165 func (msg *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
166 headers := []*types.BlockHeader{}
167 for _, data := range msg.RawHeaders {
168 header := &types.BlockHeader{}
169 if err := json.Unmarshal(data, header); err != nil {
173 headers = append(headers, header)
178 //GetBlocksMessage is one of the bytom msg type
179 type GetBlocksMessage struct {
180 RawBlockLocator [][32]byte
184 //NewGetBlocksMessage create a new GetBlocksMessage
185 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage {
186 msg := &GetBlocksMessage{
187 RawStopHash: stopHash.Byte32(),
189 for _, hash := range blockLocator {
190 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32())
195 //GetBlockLocator return the locator of the msg
196 func (msg *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
197 blockLocator := []*bc.Hash{}
198 for _, rawHash := range msg.RawBlockLocator {
199 hash := bc.NewHash(rawHash)
200 blockLocator = append(blockLocator, &hash)
205 //GetStopHash return the stop hash of the msg
206 func (msg *GetBlocksMessage) GetStopHash() *bc.Hash {
207 hash := bc.NewHash(msg.RawStopHash)
211 //BlocksMessage is one of the bytom msg type
212 type BlocksMessage struct {
216 //NewBlocksMessage create a new BlocksMessage
217 func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) {
218 rawBlocks := [][]byte{}
219 for _, block := range blocks {
220 data, err := json.Marshal(block)
225 rawBlocks = append(rawBlocks, data)
227 return &BlocksMessage{RawBlocks: rawBlocks}, nil
230 //GetBlocks returns the blocks in the msg
231 func (msg *BlocksMessage) GetBlocks() ([]*types.Block, error) {
232 blocks := []*types.Block{}
233 for _, data := range msg.RawBlocks {
234 block := &types.Block{}
235 if err := json.Unmarshal(data, block); err != nil {
239 blocks = append(blocks, block)
244 //StatusRequestMessage status request msg
245 type StatusRequestMessage struct{}
248 func (m *StatusRequestMessage) String() string {
249 return "StatusRequestMessage"
252 //StatusResponseMessage get status response msg
253 type StatusResponseMessage struct {
259 //NewStatusResponseMessage construct get status response msg
260 func NewStatusResponseMessage(blockHeader *types.BlockHeader, hash *bc.Hash) *StatusResponseMessage {
261 return &StatusResponseMessage{
262 Height: blockHeader.Height,
263 RawHash: blockHeader.Hash().Byte32(),
264 GenesisHash: hash.Byte32(),
268 //GetHash get hash from msg
269 func (m *StatusResponseMessage) GetHash() *bc.Hash {
270 hash := bc.NewHash(m.RawHash)
274 //GetGenesisHash get hash from msg
275 func (m *StatusResponseMessage) GetGenesisHash() *bc.Hash {
276 hash := bc.NewHash(m.GenesisHash)
280 //String convert msg to string
281 func (m *StatusResponseMessage) String() string {
283 genesisHash := m.GetGenesisHash()
284 return fmt.Sprintf("StatusResponseMessage{Height: %d, Best hash: %s, Genesis hash: %s}", m.Height, hash.String(), genesisHash.String())
287 //TransactionMessage notify new tx msg
288 type TransactionMessage struct {
292 //NewTransactionMessage construct notify new tx msg
293 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) {
294 rawTx, err := tx.TxData.MarshalText()
298 return &TransactionMessage{RawTx: rawTx}, nil
301 //GetTransaction get tx from msg
302 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) {
304 if err := tx.UnmarshalText(m.RawTx); err != nil {
311 func (m *TransactionMessage) String() string {
312 return fmt.Sprintf("TransactionMessage{Size: %d}", len(m.RawTx))
315 //MineBlockMessage new mined block msg
316 type MineBlockMessage struct {
320 //NewMinedBlockMessage construct new mined block msg
321 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) {
322 rawBlock, err := block.MarshalText()
326 return &MineBlockMessage{RawBlock: rawBlock}, nil
329 //GetMineBlock get mine block from msg
330 func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) {
331 block := &types.Block{}
332 if err := block.UnmarshalText(m.RawBlock); err != nil {
338 //String convert msg to string
339 func (m *MineBlockMessage) String() string {
340 return fmt.Sprintf("NewMineBlockMessage{Size: %d}", len(m.RawBlock))