github.com/turingchain2020/turingchain@v1.1.21/system/p2p/dht/protocol/broadcast/block_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  	"testing"
     9  
    10  	"github.com/turingchain2020/turingchain/common/merkle"
    11  	"github.com/turingchain2020/turingchain/queue"
    12  	"github.com/turingchain2020/turingchain/types"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func Test_sendBlock(t *testing.T) {
    17  
    18  	proto := newTestProtocol()
    19  	_, ok := proto.handleSend(&types.P2PBlock{Block: &types.Block{}}, testPidStr)
    20  	assert.True(t, ok)
    21  	_, ok = proto.handleSend(&types.P2PBlock{Block: &types.Block{}}, testPidStr)
    22  	assert.False(t, ok)
    23  	proto.p2pCfg.MinLtBlockSize = 0
    24  	data, ok := proto.handleSend(&types.P2PBlock{Block: testBlock}, "newpid")
    25  	ltBlock := data.Value.(*types.BroadCastData_LtBlock).LtBlock
    26  	assert.True(t, ok)
    27  	assert.True(t, ltBlock.MinerTx == minerTx)
    28  	assert.Equal(t, 3, len(ltBlock.STxHashes))
    29  }
    30  
    31  func Test_recvBlock(t *testing.T) {
    32  	q := queue.New("test")
    33  	go q.Start()
    34  	defer q.Close()
    35  	proto := newTestProtocolWithQueue(q)
    36  	recvData := &types.BroadCastData{}
    37  	block := &types.BroadCastData_Block{Block: &types.P2PBlock{}}
    38  	recvData.Value = block
    39  	err := proto.handleReceive(recvData, testPidStr, testAddr, broadcastV1)
    40  	assert.Equal(t, types.ErrInvalidParam, err)
    41  	block.Block = &types.P2PBlock{Block: testBlock}
    42  
    43  	newCli := q.Client()
    44  	newCli.Sub("blockchain")
    45  	err = proto.handleReceive(recvData, testPidStr, testAddr, broadcastV1)
    46  	assert.Nil(t, err)
    47  	err = proto.handleReceive(recvData, testPidStr, testAddr, broadcastV1)
    48  	assert.Nil(t, err)
    49  	blockHash := hex.EncodeToString(testBlock.Hash(proto.ChainCfg))
    50  	assert.True(t, proto.blockSendFilter.Contains(blockHash))
    51  	assert.True(t, proto.blockFilter.Contains(blockHash))
    52  
    53  	msg := <-newCli.Recv()
    54  	assert.Equal(t, types.EventBroadcastAddBlock, int(msg.Ty))
    55  	blc, ok := msg.Data.(*types.BlockPid)
    56  	assert.True(t, ok)
    57  	assert.Equal(t, testPid.Pretty(), blc.Pid)
    58  	assert.Equal(t, blockHash, hex.EncodeToString(blc.Block.Hash(proto.ChainCfg)))
    59  }
    60  
    61  func startHandleMempool(q queue.Queue, txList *[]*types.Transaction) chan struct{} {
    62  	client := q.Client()
    63  	client.Sub("mempool")
    64  	done := make(chan struct{})
    65  	go func() {
    66  		close(done)
    67  		for msg := range client.Recv() {
    68  			msg.Reply(client.NewMessage("p2p", types.EventTxListByHash, &types.ReplyTxList{Txs: *txList}))
    69  		}
    70  	}()
    71  	return done
    72  }
    73  
    74  func handleTestMsgReply(cli queue.Client, ty int64, reply interface{}, once bool) chan struct{} {
    75  	done := make(chan struct{})
    76  	go func() {
    77  		close(done)
    78  		for msg := range cli.Recv() {
    79  			if msg.Ty == ty {
    80  				msg.Reply(cli.NewMessage("p2p", ty, reply))
    81  				if once {
    82  					return
    83  				}
    84  			}
    85  		}
    86  	}()
    87  	return done
    88  }
    89  
    90  func Test_recvLtBlock(t *testing.T) {
    91  
    92  	q := queue.New("test")
    93  	proto := newTestProtocolWithQueue(q)
    94  	proto.p2pCfg.MinLtBlockSize = 0
    95  	defer q.Close()
    96  	memTxList := []*types.Transaction{tx, tx1, tx2}
    97  	done := startHandleMempool(q, &memTxList)
    98  	<-done
    99  	block := &types.Block{TxHash: []byte("test"), Txs: txList, Height: 10}
   100  	remotePid := "16Uiu2HAkudcLD1rRPmLL6PYqT3frNFUhTt764yWx1pfrVW8eWUeY"
   101  	sendData, _ := proto.handleSend(&types.P2PBlock{Block: block}, remotePid)
   102  
   103  	// block tx hash校验不过
   104  	err := proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
   105  	assert.Equal(t, errSendPeer, err)
   106  	blockHash := hex.EncodeToString(block.Hash(proto.ChainCfg))
   107  	assert.True(t, proto.blockSendFilter.Contains(blockHash))
   108  	//缺失超过1/3的交易数量
   109  	memTxList = []*types.Transaction{tx, nil, nil}
   110  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
   111  	assert.Equal(t, errSendPeer, err)
   112  	//交易组正确流程测试
   113  	txGroup, _ := types.CreateTxGroup([]*types.Transaction{tx1, tx2}, proto.ChainCfg.GetMinTxFeeRate())
   114  	gtx := txGroup.Tx()
   115  	memTxList = []*types.Transaction{tx, gtx}
   116  	block.TxHash = merkle.CalcMerkleRoot(proto.ChainCfg, block.GetHeight(), block.Txs)
   117  	newCli := q.Client()
   118  	newCli.Sub("blockchain")
   119  	sendData, _ = proto.handleSend(&types.P2PBlock{Block: block}, testPidStr)
   120  	err = proto.handleReceive(sendData, testPidStr, testAddr, broadcastV1)
   121  	assert.Nil(t, err)
   122  	msg := <-newCli.Recv()
   123  	assert.Equal(t, types.EventBroadcastAddBlock, int(msg.Ty))
   124  	blc, ok := msg.Data.(*types.BlockPid)
   125  	assert.True(t, ok)
   126  	assert.Equal(t, testPid.Pretty(), blc.Pid)
   127  	assert.Equal(t, block.Hash(proto.ChainCfg), blc.Block.Hash(proto.ChainCfg))
   128  }