import (
"bytes"
+ "encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/tendermint/go-wire"
- "github.com/bytom/protocol/bc"
- "github.com/bytom/protocol/bc/types"
+ "github.com/bytom/bytom/protocol/bc"
+ "github.com/bytom/bytom/protocol/bc/types"
)
//protocol msg byte
NewTransactionByte = byte(0x30)
NewMineBlockByte = byte(0x40)
FilterLoadByte = byte(0x50)
- FilterClearByte = byte(0x51)
+ FilterAddByte = byte(0x51)
+ FilterClearByte = byte(0x52)
MerkleRequestByte = byte(0x60)
- MerkleResponseByte = byte(0x61)
+ MerkleResponseByte = byte(0x61)
maxBlockchainResponseSize = 22020096 + 2
)
//BlockchainMessage is a generic message for this reactor.
-type BlockchainMessage interface{}
+type BlockchainMessage interface {
+ String() string
+}
var _ = wire.RegisterInterface(
struct{ BlockchainMessage }{},
wire.ConcreteType{&TransactionMessage{}, NewTransactionByte},
wire.ConcreteType{&MineBlockMessage{}, NewMineBlockByte},
wire.ConcreteType{&FilterLoadMessage{}, FilterLoadByte},
+ wire.ConcreteType{&FilterAddMessage{}, FilterAddByte},
wire.ConcreteType{&FilterClearMessage{}, FilterClearByte},
wire.ConcreteType{&GetMerkleBlockMessage{}, MerkleRequestByte},
wire.ConcreteType{&MerkleBlockMessage{}, MerkleResponseByte},
return &hash
}
-//String convert msg to string
func (m *GetBlockMessage) String() string {
if m.Height > 0 {
- return fmt.Sprintf("GetBlockMessage{Height: %d}", m.Height)
+ return fmt.Sprintf("{height: %d}", m.Height)
}
- hash := m.GetHash()
- return fmt.Sprintf("GetBlockMessage{Hash: %s}", hash.String())
+ return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
}
//BlockMessage response get block msg
}
//GetBlock get block from msg
-func (m *BlockMessage) GetBlock() *types.Block {
+func (m *BlockMessage) GetBlock() (*types.Block, error) {
block := &types.Block{
BlockHeader: types.BlockHeader{},
Transactions: []*types.Tx{},
}
- block.UnmarshalText(m.RawBlock)
- return block
+ if err := block.UnmarshalText(m.RawBlock); err != nil {
+ return nil, err
+ }
+ return block, nil
}
-//String convert msg to string
func (m *BlockMessage) String() string {
- return fmt.Sprintf("BlockMessage{Size: %d}", len(m.RawBlock))
+ block, err := m.GetBlock()
+ if err != nil {
+ return "{err: wrong message}"
+ }
+ blockHash := block.Hash()
+ return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
}
//GetHeadersMessage is one of the bytom msg type
}
//GetBlockLocator return the locator of the msg
-func (msg *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
+func (m *GetHeadersMessage) GetBlockLocator() []*bc.Hash {
blockLocator := []*bc.Hash{}
- for _, rawHash := range msg.RawBlockLocator {
+ for _, rawHash := range m.RawBlockLocator {
hash := bc.NewHash(rawHash)
blockLocator = append(blockLocator, &hash)
}
return blockLocator
}
+func (m *GetHeadersMessage) String() string {
+ return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
+}
+
//GetStopHash return the stop hash of the msg
-func (msg *GetHeadersMessage) GetStopHash() *bc.Hash {
- hash := bc.NewHash(msg.RawStopHash)
+func (m *GetHeadersMessage) GetStopHash() *bc.Hash {
+ hash := bc.NewHash(m.RawStopHash)
return &hash
}
}
//GetHeaders return the headers in the msg
-func (msg *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
+func (m *HeadersMessage) GetHeaders() ([]*types.BlockHeader, error) {
headers := []*types.BlockHeader{}
- for _, data := range msg.RawHeaders {
+ for _, data := range m.RawHeaders {
header := &types.BlockHeader{}
if err := json.Unmarshal(data, header); err != nil {
return nil, err
return headers, nil
}
+func (m *HeadersMessage) String() string {
+ return fmt.Sprintf("{header_length: %d}", len(m.RawHeaders))
+}
+
//GetBlocksMessage is one of the bytom msg type
type GetBlocksMessage struct {
RawBlockLocator [][32]byte
}
//GetBlockLocator return the locator of the msg
-func (msg *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
+func (m *GetBlocksMessage) GetBlockLocator() []*bc.Hash {
blockLocator := []*bc.Hash{}
- for _, rawHash := range msg.RawBlockLocator {
+ for _, rawHash := range m.RawBlockLocator {
hash := bc.NewHash(rawHash)
blockLocator = append(blockLocator, &hash)
}
}
//GetStopHash return the stop hash of the msg
-func (msg *GetBlocksMessage) GetStopHash() *bc.Hash {
- hash := bc.NewHash(msg.RawStopHash)
+func (m *GetBlocksMessage) GetStopHash() *bc.Hash {
+ hash := bc.NewHash(m.RawStopHash)
return &hash
}
+func (m *GetBlocksMessage) String() string {
+ return fmt.Sprintf("{stop_hash: %s}", hex.EncodeToString(m.RawStopHash[:]))
+}
+
//BlocksMessage is one of the bytom msg type
type BlocksMessage struct {
RawBlocks [][]byte
}
//GetBlocks returns the blocks in the msg
-func (msg *BlocksMessage) GetBlocks() ([]*types.Block, error) {
+func (m *BlocksMessage) GetBlocks() ([]*types.Block, error) {
blocks := []*types.Block{}
- for _, data := range msg.RawBlocks {
+ for _, data := range m.RawBlocks {
block := &types.Block{}
if err := json.Unmarshal(data, block); err != nil {
return nil, err
return blocks, nil
}
+func (m *BlocksMessage) String() string {
+ return fmt.Sprintf("{blocks_length: %d}", len(m.RawBlocks))
+}
+
//StatusRequestMessage status request msg
type StatusRequestMessage struct{}
-//String
func (m *StatusRequestMessage) String() string {
- return "StatusRequestMessage"
+ return "{}"
}
//StatusResponseMessage get status response msg
return &hash
}
-//String convert msg to string
func (m *StatusResponseMessage) String() string {
- hash := m.GetHash()
- genesisHash := m.GetGenesisHash()
- return fmt.Sprintf("StatusResponseMessage{Height: %d, Best hash: %s, Genesis hash: %s}", m.Height, hash.String(), genesisHash.String())
+ return fmt.Sprintf("{height: %d, hash: %s}", m.Height, hex.EncodeToString(m.RawHash[:]))
}
//TransactionMessage notify new tx msg
return tx, nil
}
-//String
func (m *TransactionMessage) String() string {
- return fmt.Sprintf("TransactionMessage{Size: %d}", len(m.RawTx))
+ tx, err := m.GetTransaction()
+ if err != nil {
+ return "{err: wrong message}"
+ }
+ return fmt.Sprintf("{tx_size: %d, tx_hash: %s}", len(m.RawTx), tx.ID.String())
}
//MineBlockMessage new mined block msg
return block, nil
}
-//String convert msg to string
func (m *MineBlockMessage) String() string {
- return fmt.Sprintf("NewMineBlockMessage{Size: %d}", len(m.RawBlock))
+ block, err := m.GetMineBlock()
+ if err != nil {
+ return "{err: wrong message}"
+ }
+ blockHash := block.Hash()
+ return fmt.Sprintf("{block_height: %d, block_hash: %s}", block.Height, blockHash.String())
}
//FilterLoadMessage tells the receiving peer to filter the transactions according to address.
Addresses [][]byte
}
-//FilterClearMessage tells the receiving peer to remove a previously-set filter.
-type FilterClearMessage struct {}
+func (m *FilterLoadMessage) String() string {
+ return fmt.Sprintf("{addresses_length: %d}", len(m.Addresses))
+}
+
+// FilterAddMessage tells the receiving peer to add address to the filter.
+type FilterAddMessage struct {
+ Address []byte
+}
+
+func (m *FilterAddMessage) String() string {
+ return fmt.Sprintf("{address: %s}", hex.EncodeToString(m.Address))
+}
+
+//FilterClearMessage tells the receiving peer to remove a previously-set filter.
+type FilterClearMessage struct{}
+
+func (m *FilterClearMessage) String() string {
+ return "{}"
+}
//GetMerkleBlockMessage request merkle blocks from remote peers by height/hash
type GetMerkleBlockMessage struct {
Height uint64
- RawHash [32]byte
+ RawHash [32]byte
+}
+
+//GetHash reutrn the hash of the request
+func (m *GetMerkleBlockMessage) GetHash() *bc.Hash {
+ hash := bc.NewHash(m.RawHash)
+ return &hash
+}
+
+func (m *GetMerkleBlockMessage) String() string {
+ if m.Height > 0 {
+ return fmt.Sprintf("{height: %d}", m.Height)
+ }
+ return fmt.Sprintf("{hash: %s}", hex.EncodeToString(m.RawHash[:]))
}
//MerkleBlockMessage return the merkle block to client
type MerkleBlockMessage struct {
RawBlockHeader []byte
- TransactionCount uint64
- TxHashes [][32]byte
- TxFlags []byte
- RawTxDatas [][]byte
- StatusHashes [][32]byte
- StatusFlags []byte
- RawTxStatuses [][]byte
-}
\ No newline at end of file
+ TxHashes [][32]byte
+ RawTxDatas [][]byte
+ StatusHashes [][32]byte
+ RawTxStatuses [][]byte
+ Flags []byte
+}
+
+func (m *MerkleBlockMessage) setRawBlockHeader(bh types.BlockHeader) error {
+ rawHeader, err := bh.MarshalText()
+ if err != nil {
+ return err
+ }
+
+ m.RawBlockHeader = rawHeader
+ return nil
+}
+
+func (m *MerkleBlockMessage) setTxInfo(txHashes []*bc.Hash, txFlags []uint8, relatedTxs []*types.Tx) error {
+ for _, txHash := range txHashes {
+ m.TxHashes = append(m.TxHashes, txHash.Byte32())
+ }
+ for _, tx := range relatedTxs {
+ rawTxData, err := tx.MarshalText()
+ if err != nil {
+ return err
+ }
+
+ m.RawTxDatas = append(m.RawTxDatas, rawTxData)
+ }
+ m.Flags = txFlags
+ return nil
+}
+
+func (m *MerkleBlockMessage) setStatusInfo(statusHashes []*bc.Hash, relatedStatuses []*bc.TxVerifyResult) error {
+ for _, statusHash := range statusHashes {
+ m.StatusHashes = append(m.StatusHashes, statusHash.Byte32())
+ }
+
+ for _, status := range relatedStatuses {
+ rawStatusData, err := json.Marshal(status)
+ if err != nil {
+ return err
+ }
+
+ m.RawTxStatuses = append(m.RawTxStatuses, rawStatusData)
+ }
+ return nil
+}
+
+func (m *MerkleBlockMessage) String() string {
+ return "{}"
+}
+
+//NewMerkleBlockMessage construct merkle block message
+func NewMerkleBlockMessage() *MerkleBlockMessage {
+ return &MerkleBlockMessage{}
+}