github.com/klaytn/klaytn@v1.12.1/node/cn/handler_test.go (about)

     1  // Copyright 2019 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The klaytn library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package cn
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"fmt"
    22  	"math/big"
    23  	"math/rand"
    24  	"sort"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/golang/mock/gomock"
    29  	"github.com/klaytn/klaytn/blockchain"
    30  	"github.com/klaytn/klaytn/blockchain/types"
    31  	"github.com/klaytn/klaytn/common"
    32  	"github.com/klaytn/klaytn/consensus"
    33  	consensusmocks "github.com/klaytn/klaytn/consensus/mocks"
    34  	"github.com/klaytn/klaytn/crypto"
    35  	"github.com/klaytn/klaytn/datasync/downloader"
    36  	"github.com/klaytn/klaytn/event"
    37  	"github.com/klaytn/klaytn/networks/p2p"
    38  	"github.com/klaytn/klaytn/networks/p2p/discover"
    39  	"github.com/klaytn/klaytn/node/cn/mocks"
    40  	"github.com/klaytn/klaytn/params"
    41  	"github.com/klaytn/klaytn/reward"
    42  	workmocks "github.com/klaytn/klaytn/work/mocks"
    43  	"github.com/stretchr/testify/assert"
    44  )
    45  
    46  const blockNum1 = 20190902
    47  
    48  var td1 = big.NewInt(123)
    49  
    50  const numVals = 6
    51  
    52  var (
    53  	addrs    []common.Address
    54  	keys     []*ecdsa.PrivateKey
    55  	nodeids  []discover.NodeID
    56  	p2pPeers []*p2p.Peer
    57  	blocks   []*types.Block
    58  	hashes   []common.Hash
    59  )
    60  
    61  var (
    62  	tx1 *types.Transaction
    63  	txs types.Transactions
    64  )
    65  
    66  var hash1 common.Hash
    67  
    68  var signer types.Signer
    69  
    70  func init() {
    71  	addrs = make([]common.Address, numVals)
    72  	keys = make([]*ecdsa.PrivateKey, numVals)
    73  	nodeids = make([]discover.NodeID, numVals)
    74  	p2pPeers = make([]*p2p.Peer, numVals)
    75  	blocks = make([]*types.Block, numVals)
    76  	hashes = make([]common.Hash, numVals)
    77  
    78  	for i := range keys {
    79  		keys[i], _ = crypto.GenerateKey()
    80  		addrs[i] = crypto.PubkeyToAddress(keys[i].PublicKey)
    81  		nodeids[i] = discover.PubkeyID(&keys[i].PublicKey)
    82  		p2pPeers[i] = p2p.NewPeer(nodeids[i], nodeids[i].String(), []p2p.Cap{})
    83  		blocks[i] = newBlock(i)
    84  		hashes[i] = blocks[i].Hash()
    85  	}
    86  
    87  	signer := types.MakeSigner(params.BFTTestChainConfig, big.NewInt(2019))
    88  	tx1 = types.NewTransaction(111, addrs[0], big.NewInt(111), 111, big.NewInt(111), addrs[0][:])
    89  
    90  	tx1.Sign(signer, keys[0])
    91  	tx1.Size()
    92  	txs = types.Transactions{tx1}
    93  
    94  	hash1 = tx1.Hash()
    95  }
    96  
    97  func newMocks(t *testing.T) (*gomock.Controller, *consensusmocks.MockEngine, *workmocks.MockBlockChain, *workmocks.MockTxPool) {
    98  	mockCtrl := gomock.NewController(t)
    99  	mockEngine := consensusmocks.NewMockEngine(mockCtrl)
   100  	mockBlockChain := workmocks.NewMockBlockChain(mockCtrl)
   101  	mockTxPool := workmocks.NewMockTxPool(mockCtrl)
   102  
   103  	return mockCtrl, mockEngine, mockBlockChain, mockTxPool
   104  }
   105  
   106  func newBlock(blockNum int) *types.Block {
   107  	header := &types.Header{
   108  		Number:     big.NewInt(int64(blockNum)),
   109  		BlockScore: big.NewInt(int64(1)),
   110  		Extra:      addrs[0][:],
   111  		Governance: addrs[0][:],
   112  		Vote:       addrs[0][:],
   113  	}
   114  	header.Hash()
   115  	block := types.NewBlockWithHeader(header)
   116  	block = block.WithBody(types.Transactions{})
   117  	block.Hash()
   118  	block.Size()
   119  	block.BlockScore()
   120  	return block
   121  }
   122  
   123  func newBlockWithParentHash(blockNum int, parentHash common.Hash) *types.Block {
   124  	header := &types.Header{
   125  		Number:     big.NewInt(int64(blockNum)),
   126  		BlockScore: big.NewInt(int64(1)),
   127  		Extra:      addrs[0][:],
   128  		Governance: addrs[0][:],
   129  		Vote:       addrs[0][:],
   130  		ParentHash: parentHash,
   131  	}
   132  	header.Hash()
   133  	block := types.NewBlockWithHeader(header)
   134  	block = block.WithBody(types.Transactions{})
   135  	block.Hash()
   136  	block.Size()
   137  	block.BlockScore()
   138  	return block
   139  }
   140  
   141  func newReceipt(gasUsed int) *types.Receipt {
   142  	rct := types.NewReceipt(uint(gasUsed), common.Hash{}, uint64(gasUsed))
   143  	rct.Logs = []*types.Log{}
   144  	rct.Bloom = types.Bloom{}
   145  	return rct
   146  }
   147  
   148  func newStakingInfo(blockNumber uint64) *reward.StakingInfo {
   149  	return &reward.StakingInfo{
   150  		BlockNum:              blockNumber,
   151  		CouncilNodeAddrs:      []common.Address{{0x1}, {0x1}},
   152  		CouncilStakingAddrs:   []common.Address{{0x2}, {0x2}},
   153  		CouncilRewardAddrs:    []common.Address{{0x3}, {0x3}},
   154  		CouncilStakingAmounts: []uint64{2, 5, 6},
   155  	}
   156  }
   157  
   158  func TestNewProtocolManager(t *testing.T) {
   159  	// 1. If consensus.Engine returns an empty Protocol, NewProtocolManager throws an error.
   160  	{
   161  		mockCtrl, mockEngine, mockBlockChain, mockTxPool := newMocks(t)
   162  		defer mockCtrl.Finish()
   163  
   164  		block := newBlock(blockNum1)
   165  		mockBlockChain.EXPECT().CurrentBlock().Return(block).Times(1)
   166  		mockEngine.EXPECT().Protocol().Return(consensus.Protocol{}).Times(1)
   167  
   168  		pm, err := NewProtocolManager(nil, downloader.FastSync, 0, nil, mockTxPool,
   169  			mockEngine, mockBlockChain, nil, 1, -1, &Config{})
   170  
   171  		assert.Nil(t, pm)
   172  		assert.Equal(t, errIncompatibleConfig, err)
   173  	}
   174  }
   175  
   176  func TestProtocolManager_RegisterValidator(t *testing.T) {
   177  	pm := &ProtocolManager{}
   178  	mockCtrl := gomock.NewController(t)
   179  	defer mockCtrl.Finish()
   180  
   181  	mockPeerSet := NewMockPeerSet(mockCtrl)
   182  	pm.peers = mockPeerSet
   183  
   184  	val := &ByPassValidator{}
   185  
   186  	mockPeerSet.EXPECT().RegisterValidator(common.CONSENSUSNODE, val).Times(1)
   187  	mockPeerSet.EXPECT().RegisterValidator(common.ENDPOINTNODE, val).Times(1)
   188  	mockPeerSet.EXPECT().RegisterValidator(common.PROXYNODE, val).Times(1)
   189  	mockPeerSet.EXPECT().RegisterValidator(common.BOOTNODE, val).Times(1)
   190  	mockPeerSet.EXPECT().RegisterValidator(common.UNKNOWNNODE, val).Times(1)
   191  
   192  	pm.RegisterValidator(common.CONSENSUSNODE, val)
   193  	pm.RegisterValidator(common.ENDPOINTNODE, val)
   194  	pm.RegisterValidator(common.PROXYNODE, val)
   195  	pm.RegisterValidator(common.BOOTNODE, val)
   196  	pm.RegisterValidator(common.UNKNOWNNODE, val)
   197  }
   198  
   199  func TestProtocolManager_getWSEndPoint(t *testing.T) {
   200  	pm := &ProtocolManager{}
   201  
   202  	ws1 := "abc"
   203  	ws2 := "123"
   204  
   205  	pm.SetWsEndPoint(ws1)
   206  	assert.Equal(t, ws1, pm.getWSEndPoint())
   207  
   208  	pm.SetWsEndPoint(ws2)
   209  	assert.Equal(t, ws2, pm.getWSEndPoint())
   210  }
   211  
   212  func TestProtocolManager_removePeer(t *testing.T) {
   213  	peerID := nodeids[0].String()
   214  
   215  	{
   216  		pm := &ProtocolManager{}
   217  		mockCtrl := gomock.NewController(t)
   218  
   219  		mockPeerSet := NewMockPeerSet(mockCtrl)
   220  		pm.peers = mockPeerSet
   221  
   222  		mockPeerSet.EXPECT().Peer(peerID).Return(nil).Times(1)
   223  		pm.removePeer(peerID)
   224  
   225  		mockCtrl.Finish()
   226  	}
   227  
   228  	{
   229  		pm := &ProtocolManager{}
   230  		mockCtrl := gomock.NewController(t)
   231  
   232  		mockPeerSet := NewMockPeerSet(mockCtrl)
   233  		pm.peers = mockPeerSet
   234  
   235  		mockPeer := NewMockPeer(mockCtrl)
   236  
   237  		mockDownloader := mocks.NewMockProtocolManagerDownloader(mockCtrl)
   238  		mockDownloader.EXPECT().UnregisterPeer(peerID).Times(1)
   239  		pm.downloader = mockDownloader
   240  
   241  		// Return
   242  		mockPeer.EXPECT().ExistSnapExtension().Return(false).Times(1)
   243  
   244  		mockPeerSet.EXPECT().Unregister(peerID).Return(expectedErr).Times(1)
   245  
   246  		mockPeer.EXPECT().GetP2PPeer().Return(p2pPeers[0]).Times(1)
   247  
   248  		mockPeerSet.EXPECT().Peer(peerID).Return(mockPeer).Times(1)
   249  		pm.removePeer(peerID)
   250  
   251  		mockCtrl.Finish()
   252  	}
   253  
   254  	{
   255  		pm := &ProtocolManager{}
   256  		mockCtrl := gomock.NewController(t)
   257  
   258  		mockPeerSet := NewMockPeerSet(mockCtrl)
   259  		pm.peers = mockPeerSet
   260  
   261  		mockPeer := NewMockPeer(mockCtrl)
   262  
   263  		mockDownloader := mocks.NewMockProtocolManagerDownloader(mockCtrl)
   264  		mockDownloader.EXPECT().UnregisterPeer(peerID).Times(1)
   265  		pm.downloader = mockDownloader
   266  
   267  		// Return
   268  		mockPeer.EXPECT().ExistSnapExtension().Return(false).Times(1)
   269  
   270  		mockPeerSet.EXPECT().Unregister(peerID).Return(nil).Times(1)
   271  
   272  		mockPeer.EXPECT().GetP2PPeer().Return(p2pPeers[0]).Times(1)
   273  
   274  		mockPeerSet.EXPECT().Peer(peerID).Return(mockPeer).Times(1)
   275  		pm.removePeer(peerID)
   276  
   277  		mockCtrl.Finish()
   278  	}
   279  }
   280  
   281  func TestProtocolManager_getChainID(t *testing.T) {
   282  	pm := &ProtocolManager{}
   283  	mockCtrl := gomock.NewController(t)
   284  	defer mockCtrl.Finish()
   285  
   286  	cfg := &params.ChainConfig{ChainID: big.NewInt(12345)}
   287  
   288  	mockBlockChain := workmocks.NewMockBlockChain(mockCtrl)
   289  	mockBlockChain.EXPECT().Config().Return(cfg).AnyTimes()
   290  	pm.blockchain = mockBlockChain
   291  
   292  	assert.Equal(t, cfg.ChainID, pm.getChainID())
   293  }
   294  
   295  func TestProtocolManager_processMsg_panicRecover(t *testing.T) {
   296  	pm := &ProtocolManager{}
   297  	mockCtrl := gomock.NewController(t)
   298  	defer mockCtrl.Finish()
   299  
   300  	msgCh := make(chan p2p.Msg)
   301  	errCh := make(chan error)
   302  	addr := common.Address{}
   303  
   304  	mockPeer := NewMockPeer(mockCtrl)
   305  	mockPeer.EXPECT().GetVersion().Do(
   306  		func() { panic("panic test") },
   307  	)
   308  
   309  	// pm.processMsg will be panicked by the mockPeer
   310  	go pm.processMsg(msgCh, mockPeer, addr, errCh)
   311  
   312  	msgCh <- p2p.Msg{Code: NodeDataMsg}
   313  
   314  	// panic will be recovered and errCh will receive an error
   315  	err := <-errCh
   316  	assert.Equal(t, errUnknownProcessingError, err)
   317  }
   318  
   319  func TestSampleSize(t *testing.T) {
   320  	peers := make([]Peer, minNumPeersToSendBlock-1)
   321  	assert.Equal(t, len(peers), sampleSize(peers))
   322  
   323  	peers = make([]Peer, 4)
   324  	assert.Equal(t, minNumPeersToSendBlock, sampleSize(peers))
   325  
   326  	peers = make([]Peer, 16)
   327  	assert.Equal(t, 4, sampleSize(peers))
   328  }
   329  
   330  func TestSamplingPeers(t *testing.T) {
   331  	peers := make([]Peer, 10)
   332  	assert.Equal(t, peers, samplingPeers(peers, 20))
   333  	assert.Equal(t, peers[:5], samplingPeers(peers, 5))
   334  }
   335  
   336  func TestBroadcastBlock_NoParentExists(t *testing.T) {
   337  	pm := &ProtocolManager{}
   338  	pm.nodetype = common.ENDPOINTNODE
   339  	block := newBlock(blockNum1)
   340  	mockCtrl := gomock.NewController(t)
   341  	defer mockCtrl.Finish()
   342  
   343  	td := int64(100)
   344  	mockBlockChain := workmocks.NewMockBlockChain(mockCtrl)
   345  	mockBlockChain.EXPECT().GetBlock(block.ParentHash(), block.NumberU64()-1).Return(nil).Times(1)
   346  	mockBlockChain.EXPECT().GetTd(block.ParentHash(), block.NumberU64()-1).Return(big.NewInt(td)).Times(0)
   347  	pm.blockchain = mockBlockChain
   348  
   349  	mockPeers := NewMockPeerSet(mockCtrl)
   350  	pm.peers = mockPeers
   351  
   352  	mockPeer := NewMockPeer(mockCtrl)
   353  	mockPeers.EXPECT().SamplePeersToSendBlock(block, pm.nodetype).Return([]Peer{mockPeer}).Times(0)
   354  	mockPeer.EXPECT().AsyncSendNewBlock(block, new(big.Int).Add(block.BlockScore(), big.NewInt(td))).Times(0)
   355  
   356  	pm.BroadcastBlock(block)
   357  }
   358  
   359  func TestBroadcastBlock_ParentExists(t *testing.T) {
   360  	pm := &ProtocolManager{}
   361  	pm.nodetype = common.ENDPOINTNODE
   362  	block := newBlock(blockNum1)
   363  	mockCtrl := gomock.NewController(t)
   364  	defer mockCtrl.Finish()
   365  
   366  	td := int64(100)
   367  	mockBlockChain := workmocks.NewMockBlockChain(mockCtrl)
   368  	mockBlockChain.EXPECT().GetBlock(block.ParentHash(), block.NumberU64()-1).Return(block).Times(1)
   369  	mockBlockChain.EXPECT().GetTd(block.ParentHash(), block.NumberU64()-1).Return(big.NewInt(td)).Times(1)
   370  	pm.blockchain = mockBlockChain
   371  
   372  	mockPeers := NewMockPeerSet(mockCtrl)
   373  	pm.peers = mockPeers
   374  
   375  	mockPeer := NewMockPeer(mockCtrl)
   376  	mockPeers.EXPECT().SamplePeersToSendBlock(block, pm.nodetype).Return([]Peer{mockPeer}).Times(1)
   377  	mockPeer.EXPECT().AsyncSendNewBlock(block, new(big.Int).Add(block.BlockScore(), big.NewInt(td))).Times(1)
   378  
   379  	pm.BroadcastBlock(block)
   380  }
   381  
   382  func TestBroadcastBlockHash(t *testing.T) {
   383  	pm := &ProtocolManager{}
   384  	pm.nodetype = common.ENDPOINTNODE
   385  	block := newBlock(blockNum1)
   386  	mockCtrl := gomock.NewController(t)
   387  	defer mockCtrl.Finish()
   388  
   389  	// When the given block doesn't exist.
   390  	{
   391  		mockBlockChain := workmocks.NewMockBlockChain(mockCtrl)
   392  		mockBlockChain.EXPECT().HasBlock(block.Hash(), block.NumberU64()).Return(false).Times(1)
   393  		pm.blockchain = mockBlockChain
   394  		pm.BroadcastBlockHash(block)
   395  	}
   396  
   397  	// When the given block exists.
   398  	{
   399  		mockBlockChain := workmocks.NewMockBlockChain(mockCtrl)
   400  		mockBlockChain.EXPECT().HasBlock(block.Hash(), block.NumberU64()).Return(true).Times(1)
   401  		pm.blockchain = mockBlockChain
   402  
   403  		mockPeer := NewMockPeer(mockCtrl)
   404  		mockPeer.EXPECT().AsyncSendNewBlockHash(block).Times(1)
   405  
   406  		mockPeers := NewMockPeerSet(mockCtrl)
   407  		mockPeers.EXPECT().PeersWithoutBlock(block.Hash()).Return([]Peer{mockPeer}).Times(1)
   408  		pm.peers = mockPeers
   409  
   410  		pm.BroadcastBlockHash(block)
   411  	}
   412  }
   413  
   414  func TestProtocolManager_txBroadcastLoop_FromCN_CN_NotExists(t *testing.T) {
   415  	pm := &ProtocolManager{}
   416  	pm.nodetype = common.CONSENSUSNODE
   417  	mockCtrl := gomock.NewController(t)
   418  	defer mockCtrl.Finish()
   419  
   420  	txsCh := make(chan blockchain.NewTxsEvent, txChanSize)
   421  	pm.txsCh = txsCh
   422  
   423  	feed := &event.Feed{}
   424  	pm.txsSub = feed.Subscribe(txsCh)
   425  
   426  	peers := newPeerSet()
   427  	pm.peers = peers
   428  	cnPeer, pnPeer, enPeer := createAndRegisterPeers(mockCtrl, peers)
   429  
   430  	// Using gomock.Eq(txs) for AsyncSendTransactions calls,
   431  	// since transactions are put into a new list inside broadcastCNTx.
   432  	cnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(true).Times(1)
   433  	cnPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(0)
   434  	pnPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(0)
   435  	enPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(0)
   436  
   437  	go pm.txBroadcastLoop()
   438  
   439  	txsCh <- blockchain.NewTxsEvent{Txs: txs}
   440  
   441  	time.Sleep(500 * time.Millisecond)
   442  
   443  	pm.txsSub.Unsubscribe()
   444  }
   445  
   446  func TestBroadcastTxsFromCN_CN_NotExists(t *testing.T) {
   447  	pm := &ProtocolManager{}
   448  	pm.nodetype = common.CONSENSUSNODE
   449  	mockCtrl := gomock.NewController(t)
   450  	defer mockCtrl.Finish()
   451  
   452  	peers := newPeerSet()
   453  	pm.peers = peers
   454  	cnPeer, pnPeer, enPeer := createAndRegisterPeers(mockCtrl, peers)
   455  
   456  	// Using gomock.Eq(txs) for AsyncSendTransactions calls,
   457  	// since transactions are put into a new list inside broadcastCNTx.
   458  	cnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(true).Times(1)
   459  	cnPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(0)
   460  	pnPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(0)
   461  	enPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(0)
   462  
   463  	pm.BroadcastTxs(txs)
   464  }
   465  
   466  func TestBroadcastTxsFromCN_CN_Exists(t *testing.T) {
   467  	pm := &ProtocolManager{}
   468  	pm.nodetype = common.CONSENSUSNODE
   469  	mockCtrl := gomock.NewController(t)
   470  	defer mockCtrl.Finish()
   471  
   472  	peers := newPeerSet()
   473  	pm.peers = peers
   474  	cnPeer, pnPeer, enPeer := createAndRegisterPeers(mockCtrl, peers)
   475  
   476  	// Using gomock.Eq(txs) for AsyncSendTransactions calls,
   477  	// since transactions are put into a new list inside broadcastCNTx.
   478  	cnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(false).Times(1)
   479  	cnPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(1)
   480  	pnPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(0)
   481  	enPeer.EXPECT().AsyncSendTransactions(gomock.Eq(txs)).Times(0)
   482  
   483  	pm.BroadcastTxs(txs)
   484  }
   485  
   486  func TestBroadcastTxsFromPN_PN_NotExists(t *testing.T) {
   487  	pm := &ProtocolManager{}
   488  	pm.nodetype = common.PROXYNODE
   489  	mockCtrl := gomock.NewController(t)
   490  	defer mockCtrl.Finish()
   491  
   492  	peers := newPeerSet()
   493  	pm.peers = peers
   494  	cnPeer, pnPeer, enPeer := createAndRegisterPeers(mockCtrl, peers)
   495  
   496  	cnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(false).Times(1)
   497  
   498  	cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).Times(1)
   499  	pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).Times(1)
   500  	enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).Times(1)
   501  
   502  	pnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(true).Times(1)
   503  
   504  	cnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   505  	pnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(0)
   506  	enPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(0)
   507  
   508  	pm.BroadcastTxs(txs)
   509  }
   510  
   511  func TestBroadcastTxsFromPN_PN_Exists(t *testing.T) {
   512  	pm := &ProtocolManager{}
   513  	pm.nodetype = common.PROXYNODE
   514  	mockCtrl := gomock.NewController(t)
   515  	defer mockCtrl.Finish()
   516  
   517  	peers := newPeerSet()
   518  	pm.peers = peers
   519  	cnPeer, pnPeer, enPeer := createAndRegisterPeers(mockCtrl, peers)
   520  
   521  	cnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(false).Times(1)
   522  
   523  	cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).Times(1)
   524  	pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).Times(1)
   525  	enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).Times(1)
   526  
   527  	pnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(false).Times(1)
   528  
   529  	cnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   530  	pnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   531  	enPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(0)
   532  
   533  	pm.BroadcastTxs(txs)
   534  }
   535  
   536  func TestBroadcastTxsFromEN_ALL_NotExists(t *testing.T) {
   537  	pm := &ProtocolManager{}
   538  	pm.nodetype = common.ENDPOINTNODE
   539  	mockCtrl := gomock.NewController(t)
   540  	defer mockCtrl.Finish()
   541  
   542  	peers := newPeerSet()
   543  	pm.peers = peers
   544  	cnPeer, pnPeer, enPeer := createAndRegisterPeers(mockCtrl, peers)
   545  
   546  	cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   547  	pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   548  	enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   549  
   550  	cnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(true).Times(1)
   551  	pnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(true).Times(1)
   552  	enPeer.EXPECT().KnowsTx(tx1.Hash()).Return(true).Times(1)
   553  
   554  	cnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(0)
   555  	pnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(0)
   556  	enPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(0)
   557  
   558  	pm.BroadcastTxs(txs)
   559  }
   560  
   561  func TestBroadcastTxsFromEN_ALL_Exists(t *testing.T) {
   562  	pm := &ProtocolManager{}
   563  	pm.nodetype = common.ENDPOINTNODE
   564  	mockCtrl := gomock.NewController(t)
   565  	defer mockCtrl.Finish()
   566  
   567  	peers := newPeerSet()
   568  	pm.peers = peers
   569  	cnPeer, pnPeer, enPeer := createAndRegisterPeers(mockCtrl, peers)
   570  
   571  	cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   572  	pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   573  	enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   574  
   575  	cnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(false).Times(1)
   576  	pnPeer.EXPECT().KnowsTx(tx1.Hash()).Return(false).Times(1)
   577  	enPeer.EXPECT().KnowsTx(tx1.Hash()).Return(false).Times(1)
   578  
   579  	cnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   580  	pnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   581  	enPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   582  
   583  	pm.BroadcastTxs(txs)
   584  }
   585  
   586  func TestBroadcastTxsFrom_DefaultCase(t *testing.T) {
   587  	pm := &ProtocolManager{}
   588  	pm.nodetype = common.BOOTNODE
   589  	mockCtrl := gomock.NewController(t)
   590  	defer mockCtrl.Finish()
   591  
   592  	peers := newPeerSet()
   593  	pm.peers = peers
   594  	createAndRegisterPeers(mockCtrl, peers)
   595  
   596  	// There are no expected calls for the mocks.
   597  	pm.nodetype = common.BOOTNODE
   598  	pm.BroadcastTxs(txs)
   599  
   600  	pm.nodetype = common.UNKNOWNNODE
   601  	pm.BroadcastTxs(txs)
   602  }
   603  
   604  func TestProtocolManager_txResendLoop(t *testing.T) {
   605  	pm := &ProtocolManager{}
   606  	pm.nodetype = common.CONSENSUSNODE
   607  	mockCtrl := gomock.NewController(t)
   608  	defer mockCtrl.Finish()
   609  
   610  	peers := newPeerSet()
   611  	pm.peers = peers
   612  	createAndRegisterPeers(mockCtrl, peers)
   613  
   614  	pm.quitResendCh = make(chan struct{})
   615  
   616  	maxTxCount := 100
   617  	mockTxPool := workmocks.NewMockTxPool(mockCtrl)
   618  	mockTxPool.EXPECT().CachedPendingTxsByCount(maxTxCount).Return(txs).Times(1)
   619  
   620  	pm.txpool = mockTxPool
   621  
   622  	go pm.txResendLoop(1, maxTxCount)
   623  
   624  	time.Sleep(1500 * time.Millisecond)
   625  
   626  	pm.quitResendCh <- struct{}{}
   627  }
   628  
   629  func TestProtocolManager_txResend(t *testing.T) {
   630  	pm := &ProtocolManager{}
   631  	pm.nodetype = common.CONSENSUSNODE
   632  	mockCtrl := gomock.NewController(t)
   633  	defer mockCtrl.Finish()
   634  
   635  	peers := newPeerSet()
   636  	pm.peers = peers
   637  	createAndRegisterPeers(mockCtrl, peers)
   638  
   639  	pm.txResend(txs)
   640  }
   641  
   642  func TestReBroadcastTxs_CN(t *testing.T) {
   643  	pm := &ProtocolManager{}
   644  	pm.nodetype = common.CONSENSUSNODE
   645  	mockCtrl := gomock.NewController(t)
   646  	defer mockCtrl.Finish()
   647  
   648  	peers := newPeerSet()
   649  	pm.peers = peers
   650  	createAndRegisterPeers(mockCtrl, peers)
   651  
   652  	pm.ReBroadcastTxs(txs)
   653  }
   654  
   655  func TestReBroadcastTxs_PN(t *testing.T) {
   656  	// CN Peer=0, PN Peer=1
   657  	{
   658  		pm := &ProtocolManager{}
   659  		pm.nodetype = common.PROXYNODE
   660  		mockCtrl := gomock.NewController(t)
   661  
   662  		peers := newPeerSet()
   663  		pm.peers = peers
   664  
   665  		enPeer := NewMockPeer(mockCtrl)
   666  		enPeer.EXPECT().ConnType().Return(common.PROXYNODE).Times(2)
   667  		enPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   668  
   669  		peers.enpeers[addrs[2]] = enPeer
   670  		peers.peers[fmt.Sprintf("%x", nodeids[2][:8])] = enPeer
   671  
   672  		pm.ReBroadcastTxs(txs)
   673  
   674  		mockCtrl.Finish()
   675  	}
   676  	// CN Peer=1, PN Peer=0
   677  	{
   678  		pm := &ProtocolManager{}
   679  		pm.nodetype = common.PROXYNODE
   680  		mockCtrl := gomock.NewController(t)
   681  
   682  		peers := newPeerSet()
   683  		pm.peers = peers
   684  
   685  		pnPeer := NewMockPeer(mockCtrl)
   686  		pnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).Times(1)
   687  		pnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   688  
   689  		peers.pnpeers[addrs[2]] = pnPeer
   690  		peers.peers[fmt.Sprintf("%x", nodeids[2][:8])] = pnPeer
   691  
   692  		pm.ReBroadcastTxs(txs)
   693  
   694  		mockCtrl.Finish()
   695  	}
   696  }
   697  
   698  func TestReBroadcastTxs_EN(t *testing.T) {
   699  	// PN Peer=0, EN Peer=1
   700  	{
   701  		pm := &ProtocolManager{}
   702  		pm.nodetype = common.ENDPOINTNODE
   703  		mockCtrl := gomock.NewController(t)
   704  
   705  		peers := newPeerSet()
   706  		pm.peers = peers
   707  
   708  		enPeer := NewMockPeer(mockCtrl)
   709  		enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).Times(3)
   710  		enPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   711  
   712  		peers.enpeers[addrs[2]] = enPeer
   713  		peers.peers[fmt.Sprintf("%x", nodeids[2][:8])] = enPeer
   714  
   715  		pm.ReBroadcastTxs(txs)
   716  
   717  		mockCtrl.Finish()
   718  	}
   719  	// PN Peer=1, EN Peer=0
   720  	{
   721  		pm := &ProtocolManager{}
   722  		pm.nodetype = common.ENDPOINTNODE
   723  		mockCtrl := gomock.NewController(t)
   724  
   725  		peers := newPeerSet()
   726  		pm.peers = peers
   727  
   728  		pnPeer := NewMockPeer(mockCtrl)
   729  		pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).Times(3)
   730  		pnPeer.EXPECT().SendTransactions(gomock.Eq(txs)).Times(1)
   731  
   732  		peers.pnpeers[addrs[2]] = pnPeer
   733  		peers.peers[fmt.Sprintf("%x", nodeids[2][:8])] = pnPeer
   734  
   735  		pm.ReBroadcastTxs(txs)
   736  
   737  		mockCtrl.Finish()
   738  	}
   739  }
   740  
   741  func TestUseTxResend(t *testing.T) {
   742  	testSet := [...]struct {
   743  		pm     *ProtocolManager
   744  		result bool
   745  	}{
   746  		{&ProtocolManager{nodetype: common.CONSENSUSNODE, txResendUseLegacy: true}, false},
   747  		{&ProtocolManager{nodetype: common.ENDPOINTNODE, txResendUseLegacy: true}, false},
   748  		{&ProtocolManager{nodetype: common.PROXYNODE, txResendUseLegacy: true}, false},
   749  		{&ProtocolManager{nodetype: common.BOOTNODE, txResendUseLegacy: true}, false},
   750  		{&ProtocolManager{nodetype: common.UNKNOWNNODE, txResendUseLegacy: true}, false},
   751  
   752  		{&ProtocolManager{nodetype: common.CONSENSUSNODE, txResendUseLegacy: false}, false},
   753  		{&ProtocolManager{nodetype: common.ENDPOINTNODE, txResendUseLegacy: false}, true},
   754  		{&ProtocolManager{nodetype: common.PROXYNODE, txResendUseLegacy: false}, true},
   755  		{&ProtocolManager{nodetype: common.BOOTNODE, txResendUseLegacy: false}, true},
   756  		{&ProtocolManager{nodetype: common.UNKNOWNNODE, txResendUseLegacy: false}, true},
   757  	}
   758  
   759  	for _, tc := range testSet {
   760  		assert.Equal(t, tc.result, tc.pm.useTxResend())
   761  	}
   762  }
   763  
   764  func TestNodeInfo(t *testing.T) {
   765  	pm := &ProtocolManager{}
   766  	pm.nodetype = common.ENDPOINTNODE
   767  	mockCtrl := gomock.NewController(t)
   768  	defer mockCtrl.Finish()
   769  
   770  	mockBlockChain := workmocks.NewMockBlockChain(mockCtrl)
   771  	pm.blockchain = mockBlockChain
   772  
   773  	genesis := newBlock(0)
   774  	block := newBlock(blockNum1)
   775  	config := &params.ChainConfig{ChainID: td1}
   776  
   777  	pm.networkId = 1234
   778  	mockBlockChain.EXPECT().CurrentBlock().Return(block).Times(1)
   779  	mockBlockChain.EXPECT().GetTd(block.Hash(), block.NumberU64()).Return(td1).Times(1)
   780  	mockBlockChain.EXPECT().Genesis().Return(genesis).Times(1)
   781  	mockBlockChain.EXPECT().Config().Return(config).Times(1)
   782  
   783  	expected := &NodeInfo{
   784  		Network:    pm.networkId,
   785  		BlockScore: td1,
   786  		Genesis:    genesis.Hash(),
   787  		Config:     config,
   788  		Head:       block.Hash(),
   789  	}
   790  
   791  	assert.Equal(t, *expected, *pm.NodeInfo())
   792  }
   793  
   794  func TestGetCNPeersAndGetENPeers(t *testing.T) {
   795  	pm := &ProtocolManager{}
   796  	pm.nodetype = common.ENDPOINTNODE
   797  	mockCtrl := gomock.NewController(t)
   798  	defer mockCtrl.Finish()
   799  
   800  	peers := newPeerSet()
   801  	pm.peers = peers
   802  
   803  	cnPeer := NewMockPeer(mockCtrl)
   804  	pnPeer := NewMockPeer(mockCtrl)
   805  	enPeer := NewMockPeer(mockCtrl)
   806  
   807  	peers.cnpeers[addrs[0]] = cnPeer
   808  	peers.pnpeers[addrs[1]] = pnPeer
   809  	peers.enpeers[addrs[2]] = enPeer
   810  
   811  	cnPeers := pm.GetCNPeers()
   812  	enPeers := pm.GetENPeers()
   813  
   814  	assert.Equal(t, 1, len(cnPeers))
   815  	assert.Equal(t, 1, len(enPeers))
   816  
   817  	assert.Equal(t, cnPeer, cnPeers[addrs[0]])
   818  	assert.Equal(t, enPeer, enPeers[addrs[2]])
   819  }
   820  
   821  func TestFindPeers_AddrExists(t *testing.T) {
   822  	pm := &ProtocolManager{}
   823  	pm.nodetype = common.ENDPOINTNODE
   824  	mockCtrl := gomock.NewController(t)
   825  	defer mockCtrl.Finish()
   826  
   827  	peers := NewMockPeerSet(mockCtrl)
   828  	pm.peers = peers
   829  
   830  	cnPeer := NewMockPeer(mockCtrl)
   831  	pnPeer := NewMockPeer(mockCtrl)
   832  	enPeer := NewMockPeer(mockCtrl)
   833  
   834  	peersResult := map[string]Peer{"cnPeer": cnPeer, "pnPeer": pnPeer, "enPeer": enPeer}
   835  
   836  	peers.EXPECT().Peers().Return(peersResult).Times(1)
   837  	cnPeer.EXPECT().GetAddr().Return(addrs[0]).Times(1)
   838  	pnPeer.EXPECT().GetAddr().Return(addrs[1]).Times(1)
   839  	enPeer.EXPECT().GetAddr().Return(addrs[2]).Times(1)
   840  
   841  	targets := make(map[common.Address]bool)
   842  	targets[addrs[0]] = true
   843  	targets[addrs[1]] = true
   844  	targets[addrs[2]] = false
   845  
   846  	foundPeers := pm.FindPeers(targets)
   847  
   848  	assert.Equal(t, 2, len(foundPeers))
   849  	assert.EqualValues(t, cnPeer, foundPeers[addrs[0]])
   850  	assert.EqualValues(t, pnPeer, foundPeers[addrs[1]])
   851  	assert.Nil(t, foundPeers[addrs[2]])
   852  }
   853  
   854  func TestFindPeers_AddrNotExists(t *testing.T) {
   855  	pm := &ProtocolManager{}
   856  	pm.nodetype = common.ENDPOINTNODE
   857  	mockCtrl := gomock.NewController(t)
   858  	defer mockCtrl.Finish()
   859  
   860  	peers := NewMockPeerSet(mockCtrl)
   861  	pm.peers = peers
   862  
   863  	cnPeer := NewMockPeer(mockCtrl)
   864  	pnPeer := NewMockPeer(mockCtrl)
   865  	enPeer := NewMockPeer(mockCtrl)
   866  
   867  	peersResult := map[string]Peer{"cnPeer": cnPeer, "pnPeer": pnPeer, "enPeer": enPeer}
   868  
   869  	peers.EXPECT().Peers().Return(peersResult).Times(1)
   870  	cnPeer.EXPECT().GetAddr().Return(common.Address{}).Times(1)
   871  	pnPeer.EXPECT().GetAddr().Return(common.Address{}).Times(1)
   872  	enPeer.EXPECT().GetAddr().Return(common.Address{}).Times(1)
   873  
   874  	cnPeer.EXPECT().GetP2PPeerID().Return(nodeids[0]).Times(1)
   875  	pnPeer.EXPECT().GetP2PPeerID().Return(nodeids[1]).Times(1)
   876  	enPeer.EXPECT().GetP2PPeerID().Return(nodeids[2]).Times(1)
   877  
   878  	cnPeer.EXPECT().SetAddr(addrs[0]).Times(1)
   879  	pnPeer.EXPECT().SetAddr(addrs[1]).Times(1)
   880  	enPeer.EXPECT().SetAddr(addrs[2]).Times(1)
   881  
   882  	targets := make(map[common.Address]bool)
   883  	targets[addrs[0]] = true
   884  	targets[addrs[1]] = true
   885  	targets[addrs[2]] = false
   886  
   887  	foundPeers := pm.FindPeers(targets)
   888  
   889  	assert.Equal(t, 2, len(foundPeers))
   890  	assert.EqualValues(t, cnPeer, foundPeers[addrs[0]])
   891  	assert.EqualValues(t, pnPeer, foundPeers[addrs[1]])
   892  	assert.Nil(t, foundPeers[addrs[2]])
   893  }
   894  
   895  func TestFindCNPeers(t *testing.T) {
   896  	pm := &ProtocolManager{}
   897  	pm.nodetype = common.ENDPOINTNODE
   898  	mockCtrl := gomock.NewController(t)
   899  	defer mockCtrl.Finish()
   900  
   901  	peers := newPeerSet()
   902  	pm.peers = peers
   903  
   904  	cnPeer1 := NewMockPeer(mockCtrl)
   905  	cnPeer2 := NewMockPeer(mockCtrl)
   906  	cnPeer3 := NewMockPeer(mockCtrl)
   907  
   908  	peers.cnpeers[addrs[0]] = cnPeer1
   909  	peers.cnpeers[addrs[1]] = cnPeer2
   910  	peers.cnpeers[addrs[2]] = cnPeer3
   911  
   912  	targets := make(map[common.Address]bool)
   913  	targets[addrs[0]] = true
   914  	targets[addrs[1]] = true
   915  	targets[addrs[2]] = false
   916  
   917  	foundCNPeers := pm.FindCNPeers(targets)
   918  
   919  	assert.Equal(t, 2, len(foundCNPeers))
   920  	assert.EqualValues(t, cnPeer1, foundCNPeers[addrs[0]])
   921  	assert.EqualValues(t, cnPeer2, foundCNPeers[addrs[1]])
   922  	assert.Nil(t, foundCNPeers[addrs[2]])
   923  }
   924  
   925  func TestGetPeers_AddrExists(t *testing.T) {
   926  	pm := &ProtocolManager{}
   927  	pm.nodetype = common.ENDPOINTNODE
   928  	mockCtrl := gomock.NewController(t)
   929  	defer mockCtrl.Finish()
   930  
   931  	peers := NewMockPeerSet(mockCtrl)
   932  	pm.peers = peers
   933  
   934  	cnPeer := NewMockPeer(mockCtrl)
   935  	pnPeer := NewMockPeer(mockCtrl)
   936  	enPeer := NewMockPeer(mockCtrl)
   937  
   938  	peersResult := map[string]Peer{"cnPeer": cnPeer, "pnPeer": pnPeer, "enPeer": enPeer}
   939  
   940  	peers.EXPECT().Peers().Return(peersResult).Times(1)
   941  	cnPeer.EXPECT().GetAddr().Return(addrs[0]).Times(1)
   942  	pnPeer.EXPECT().GetAddr().Return(addrs[1]).Times(1)
   943  	enPeer.EXPECT().GetAddr().Return(addrs[2]).Times(1)
   944  
   945  	foundAddrs := pm.GetPeers()
   946  
   947  	assert.Equal(t, 3, len(foundAddrs))
   948  	assert.True(t, contains(foundAddrs, addrs[0]))
   949  	assert.True(t, contains(foundAddrs, addrs[1]))
   950  	assert.True(t, contains(foundAddrs, addrs[2]))
   951  }
   952  
   953  func TestGetPeers_AddrNotExists(t *testing.T) {
   954  	pm := &ProtocolManager{}
   955  	pm.nodetype = common.ENDPOINTNODE
   956  	mockCtrl := gomock.NewController(t)
   957  	defer mockCtrl.Finish()
   958  
   959  	peers := NewMockPeerSet(mockCtrl)
   960  	pm.peers = peers
   961  
   962  	cnPeer := NewMockPeer(mockCtrl)
   963  	pnPeer := NewMockPeer(mockCtrl)
   964  	enPeer := NewMockPeer(mockCtrl)
   965  
   966  	peersResult := map[string]Peer{"cnPeer": cnPeer, "pnPeer": pnPeer, "enPeer": enPeer}
   967  
   968  	peers.EXPECT().Peers().Return(peersResult).Times(1)
   969  	cnPeer.EXPECT().GetAddr().Return(common.Address{}).Times(1)
   970  	pnPeer.EXPECT().GetAddr().Return(common.Address{}).Times(1)
   971  	enPeer.EXPECT().GetAddr().Return(common.Address{}).Times(1)
   972  
   973  	cnPeer.EXPECT().GetP2PPeerID().Return(nodeids[0]).Times(1)
   974  	pnPeer.EXPECT().GetP2PPeerID().Return(nodeids[1]).Times(1)
   975  	enPeer.EXPECT().GetP2PPeerID().Return(nodeids[2]).Times(1)
   976  
   977  	cnPeer.EXPECT().SetAddr(addrs[0]).Times(1)
   978  	pnPeer.EXPECT().SetAddr(addrs[1]).Times(1)
   979  	enPeer.EXPECT().SetAddr(addrs[2]).Times(1)
   980  
   981  	foundAddrs := pm.GetPeers()
   982  
   983  	assert.Equal(t, 3, len(foundAddrs))
   984  	assert.True(t, contains(foundAddrs, addrs[0]))
   985  	assert.True(t, contains(foundAddrs, addrs[1]))
   986  	assert.True(t, contains(foundAddrs, addrs[2]))
   987  }
   988  
   989  func TestEnqueue(t *testing.T) {
   990  	pm := &ProtocolManager{}
   991  	mockCtrl := gomock.NewController(t)
   992  	defer mockCtrl.Finish()
   993  
   994  	fetcherMock := mocks.NewMockProtocolManagerFetcher(mockCtrl)
   995  	pm.fetcher = fetcherMock
   996  
   997  	block := newBlock(blockNum1)
   998  	id := nodeids[0].String()
   999  
  1000  	fetcherMock.EXPECT().Enqueue(id, block).Times(1)
  1001  	pm.Enqueue(id, block)
  1002  }
  1003  
  1004  func TestProtocolManager_Downloader(t *testing.T) {
  1005  	pm := &ProtocolManager{}
  1006  	assert.Nil(t, pm.Downloader())
  1007  
  1008  	downloader := &downloader.Downloader{}
  1009  	pm.downloader = downloader
  1010  
  1011  	assert.Equal(t, downloader, pm.Downloader())
  1012  }
  1013  
  1014  func TestProtocolManager_SetWsEndPoint(t *testing.T) {
  1015  	pm := &ProtocolManager{}
  1016  	assert.Equal(t, "", pm.wsendpoint)
  1017  
  1018  	wsep := "wsep"
  1019  	pm.SetWsEndPoint(wsep)
  1020  	assert.Equal(t, wsep, pm.wsendpoint)
  1021  }
  1022  
  1023  func TestBroadcastTxsSortedByTime(t *testing.T) {
  1024  	// Generate a batch of accounts to start with
  1025  	keys := make([]*ecdsa.PrivateKey, 5)
  1026  	for i := 0; i < len(keys); i++ {
  1027  		keys[i], _ = crypto.GenerateKey()
  1028  	}
  1029  	signer := types.LatestSignerForChainID(big.NewInt(1))
  1030  
  1031  	// Generate a batch of transactions.
  1032  	txs := types.Transactions{}
  1033  	for _, key := range keys {
  1034  		tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100, big.NewInt(1), nil), signer, key)
  1035  
  1036  		txs = append(txs, tx)
  1037  	}
  1038  
  1039  	// Shuffle transactions.
  1040  	rand.Seed(time.Now().Unix())
  1041  	rand.Shuffle(len(txs), func(i, j int) {
  1042  		txs[i], txs[j] = txs[j], txs[i]
  1043  	})
  1044  
  1045  	sortedTxs := make(types.Transactions, len(txs))
  1046  	copy(sortedTxs, txs)
  1047  
  1048  	// Sort transaction by time.
  1049  	sort.Sort(types.TxByTime(sortedTxs))
  1050  
  1051  	pm := &ProtocolManager{}
  1052  	pm.nodetype = common.ENDPOINTNODE
  1053  
  1054  	peers := newPeerSet()
  1055  	basePeer, _, oppositePipe := newBasePeer()
  1056  
  1057  	pm.peers = peers
  1058  	pm.peers.Register(basePeer, nil)
  1059  
  1060  	go func(t *testing.T) {
  1061  		pm.BroadcastTxs(txs)
  1062  	}(t)
  1063  
  1064  	receivedMsg, err := oppositePipe.ReadMsg()
  1065  	if err != nil {
  1066  		t.Fatal(err)
  1067  	}
  1068  
  1069  	var receivedTxs types.Transactions
  1070  	if err := receivedMsg.Decode(&receivedTxs); err != nil {
  1071  		t.Fatal(err)
  1072  	}
  1073  
  1074  	assert.Equal(t, len(txs), len(receivedTxs))
  1075  
  1076  	// It should be received transaction with sorted by times.
  1077  	for i, tx := range receivedTxs {
  1078  		assert.True(t, basePeer.KnowsTx(tx.Hash()))
  1079  		assert.Equal(t, sortedTxs[i].Hash(), tx.Hash())
  1080  		assert.False(t, sortedTxs[i].Time().Equal(tx.Time()))
  1081  	}
  1082  }
  1083  
  1084  func TestReBroadcastTxsSortedByTime(t *testing.T) {
  1085  	// Generate a batch of accounts to start with
  1086  	keys := make([]*ecdsa.PrivateKey, 5)
  1087  	for i := 0; i < len(keys); i++ {
  1088  		keys[i], _ = crypto.GenerateKey()
  1089  	}
  1090  	signer := types.LatestSignerForChainID(big.NewInt(1))
  1091  
  1092  	// Generate a batch of transactions.
  1093  	txs := types.Transactions{}
  1094  	for _, key := range keys {
  1095  		tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100, big.NewInt(1), nil), signer, key)
  1096  
  1097  		txs = append(txs, tx)
  1098  	}
  1099  
  1100  	// Shuffle transactions.
  1101  	rand.Seed(time.Now().Unix())
  1102  	rand.Shuffle(len(txs), func(i, j int) {
  1103  		txs[i], txs[j] = txs[j], txs[i]
  1104  	})
  1105  
  1106  	sortedTxs := make(types.Transactions, len(txs))
  1107  	copy(sortedTxs, txs)
  1108  
  1109  	// Sort transaction by time.
  1110  	sort.Sort(types.TxByTime(sortedTxs))
  1111  
  1112  	pm := &ProtocolManager{}
  1113  	pm.nodetype = common.ENDPOINTNODE
  1114  
  1115  	peers := newPeerSet()
  1116  	basePeer, _, oppositePipe := newBasePeer()
  1117  
  1118  	pm.peers = peers
  1119  	pm.peers.Register(basePeer, nil)
  1120  
  1121  	go func(t *testing.T) {
  1122  		pm.ReBroadcastTxs(txs)
  1123  	}(t)
  1124  
  1125  	receivedMsg, err := oppositePipe.ReadMsg()
  1126  	if err != nil {
  1127  		t.Fatal(err)
  1128  	}
  1129  
  1130  	var receivedTxs types.Transactions
  1131  	if err := receivedMsg.Decode(&receivedTxs); err != nil {
  1132  		t.Fatal(err)
  1133  	}
  1134  
  1135  	assert.Equal(t, len(txs), len(receivedTxs))
  1136  
  1137  	// It should be received transaction with sorted by times.
  1138  	for i, tx := range receivedTxs {
  1139  		assert.Equal(t, sortedTxs[i].Hash(), tx.Hash())
  1140  		assert.False(t, sortedTxs[i].Time().Equal(tx.Time()))
  1141  	}
  1142  }
  1143  
  1144  func contains(addrs []common.Address, item common.Address) bool {
  1145  	for _, a := range addrs {
  1146  		if a == item {
  1147  			return true
  1148  		}
  1149  	}
  1150  	return false
  1151  }
  1152  
  1153  func createAndRegisterPeers(mockCtrl *gomock.Controller, peers *peerSet) (*MockPeer, *MockPeer, *MockPeer) {
  1154  	cnPeer := NewMockPeer(mockCtrl)
  1155  	pnPeer := NewMockPeer(mockCtrl)
  1156  	enPeer := NewMockPeer(mockCtrl)
  1157  
  1158  	peers.cnpeers[addrs[0]] = cnPeer
  1159  	peers.pnpeers[addrs[1]] = pnPeer
  1160  	peers.enpeers[addrs[2]] = enPeer
  1161  
  1162  	peers.peers[fmt.Sprintf("%x", nodeids[0][:8])] = cnPeer
  1163  	peers.peers[fmt.Sprintf("%x", nodeids[1][:8])] = pnPeer
  1164  	peers.peers[fmt.Sprintf("%x", nodeids[2][:8])] = enPeer
  1165  
  1166  	return cnPeer, pnPeer, enPeer
  1167  }