github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/netsync/messages/chain_msg.go (about) 1 package messages 2 3 import ( 4 "encoding/hex" 5 "encoding/json" 6 "fmt" 7 8 "github.com/tendermint/go-wire" 9 10 "github.com/bytom/bytom/protocol/bc" 11 "github.com/bytom/bytom/protocol/bc/types" 12 ) 13 14 //protocol msg byte 15 const ( 16 BlockchainChannel = byte(0x40) 17 18 BlockRequestByte = byte(0x10) 19 BlockResponseByte = byte(0x11) 20 HeadersRequestByte = byte(0x12) 21 HeadersResponseByte = byte(0x13) 22 BlocksRequestByte = byte(0x14) 23 BlocksResponseByte = byte(0x15) 24 StatusByte = byte(0x21) 25 NewTransactionByte = byte(0x30) 26 NewTransactionsByte = byte(0x31) 27 NewMineBlockByte = byte(0x40) 28 FilterLoadByte = byte(0x50) 29 FilterAddByte = byte(0x51) 30 FilterClearByte = byte(0x52) 31 MerkleRequestByte = byte(0x60) 32 MerkleResponseByte = byte(0x61) 33 34 MaxBlockchainResponseSize = 22020096 + 2 35 TxsMsgMaxTxNum = 1024 36 ) 37 38 //BlockchainMessage is a generic message for this reactor. 39 type BlockchainMessage interface { 40 String() string 41 } 42 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{&TransactionsMessage{}, NewTransactionsByte}, 54 wire.ConcreteType{&MineBlockMessage{}, NewMineBlockByte}, 55 wire.ConcreteType{&FilterLoadMessage{}, FilterLoadByte}, 56 wire.ConcreteType{&FilterAddMessage{}, FilterAddByte}, 57 wire.ConcreteType{&FilterClearMessage{}, FilterClearByte}, 58 wire.ConcreteType{&GetMerkleBlockMessage{}, MerkleRequestByte}, 59 wire.ConcreteType{&MerkleBlockMessage{}, MerkleResponseByte}, 60 ) 61 62 //GetBlockMessage request blocks from remote peers by height/hash 63 type GetBlockMessage struct { 64 Height uint64 65 RawHash [32]byte 66 } 67 68 //GetHash reutrn the hash of the request 69 func (m *GetBlockMessage) GetHash() *bc.Hash { 70 hash := bc.NewHash(m.RawHash) 71 return &hash 72 } 73 74 func (m *GetBlockMessage) String() string { 75 if m.Height > 0 { 76 return fmt.Sprintf("{height: %d}", m.Height) 77 } 78 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:])) 79 } 80 81 //BlockMessage response get block msg 82 type BlockMessage struct { 83 RawBlock []byte 84 } 85 86 //NewBlockMessage construct bock response msg 87 func NewBlockMessage(block *types.Block) (*BlockMessage, error) { 88 rawBlock, err := block.MarshalText() 89 if err != nil { 90 return nil, err 91 } 92 return &BlockMessage{RawBlock: rawBlock}, nil 93 } 94 95 //GetBlock get block from msg 96 func (m *BlockMessage) GetBlock() (*types.Block, error) { 97 block := &types.Block{ 98 BlockHeader: types.BlockHeader{}, 99 Transactions: []*types.Tx{}, 100 } 101 if err := block.UnmarshalText(m.RawBlock); err != nil { 102 return nil, err 103 } 104 return block, nil 105 } 106 107 func (m *BlockMessage) String() string { 108 block, err := m.GetBlock() 109 if err != nil { 110 return "{err: wrong message}" 111 } 112 blockHash := block.Hash() 113 return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String()) 114 } 115 116 //GetHeadersMessage is one of the bytom msg type 117 type GetHeadersMessage struct { 118 RawBlockLocator [][32]byte 119 RawStopHash [32]byte 120 Skip uint64 121 } 122 123 //NewGetHeadersMessage return a new GetHeadersMessage 124 func NewGetHeadersMessage(blockLocator []*bc.Hash, stopHash *bc.Hash, skip uint64) *GetHeadersMessage { 125 msg := &GetHeadersMessage{ 126 RawStopHash: stopHash.Byte32(), 127 Skip: skip, 128 } 129 for _, hash := range blockLocator { 130 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32()) 131 } 132 return msg 133 } 134 135 //GetBlockLocator return the locator of the msg 136 func (m *GetHeadersMessage) GetBlockLocator() []*bc.Hash { 137 blockLocator := []*bc.Hash{} 138 for _, rawHash := range m.RawBlockLocator { 139 hash := bc.NewHash(rawHash) 140 blockLocator = append(blockLocator, &hash) 141 } 142 return blockLocator 143 } 144 145 func (m *GetHeadersMessage) String() string { 146 stopHash := bc.NewHash(m.RawStopHash) 147 return fmt.Sprintf("{skip:%d,stopHash:%s}", m.Skip, stopHash.String()) 148 } 149 150 //GetStopHash return the stop hash of the msg 151 func (m *GetHeadersMessage) GetStopHash() *bc.Hash { 152 hash := bc.NewHash(m.RawStopHash) 153 return &hash 154 } 155 156 func (m *GetHeadersMessage) GetSkip() uint64 { 157 return m.Skip 158 } 159 160 //HeadersMessage is one of the bytom msg type 161 type HeadersMessage struct { 162 RawHeaders [][]byte 163 } 164 165 //NewHeadersMessage create a new HeadersMessage 166 func NewHeadersMessage(headers []*types.BlockHeader) (*HeadersMessage, error) { 167 RawHeaders := [][]byte{} 168 for _, header := range headers { 169 data, err := json.Marshal(header) 170 if err != nil { 171 return nil, err 172 } 173 174 RawHeaders = append(RawHeaders, data) 175 } 176 return &HeadersMessage{RawHeaders: RawHeaders}, nil 177 } 178 179 //GetHeaders return the headers in the msg 180 func (m *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) { 181 headers := []*types.BlockHeader{} 182 for _, data := range m.RawHeaders { 183 header := &types.BlockHeader{} 184 if err := json.Unmarshal(data, header); err != nil { 185 return nil, err 186 } 187 188 headers = append(headers, header) 189 } 190 return headers, nil 191 } 192 193 func (m *HeadersMessage) String() string { 194 return fmt.Sprintf("{header_length: %d}", len(m.RawHeaders)) 195 } 196 197 //GetBlocksMessage is one of the bytom msg type 198 type GetBlocksMessage struct { 199 RawBlockLocator [][32]byte 200 RawStopHash [32]byte 201 } 202 203 //NewGetBlocksMessage create a new GetBlocksMessage 204 func NewGetBlocksMessage(blockLocator []*bc.Hash, stopHash *bc.Hash) *GetBlocksMessage { 205 msg := &GetBlocksMessage{ 206 RawStopHash: stopHash.Byte32(), 207 } 208 for _, hash := range blockLocator { 209 msg.RawBlockLocator = append(msg.RawBlockLocator, hash.Byte32()) 210 } 211 return msg 212 } 213 214 //GetBlockLocator return the locator of the msg 215 func (m *GetBlocksMessage) GetBlockLocator() []*bc.Hash { 216 blockLocator := []*bc.Hash{} 217 for _, rawHash := range m.RawBlockLocator { 218 hash := bc.NewHash(rawHash) 219 blockLocator = append(blockLocator, &hash) 220 } 221 return blockLocator 222 } 223 224 //GetStopHash return the stop hash of the msg 225 func (m *GetBlocksMessage) GetStopHash() *bc.Hash { 226 hash := bc.NewHash(m.RawStopHash) 227 return &hash 228 } 229 230 func (m *GetBlocksMessage) String() string { 231 return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:])) 232 } 233 234 //BlocksMessage is one of the bytom msg type 235 type BlocksMessage struct { 236 RawBlocks [][]byte 237 } 238 239 //NewBlocksMessage create a new BlocksMessage 240 func NewBlocksMessage(blocks []*types.Block) (*BlocksMessage, error) { 241 rawBlocks := [][]byte{} 242 for _, block := range blocks { 243 data, err := json.Marshal(block) 244 if err != nil { 245 return nil, err 246 } 247 248 rawBlocks = append(rawBlocks, data) 249 } 250 return &BlocksMessage{RawBlocks: rawBlocks}, nil 251 } 252 253 //GetBlocks returns the blocks in the msg 254 func (m *BlocksMessage) GetBlocks() ([]*types.Block, error) { 255 blocks := []*types.Block{} 256 for _, data := range m.RawBlocks { 257 block := &types.Block{} 258 if err := json.Unmarshal(data, block); err != nil { 259 return nil, err 260 } 261 262 blocks = append(blocks, block) 263 } 264 return blocks, nil 265 } 266 267 func (m *BlocksMessage) String() string { 268 return fmt.Sprintf("{blocks_length: %d}", len(m.RawBlocks)) 269 } 270 271 //StatusResponseMessage get status response msg 272 type StatusMessage struct { 273 BestHeight uint64 274 BestHash [32]byte 275 JustifiedHeight uint64 276 JustifiedHash [32]byte 277 } 278 279 //NewStatusResponseMessage construct get status response msg 280 func NewStatusMessage(bestHeader, justifiedHeader *types.BlockHeader) *StatusMessage { 281 return &StatusMessage{ 282 BestHeight: bestHeader.Height, 283 BestHash: bestHeader.Hash().Byte32(), 284 JustifiedHeight: justifiedHeader.Height, 285 JustifiedHash: justifiedHeader.Hash().Byte32(), 286 } 287 } 288 289 //GetHash get hash from msg 290 func (m *StatusMessage) GetBestHash() *bc.Hash { 291 hash := bc.NewHash(m.BestHash) 292 return &hash 293 } 294 295 func (m *StatusMessage) GetIrreversibleHash() *bc.Hash { 296 hash := bc.NewHash(m.JustifiedHash) 297 return &hash 298 } 299 300 func (m *StatusMessage) String() string { 301 return fmt.Sprintf("{best hash: %s, irreversible hash: %s}", hex.EncodeToString(m.BestHash[:]), hex.EncodeToString(m.JustifiedHash[:])) 302 } 303 304 //TransactionMessage notify new tx msg 305 type TransactionMessage struct { 306 RawTx []byte 307 } 308 309 //NewTransactionMessage construct notify new tx msg 310 func NewTransactionMessage(tx *types.Tx) (*TransactionMessage, error) { 311 rawTx, err := tx.TxData.MarshalText() 312 if err != nil { 313 return nil, err 314 } 315 return &TransactionMessage{RawTx: rawTx}, nil 316 } 317 318 //GetTransaction get tx from msg 319 func (m *TransactionMessage) GetTransaction() (*types.Tx, error) { 320 tx := &types.Tx{} 321 if err := tx.UnmarshalText(m.RawTx); err != nil { 322 return nil, err 323 } 324 return tx, nil 325 } 326 327 func (m *TransactionMessage) String() string { 328 tx, err := m.GetTransaction() 329 if err != nil { 330 return "{err: wrong message}" 331 } 332 return fmt.Sprintf("{tx_size: %d, tx_hash: %s}", len(m.RawTx), tx.ID.String()) 333 } 334 335 //TransactionsMessage notify new txs msg 336 type TransactionsMessage struct { 337 RawTxs [][]byte 338 } 339 340 //NewTransactionsMessage construct notify new txs msg 341 func NewTransactionsMessage(txs []*types.Tx) (*TransactionsMessage, error) { 342 rawTxs := make([][]byte, 0, len(txs)) 343 for _, tx := range txs { 344 rawTx, err := tx.TxData.MarshalText() 345 if err != nil { 346 return nil, err 347 } 348 349 rawTxs = append(rawTxs, rawTx) 350 } 351 return &TransactionsMessage{RawTxs: rawTxs}, nil 352 } 353 354 //GetTransactions get txs from msg 355 func (m *TransactionsMessage) GetTransactions() ([]*types.Tx, error) { 356 txs := make([]*types.Tx, 0, len(m.RawTxs)) 357 for _, rawTx := range m.RawTxs { 358 tx := &types.Tx{} 359 if err := tx.UnmarshalText(rawTx); err != nil { 360 return nil, err 361 } 362 363 txs = append(txs, tx) 364 } 365 return txs, nil 366 } 367 368 func (m *TransactionsMessage) String() string { 369 return fmt.Sprintf("{tx_num: %d}", len(m.RawTxs)) 370 } 371 372 //MineBlockMessage new mined block msg 373 type MineBlockMessage struct { 374 RawBlock []byte 375 } 376 377 //NewMinedBlockMessage construct new mined block msg 378 func NewMinedBlockMessage(block *types.Block) (*MineBlockMessage, error) { 379 rawBlock, err := block.MarshalText() 380 if err != nil { 381 return nil, err 382 } 383 return &MineBlockMessage{RawBlock: rawBlock}, nil 384 } 385 386 //GetMineBlock get mine block from msg 387 func (m *MineBlockMessage) GetMineBlock() (*types.Block, error) { 388 block := &types.Block{} 389 if err := block.UnmarshalText(m.RawBlock); err != nil { 390 return nil, err 391 } 392 return block, nil 393 } 394 395 func (m *MineBlockMessage) String() string { 396 block, err := m.GetMineBlock() 397 if err != nil { 398 return "{err: wrong message}" 399 } 400 blockHash := block.Hash() 401 return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String()) 402 } 403 404 //FilterLoadMessage tells the receiving peer to filter the transactions according to address. 405 type FilterLoadMessage struct { 406 Addresses [][]byte 407 } 408 409 func (m *FilterLoadMessage) String() string { 410 return fmt.Sprintf("{addresses_length: %d}", len(m.Addresses)) 411 } 412 413 // FilterAddMessage tells the receiving peer to add address to the filter. 414 type FilterAddMessage struct { 415 Address []byte 416 } 417 418 func (m *FilterAddMessage) String() string { 419 return fmt.Sprintf("{address: %s}", hex.EncodeToString(m.Address)) 420 } 421 422 //FilterClearMessage tells the receiving peer to remove a previously-set filter. 423 type FilterClearMessage struct{} 424 425 func (m *FilterClearMessage) String() string { 426 return "{}" 427 } 428 429 //GetMerkleBlockMessage request merkle blocks from remote peers by height/hash 430 type GetMerkleBlockMessage struct { 431 Height uint64 432 RawHash [32]byte 433 } 434 435 //GetHash reutrn the hash of the request 436 func (m *GetMerkleBlockMessage) GetHash() *bc.Hash { 437 hash := bc.NewHash(m.RawHash) 438 return &hash 439 } 440 441 func (m *GetMerkleBlockMessage) String() string { 442 if m.Height > 0 { 443 return fmt.Sprintf("{height: %d}", m.Height) 444 } 445 return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:])) 446 } 447 448 //MerkleBlockMessage return the merkle block to client 449 type MerkleBlockMessage struct { 450 RawBlockHeader []byte 451 TxHashes [][32]byte 452 RawTxDatas [][]byte 453 Flags []byte 454 } 455 456 func (m *MerkleBlockMessage) SetRawBlockHeader(bh types.BlockHeader) error { 457 rawHeader, err := bh.MarshalText() 458 if err != nil { 459 return err 460 } 461 462 m.RawBlockHeader = rawHeader 463 return nil 464 } 465 466 func (m *MerkleBlockMessage) SetTxInfo(txHashes []*bc.Hash, txFlags []uint8, relatedTxs []*types.Tx) error { 467 for _, txHash := range txHashes { 468 m.TxHashes = append(m.TxHashes, txHash.Byte32()) 469 } 470 for _, tx := range relatedTxs { 471 rawTxData, err := tx.MarshalText() 472 if err != nil { 473 return err 474 } 475 476 m.RawTxDatas = append(m.RawTxDatas, rawTxData) 477 } 478 m.Flags = txFlags 479 return nil 480 } 481 482 func (m *MerkleBlockMessage) String() string { 483 return "{}" 484 } 485 486 //NewMerkleBlockMessage construct merkle block message 487 func NewMerkleBlockMessage() *MerkleBlockMessage { 488 return &MerkleBlockMessage{} 489 }