github.com/turingchain2020/turingchain@v1.1.21/system/p2p/dht/protocol/broadcast/query_test.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  package broadcast
     5  
     6  import (
     7  	"encoding/hex"
     8  	"errors"
     9  	"testing"
    10  
    11  	"github.com/turingchain2020/turingchain/common/merkle"
    12  	"github.com/turingchain2020/turingchain/queue"
    13  	"github.com/turingchain2020/turingchain/types"
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  func Test_sendQueryData(t *testing.T) {
    18  
    19  	proto := newTestProtocol()
    20  	_, ok := proto.handleSend(&types.P2PQueryData{}, testPidStr)
    21  	assert.True(t, ok)
    22  }
    23  
    24  func Test_sendQueryReply(t *testing.T) {
    25  
    26  	proto := newTestProtocol()
    27  	_, ok := proto.handleSend(&types.P2PBlockTxReply{}, testPidStr)
    28  	assert.True(t, ok)
    29  }
    30  
    31  func Test_recvQueryData(t *testing.T) {
    32  
    33  	q := queue.New("test")
    34  	go q.Start()
    35  	defer q.Close()
    36  	proto := newTestProtocolWithQueue(q)
    37  	query := &types.P2PQueryData{
    38  		Value: &types.P2PQueryData_TxReq{
    39  			TxReq: &types.P2PTxReq{TxHash: tx.Hash()}}}
    40  	sendData, _ := proto.handleSend(query, testPidStr)
    41  	memTxs := []*types.Transaction{nil}
    42  	<-startHandleMempool(q, &memTxs)
    43  	err := proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    44  	assert.Equal(t, errRecvMempool, err)
    45  	memTxs = []*types.Transaction{tx}
    46  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    47  	assert.Equal(t, errSendPeer, err)
    48  
    49  	blockHash := hex.EncodeToString(testBlock.Hash(proto.ChainCfg))
    50  	blockChainCli := q.Client()
    51  	blockChainCli.Sub("blockchain")
    52  	req := &types.P2PBlockTxReq{
    53  		BlockHash: blockHash,
    54  		TxIndices: []int32{0, 1, 2},
    55  	}
    56  	query = &types.P2PQueryData{
    57  		Value: &types.P2PQueryData_BlockTxReq{
    58  			BlockTxReq: req,
    59  		},
    60  	}
    61  	sendData, _ = proto.handleSend(query, testPidStr)
    62  	<-handleTestMsgReply(blockChainCli, types.EventGetBlockByHashes, errors.New("errTest"), true)
    63  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    64  	assert.Equal(t, errQueryBlockChain, err)
    65  	<-handleTestMsgReply(blockChainCli, types.EventGetBlockByHashes, &types.BlockDetails{Items: []*types.BlockDetail{{}}}, true)
    66  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    67  	assert.Equal(t, errRecvBlockChain, err)
    68  	<-handleTestMsgReply(blockChainCli, types.EventGetBlockByHashes, &types.BlockDetails{Items: []*types.BlockDetail{{Block: testBlock}}}, false)
    69  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    70  	assert.Equal(t, errSendPeer, err)
    71  	req.TxIndices = nil
    72  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    73  	assert.Equal(t, errSendPeer, err)
    74  }
    75  
    76  func Test_recvQueryReply(t *testing.T) {
    77  
    78  	q := queue.New("test")
    79  	go q.Start()
    80  	defer q.Close()
    81  
    82  	proto := newTestProtocolWithQueue(q)
    83  	block := &types.Block{TxHash: []byte("test"), Txs: txList, Height: 10}
    84  	blockHash := hex.EncodeToString(block.Hash(proto.ChainCfg))
    85  	reply := &types.P2PBlockTxReply{
    86  		BlockHash: blockHash,
    87  	}
    88  	sendData, _ := proto.handleSend(reply, testPidStr)
    89  	err := proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    90  	assert.Equal(t, errLtBlockNotExist, err)
    91  	proto.ltBlockCache.Add(blockHash, nil, 1)
    92  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    93  	assert.Equal(t, errLtBlockNotExist, err)
    94  	proto.ltBlockCache.Add(blockHash, block, 1)
    95  	//block组装失败,重新请求
    96  	reply.Txs = []*types.Transaction{tx}
    97  	reply.TxIndices = []int32{2}
    98  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
    99  	assert.Equal(t, errSendPeer, err)
   100  
   101  	//block组装失败,不再请求
   102  	proto.ltBlockCache.Add(blockHash, block, 1)
   103  	reply.TxIndices = nil
   104  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
   105  	assert.Equal(t, errBuildBlockFailed, err)
   106  	//block组装成功
   107  	newCli := q.Client()
   108  	newCli.Sub("blockchain")
   109  	reply.Txs = block.Txs
   110  	block.TxHash = merkle.CalcMerkleRoot(proto.ChainCfg, block.Height, block.GetTxs())
   111  	proto.ltBlockCache.Add(blockHash, block, 1)
   112  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
   113  	assert.Nil(t, err)
   114  	msg := <-newCli.Recv()
   115  	assert.Equal(t, types.EventBroadcastAddBlock, int(msg.Ty))
   116  	blc, ok := msg.Data.(*types.BlockPid)
   117  	assert.True(t, ok)
   118  	assert.Equal(t, testPidStr, blc.Pid)
   119  	assert.Equal(t, block.Hash(proto.ChainCfg), blc.Block.Hash(proto.ChainCfg))
   120  
   121  }