github.com/klaytn/klaytn@v1.12.1/node/cn/peer_set_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  	"math/big"
    21  	"testing"
    22  
    23  	"github.com/golang/mock/gomock"
    24  	"github.com/klaytn/klaytn/blockchain/types"
    25  	"github.com/klaytn/klaytn/common"
    26  	"github.com/klaytn/klaytn/networks/p2p"
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  func setMockPeers(mockPeers []*MockPeer) {
    31  	for i, mp := range mockPeers {
    32  		mp.EXPECT().GetAddr().Return(addrs[i]).AnyTimes()
    33  		mp.EXPECT().GetID().Return(nodeids[i].String()).AnyTimes()
    34  		mp.EXPECT().Broadcast().AnyTimes()
    35  	}
    36  }
    37  
    38  func setMockPeersConnType(cnPeer, pnPeer, enPeer *MockPeer) {
    39  	cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
    40  	pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
    41  	enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
    42  }
    43  
    44  func TestPeerSet_Register(t *testing.T) {
    45  	peerSet := newPeerSet()
    46  	mockCtrl := gomock.NewController(t)
    47  	defer mockCtrl.Finish()
    48  
    49  	cnPeer := NewMockPeer(mockCtrl)
    50  	pnPeer := NewMockPeer(mockCtrl)
    51  	enPeer := NewMockPeer(mockCtrl)
    52  
    53  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
    54  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
    55  
    56  	assert.NoError(t, peerSet.Register(cnPeer, nil))
    57  	assert.NoError(t, peerSet.Register(pnPeer, nil))
    58  	assert.NoError(t, peerSet.Register(enPeer, nil))
    59  	assert.Equal(t, 3, len(peerSet.peers))
    60  
    61  	assert.Equal(t, errAlreadyRegistered, peerSet.Register(cnPeer, nil))
    62  	assert.Equal(t, errAlreadyRegistered, peerSet.Register(pnPeer, nil))
    63  	assert.Equal(t, errAlreadyRegistered, peerSet.Register(enPeer, nil))
    64  	assert.Equal(t, 3, len(peerSet.peers))
    65  
    66  	peerSet.closed = true
    67  	assert.Equal(t, errClosed, peerSet.Register(cnPeer, nil))
    68  	assert.Equal(t, errClosed, peerSet.Register(pnPeer, nil))
    69  	assert.Equal(t, errClosed, peerSet.Register(enPeer, nil))
    70  }
    71  
    72  func TestPeerSet_Unregister(t *testing.T) {
    73  	peerSet := newPeerSet()
    74  	mockCtrl := gomock.NewController(t)
    75  	defer mockCtrl.Finish()
    76  
    77  	cnPeer := NewMockPeer(mockCtrl)
    78  	pnPeer := NewMockPeer(mockCtrl)
    79  	enPeer := NewMockPeer(mockCtrl)
    80  
    81  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
    82  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
    83  
    84  	cnPeer.EXPECT().Close().Times(1)
    85  	cnPeer.EXPECT().ExistSnapExtension().Return(false).Times(1)
    86  	pnPeer.EXPECT().Close().Times(1)
    87  	pnPeer.EXPECT().ExistSnapExtension().Return(false).Times(1)
    88  	enPeer.EXPECT().Close().Times(1)
    89  	enPeer.EXPECT().ExistSnapExtension().Return(false).Times(1)
    90  
    91  	assert.Equal(t, errNotRegistered, peerSet.Unregister(nodeids[0].String()))
    92  	assert.Equal(t, errNotRegistered, peerSet.Unregister(nodeids[1].String()))
    93  	assert.Equal(t, errNotRegistered, peerSet.Unregister(nodeids[2].String()))
    94  
    95  	assert.NoError(t, peerSet.Register(cnPeer, nil))
    96  	assert.NoError(t, peerSet.Register(pnPeer, nil))
    97  	assert.NoError(t, peerSet.Register(enPeer, nil))
    98  	assert.Equal(t, 3, len(peerSet.peers))
    99  
   100  	assert.NoError(t, peerSet.Unregister(nodeids[0].String()))
   101  	assert.NoError(t, peerSet.Unregister(nodeids[1].String()))
   102  	assert.NoError(t, peerSet.Unregister(nodeids[2].String()))
   103  	assert.Equal(t, 0, len(peerSet.peers))
   104  }
   105  
   106  func TestPeerSet_Peers(t *testing.T) {
   107  	peerSet := newPeerSet()
   108  	mockCtrl := gomock.NewController(t)
   109  	defer mockCtrl.Finish()
   110  
   111  	cnPeer := NewMockPeer(mockCtrl)
   112  	pnPeer := NewMockPeer(mockCtrl)
   113  	enPeer := NewMockPeer(mockCtrl)
   114  
   115  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
   116  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
   117  
   118  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   119  	assert.NoError(t, peerSet.Register(pnPeer, nil))
   120  	assert.NoError(t, peerSet.Register(enPeer, nil))
   121  
   122  	peers := peerSet.Peers()
   123  	expectedPeers := map[string]Peer{nodeids[0].String(): cnPeer, nodeids[1].String(): pnPeer, nodeids[2].String(): enPeer}
   124  	assert.EqualValues(t, expectedPeers, peers)
   125  }
   126  
   127  func TestPeerSet_CNPeers(t *testing.T) {
   128  	peerSet := newPeerSet()
   129  	mockCtrl := gomock.NewController(t)
   130  	defer mockCtrl.Finish()
   131  
   132  	cnPeer := NewMockPeer(mockCtrl)
   133  	cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).Times(1)
   134  	setMockPeers([]*MockPeer{cnPeer})
   135  
   136  	assert.EqualValues(t, map[common.Address]Peer{}, peerSet.CNPeers())
   137  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   138  	assert.EqualValues(t, map[common.Address]Peer{addrs[0]: cnPeer}, peerSet.CNPeers())
   139  }
   140  
   141  func TestPeerSet_PNPeers(t *testing.T) {
   142  	peerSet := newPeerSet()
   143  	mockCtrl := gomock.NewController(t)
   144  	defer mockCtrl.Finish()
   145  
   146  	pnPeer := NewMockPeer(mockCtrl)
   147  	pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).Times(1)
   148  	setMockPeers([]*MockPeer{pnPeer})
   149  
   150  	assert.EqualValues(t, map[common.Address]Peer{}, peerSet.PNPeers())
   151  	assert.NoError(t, peerSet.Register(pnPeer, nil))
   152  	assert.EqualValues(t, map[common.Address]Peer{addrs[0]: pnPeer}, peerSet.PNPeers())
   153  }
   154  
   155  func TestPeerSet_ENPeers(t *testing.T) {
   156  	peerSet := newPeerSet()
   157  	mockCtrl := gomock.NewController(t)
   158  	defer mockCtrl.Finish()
   159  
   160  	enPeer := NewMockPeer(mockCtrl)
   161  	enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).Times(1)
   162  	setMockPeers([]*MockPeer{enPeer})
   163  
   164  	assert.EqualValues(t, map[common.Address]Peer{}, peerSet.ENPeers())
   165  	assert.NoError(t, peerSet.Register(enPeer, nil))
   166  	assert.EqualValues(t, map[common.Address]Peer{addrs[0]: enPeer}, peerSet.ENPeers())
   167  }
   168  
   169  func TestPeerSet_Peer_And_Len(t *testing.T) {
   170  	peerSet := newPeerSet()
   171  	mockCtrl := gomock.NewController(t)
   172  	defer mockCtrl.Finish()
   173  
   174  	cnPeer := NewMockPeer(mockCtrl)
   175  	pnPeer := NewMockPeer(mockCtrl)
   176  	enPeer := NewMockPeer(mockCtrl)
   177  
   178  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
   179  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
   180  
   181  	assert.Equal(t, 0, peerSet.Len())
   182  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   183  	assert.Equal(t, 1, peerSet.Len())
   184  	assert.NoError(t, peerSet.Register(pnPeer, nil))
   185  	assert.Equal(t, 2, peerSet.Len())
   186  	assert.NoError(t, peerSet.Register(enPeer, nil))
   187  	assert.Equal(t, 3, peerSet.Len())
   188  
   189  	assert.Equal(t, cnPeer, peerSet.Peer(nodeids[0].String()))
   190  	assert.Equal(t, pnPeer, peerSet.Peer(nodeids[1].String()))
   191  	assert.Equal(t, enPeer, peerSet.Peer(nodeids[2].String()))
   192  }
   193  
   194  func TestPeerSet_PeersWithoutBlock(t *testing.T) {
   195  	peerSet := newPeerSet()
   196  	mockCtrl := gomock.NewController(t)
   197  	defer mockCtrl.Finish()
   198  
   199  	block := newBlock(blockNum1)
   200  
   201  	cnPeer := NewMockPeer(mockCtrl)
   202  	pnPeer := NewMockPeer(mockCtrl)
   203  	enPeer := NewMockPeer(mockCtrl)
   204  
   205  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
   206  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
   207  
   208  	cnPeer.EXPECT().KnowsBlock(block.Hash()).Return(false).AnyTimes()
   209  	pnPeer.EXPECT().KnowsBlock(block.Hash()).Return(true).AnyTimes()
   210  	enPeer.EXPECT().KnowsBlock(block.Hash()).Return(false).AnyTimes()
   211  
   212  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   213  	assert.NoError(t, peerSet.Register(pnPeer, nil))
   214  	assert.NoError(t, peerSet.Register(enPeer, nil))
   215  
   216  	peersWithoutBlock := peerSet.PeersWithoutBlock(block.Hash())
   217  	assert.Equal(t, 2, len(peersWithoutBlock))
   218  	assert.EqualValues(t, []Peer{cnPeer, enPeer}, peersWithoutBlock)
   219  
   220  	cnWithoutBlock := peerSet.CNWithoutBlock(block.Hash())
   221  	assert.Equal(t, 1, len(cnWithoutBlock))
   222  	assert.Equal(t, []Peer{cnPeer}, cnWithoutBlock)
   223  
   224  	pnWithoutBlock := peerSet.PNWithoutBlock(block.Hash())
   225  	assert.Equal(t, 0, len(pnWithoutBlock))
   226  	assert.Equal(t, []Peer{}, pnWithoutBlock)
   227  
   228  	enWithoutBlock := peerSet.ENWithoutBlock(block.Hash())
   229  	assert.Equal(t, 1, len(enWithoutBlock))
   230  	assert.Equal(t, []Peer{enPeer}, enWithoutBlock)
   231  }
   232  
   233  func TestPeerSet_PeersWithoutTx(t *testing.T) {
   234  	peerSet := newPeerSet()
   235  	mockCtrl := gomock.NewController(t)
   236  	defer mockCtrl.Finish()
   237  	tx := types.NewTransaction(111, addrs[0], big.NewInt(111), 111, big.NewInt(111), nil)
   238  
   239  	cnPeer := NewMockPeer(mockCtrl)
   240  	pnPeer := NewMockPeer(mockCtrl)
   241  	enPeer := NewMockPeer(mockCtrl)
   242  
   243  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
   244  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
   245  
   246  	cnPeer.EXPECT().KnowsTx(tx.Hash()).Return(false).AnyTimes()
   247  	pnPeer.EXPECT().KnowsTx(tx.Hash()).Return(true).AnyTimes()
   248  	enPeer.EXPECT().KnowsTx(tx.Hash()).Return(false).AnyTimes()
   249  
   250  	assert.EqualValues(t, []Peer{}, peerSet.PeersWithoutTx(tx.Hash()))
   251  
   252  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   253  	assert.NoError(t, peerSet.Register(pnPeer, nil))
   254  	assert.NoError(t, peerSet.Register(enPeer, nil))
   255  
   256  	peersWithoutTx := peerSet.PeersWithoutTx(tx.Hash())
   257  
   258  	assert.Equal(t, 2, len(peersWithoutTx))
   259  	assert.EqualValues(t, []Peer{cnPeer, enPeer}, peersWithoutTx)
   260  }
   261  
   262  func TestPeerSet_TypePeersWithoutTx(t *testing.T) {
   263  	peerSet := newPeerSet()
   264  	mockCtrl := gomock.NewController(t)
   265  	defer mockCtrl.Finish()
   266  	tx := types.NewTransaction(111, addrs[0], big.NewInt(111), 111, big.NewInt(111), nil)
   267  
   268  	cnPeer := NewMockPeer(mockCtrl)
   269  	pnPeer := NewMockPeer(mockCtrl)
   270  	enPeer := NewMockPeer(mockCtrl)
   271  
   272  	cnPeer.EXPECT().KnowsTx(tx.Hash()).Return(false).AnyTimes()
   273  	pnPeer.EXPECT().KnowsTx(tx.Hash()).Return(true).AnyTimes()
   274  	enPeer.EXPECT().KnowsTx(tx.Hash()).Return(false).AnyTimes()
   275  
   276  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
   277  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
   278  
   279  	assert.EqualValues(t, []Peer{}, peerSet.TypePeersWithoutTx(tx.Hash(), common.CONSENSUSNODE))
   280  	assert.EqualValues(t, []Peer{}, peerSet.TypePeersWithoutTx(tx.Hash(), common.PROXYNODE))
   281  	assert.EqualValues(t, []Peer{}, peerSet.TypePeersWithoutTx(tx.Hash(), common.ENDPOINTNODE))
   282  
   283  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   284  	assert.NoError(t, peerSet.Register(pnPeer, nil))
   285  	assert.NoError(t, peerSet.Register(enPeer, nil))
   286  
   287  	assert.EqualValues(t, []Peer{cnPeer}, peerSet.TypePeersWithoutTx(tx.Hash(), common.CONSENSUSNODE))
   288  	assert.EqualValues(t, []Peer{}, peerSet.TypePeersWithoutTx(tx.Hash(), common.PROXYNODE))
   289  	assert.EqualValues(t, []Peer{enPeer}, peerSet.TypePeersWithoutTx(tx.Hash(), common.ENDPOINTNODE))
   290  }
   291  
   292  func TestPeerSet_CNWithoutTx(t *testing.T) {
   293  	peerSet := newPeerSet()
   294  	mockCtrl := gomock.NewController(t)
   295  	defer mockCtrl.Finish()
   296  	tx := types.NewTransaction(111, addrs[0], big.NewInt(111), 111, big.NewInt(111), nil)
   297  
   298  	cnPeer := NewMockPeer(mockCtrl)
   299  	cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   300  	cnPeer.EXPECT().KnowsTx(tx.Hash()).Return(false).Times(1)
   301  	setMockPeers([]*MockPeer{cnPeer})
   302  
   303  	assert.EqualValues(t, []Peer{}, peerSet.CNWithoutTx(tx.Hash()))
   304  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   305  	assert.EqualValues(t, []Peer{cnPeer}, peerSet.CNWithoutTx(tx.Hash()))
   306  }
   307  
   308  func TestPeerSet_BestPeer(t *testing.T) {
   309  	peerSet := newPeerSet()
   310  	mockCtrl := gomock.NewController(t)
   311  	defer mockCtrl.Finish()
   312  
   313  	cnPeer := NewMockPeer(mockCtrl)
   314  	pnPeer := NewMockPeer(mockCtrl)
   315  	enPeer := NewMockPeer(mockCtrl)
   316  
   317  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
   318  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
   319  
   320  	cnPeer.EXPECT().Head().Return(common.Hash{}, big.NewInt(111)).Times(2)
   321  	pnPeer.EXPECT().Head().Return(common.Hash{}, big.NewInt(222)).Times(2)
   322  	enPeer.EXPECT().Head().Return(common.Hash{}, big.NewInt(333)).Times(1)
   323  	enPeer.EXPECT().ExistSnapExtension().Return(false).Times(1)
   324  	enPeer.EXPECT().Close().Times(1)
   325  
   326  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
   327  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
   328  
   329  	assert.Nil(t, peerSet.BestPeer())
   330  
   331  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   332  	assert.NoError(t, peerSet.Register(pnPeer, nil))
   333  	assert.NoError(t, peerSet.Register(enPeer, nil))
   334  
   335  	assert.Equal(t, enPeer, peerSet.BestPeer())
   336  
   337  	assert.NoError(t, peerSet.Unregister(nodeids[2].String()))
   338  
   339  	assert.Equal(t, pnPeer, peerSet.BestPeer())
   340  }
   341  
   342  func TestPeerSet_Close(t *testing.T) {
   343  	peerSet := newPeerSet()
   344  	mockCtrl := gomock.NewController(t)
   345  	defer mockCtrl.Finish()
   346  
   347  	cnPeer := NewMockPeer(mockCtrl)
   348  	pnPeer := NewMockPeer(mockCtrl)
   349  	enPeer := NewMockPeer(mockCtrl)
   350  
   351  	cnPeer.EXPECT().DisconnectP2PPeer(p2p.DiscQuitting).Times(1)
   352  	pnPeer.EXPECT().DisconnectP2PPeer(p2p.DiscQuitting).Times(1)
   353  	enPeer.EXPECT().DisconnectP2PPeer(p2p.DiscQuitting).Times(1)
   354  
   355  	setMockPeersConnType(cnPeer, pnPeer, enPeer)
   356  	setMockPeers([]*MockPeer{cnPeer, pnPeer, enPeer})
   357  
   358  	assert.NoError(t, peerSet.Register(cnPeer, nil))
   359  	assert.NoError(t, peerSet.Register(pnPeer, nil))
   360  	assert.NoError(t, peerSet.Register(enPeer, nil))
   361  
   362  	assert.False(t, peerSet.closed)
   363  	peerSet.Close()
   364  	assert.True(t, peerSet.closed)
   365  }
   366  
   367  func TestPeerSet_SampleResendPeersByType_PN(t *testing.T) {
   368  	// CN Peer=1, PN Peer=0
   369  	{
   370  		peerSet := newPeerSet()
   371  		mockCtrl := gomock.NewController(t)
   372  
   373  		cnPeer := NewMockPeer(mockCtrl)
   374  		cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).Times(2)
   375  		setMockPeers([]*MockPeer{cnPeer})
   376  
   377  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.PROXYNODE))
   378  		assert.NoError(t, peerSet.Register(cnPeer, nil))
   379  		assert.Equal(t, []Peer{cnPeer}, peerSet.SampleResendPeersByType(common.PROXYNODE))
   380  
   381  		mockCtrl.Finish()
   382  	}
   383  	// CN Peer=0, PN Peer=1
   384  	{
   385  		peerSet := newPeerSet()
   386  		mockCtrl := gomock.NewController(t)
   387  
   388  		pnPeer := NewMockPeer(mockCtrl)
   389  		pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).Times(3)
   390  		setMockPeers([]*MockPeer{pnPeer})
   391  
   392  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.PROXYNODE))
   393  		assert.NoError(t, peerSet.Register(pnPeer, nil))
   394  		assert.Equal(t, []Peer{pnPeer}, peerSet.SampleResendPeersByType(common.PROXYNODE))
   395  
   396  		mockCtrl.Finish()
   397  	}
   398  	// CN Peer=1, PN Peer=1
   399  	{
   400  		peerSet := newPeerSet()
   401  		mockCtrl := gomock.NewController(t)
   402  
   403  		cnPeer := NewMockPeer(mockCtrl)
   404  		pnPeer := NewMockPeer(mockCtrl)
   405  
   406  		cnPeer.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   407  		pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   408  
   409  		setMockPeers([]*MockPeer{cnPeer, pnPeer})
   410  
   411  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.PROXYNODE))
   412  		assert.NoError(t, peerSet.Register(cnPeer, nil))
   413  		assert.NoError(t, peerSet.Register(pnPeer, nil))
   414  		assert.Equal(t, []Peer{cnPeer}, peerSet.SampleResendPeersByType(common.PROXYNODE))
   415  
   416  		mockCtrl.Finish()
   417  	}
   418  	// CN Peer=3, PN Peer=1
   419  	{
   420  		peerSet := newPeerSet()
   421  		mockCtrl := gomock.NewController(t)
   422  
   423  		cnPeer1 := NewMockPeer(mockCtrl)
   424  		cnPeer2 := NewMockPeer(mockCtrl)
   425  		cnPeer3 := NewMockPeer(mockCtrl)
   426  		pnPeer := NewMockPeer(mockCtrl)
   427  
   428  		cnPeer1.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   429  		cnPeer2.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   430  		cnPeer3.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   431  		pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   432  
   433  		setMockPeers([]*MockPeer{cnPeer1, cnPeer2, cnPeer3, pnPeer})
   434  
   435  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.PROXYNODE))
   436  		assert.NoError(t, peerSet.Register(cnPeer1, nil))
   437  		assert.NoError(t, peerSet.Register(cnPeer2, nil))
   438  		assert.NoError(t, peerSet.Register(cnPeer3, nil))
   439  		assert.NoError(t, peerSet.Register(pnPeer, nil))
   440  		resendPeers := peerSet.SampleResendPeersByType(common.PROXYNODE)
   441  
   442  		assert.Equal(t, 2, len(resendPeers))
   443  		assert.False(t, containsPeer(pnPeer, resendPeers))
   444  
   445  		mockCtrl.Finish()
   446  	}
   447  }
   448  
   449  func TestPeerSet_SampleResendPeersByType_EN(t *testing.T) {
   450  	// PN Peer=1, EN Peer=0
   451  	{
   452  		peerSet := newPeerSet()
   453  		mockCtrl := gomock.NewController(t)
   454  
   455  		pnPeer := NewMockPeer(mockCtrl)
   456  		pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   457  		setMockPeers([]*MockPeer{pnPeer})
   458  
   459  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   460  		assert.NoError(t, peerSet.Register(pnPeer, nil))
   461  		assert.Equal(t, []Peer{pnPeer}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   462  
   463  		mockCtrl.Finish()
   464  	}
   465  	// PN Peer=0, EN Peer=1
   466  	{
   467  		peerSet := newPeerSet()
   468  		mockCtrl := gomock.NewController(t)
   469  
   470  		enPeer := NewMockPeer(mockCtrl)
   471  		enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   472  		setMockPeers([]*MockPeer{enPeer})
   473  
   474  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   475  		assert.NoError(t, peerSet.Register(enPeer, nil))
   476  		assert.Equal(t, []Peer{enPeer}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   477  
   478  		mockCtrl.Finish()
   479  	}
   480  	// PN Peer=1, EN Peer=1
   481  	{
   482  		peerSet := newPeerSet()
   483  		mockCtrl := gomock.NewController(t)
   484  
   485  		pnPeer := NewMockPeer(mockCtrl)
   486  		enPeer := NewMockPeer(mockCtrl)
   487  
   488  		pnPeer.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   489  		enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   490  
   491  		setMockPeers([]*MockPeer{pnPeer, enPeer})
   492  
   493  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   494  		assert.NoError(t, peerSet.Register(pnPeer, nil))
   495  		assert.NoError(t, peerSet.Register(enPeer, nil))
   496  		assert.Equal(t, []Peer{pnPeer, enPeer}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   497  
   498  		mockCtrl.Finish()
   499  	}
   500  	// PN Peer=3, EN Peer=1
   501  	{
   502  		peerSet := newPeerSet()
   503  		mockCtrl := gomock.NewController(t)
   504  
   505  		pnPeer1 := NewMockPeer(mockCtrl)
   506  		pnPeer2 := NewMockPeer(mockCtrl)
   507  		pnPeer3 := NewMockPeer(mockCtrl)
   508  		enPeer := NewMockPeer(mockCtrl)
   509  
   510  		pnPeer1.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   511  		pnPeer2.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   512  		pnPeer3.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   513  		enPeer.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   514  
   515  		setMockPeers([]*MockPeer{pnPeer1, pnPeer2, pnPeer3, enPeer})
   516  
   517  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   518  		registerPeers(t, peerSet, []Peer{pnPeer1, pnPeer2, pnPeer3, enPeer})
   519  		resendPeers := peerSet.SampleResendPeersByType(common.ENDPOINTNODE)
   520  
   521  		assert.Equal(t, 2, len(resendPeers))
   522  		assert.False(t, containsPeer(enPeer, resendPeers))
   523  
   524  		mockCtrl.Finish()
   525  	}
   526  	// CN Peer=1, PN Peer=2, EN Peer=2
   527  	{
   528  		peerSet := newPeerSet()
   529  		mockCtrl := gomock.NewController(t)
   530  
   531  		cnPeer1 := NewMockPeer(mockCtrl)
   532  		pnPeer1 := NewMockPeer(mockCtrl)
   533  		pnPeer2 := NewMockPeer(mockCtrl)
   534  		enPeer1 := NewMockPeer(mockCtrl)
   535  		enPeer2 := NewMockPeer(mockCtrl)
   536  
   537  		cnPeer1.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   538  
   539  		pnPeer1.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   540  		pnPeer2.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   541  
   542  		enPeer1.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   543  		enPeer2.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   544  
   545  		setMockPeers([]*MockPeer{cnPeer1, pnPeer1, pnPeer2, enPeer1, enPeer2})
   546  
   547  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   548  		registerPeers(t, peerSet, []Peer{cnPeer1, pnPeer1, pnPeer2, enPeer1, enPeer2})
   549  		resendPeers := peerSet.SampleResendPeersByType(common.ENDPOINTNODE)
   550  
   551  		assert.Equal(t, 2, len(resendPeers))
   552  		assert.Equal(t, 1, countPeerType(common.CONSENSUSNODE, resendPeers))
   553  		assert.Equal(t, 1, countPeerType(common.PROXYNODE, resendPeers))
   554  
   555  		mockCtrl.Finish()
   556  	}
   557  	// CN Peer=2, PN Peer=2, EN Peer=2
   558  	{
   559  		peerSet := newPeerSet()
   560  		mockCtrl := gomock.NewController(t)
   561  
   562  		cnPeer1 := NewMockPeer(mockCtrl)
   563  		cnPeer2 := NewMockPeer(mockCtrl)
   564  		pnPeer1 := NewMockPeer(mockCtrl)
   565  		pnPeer2 := NewMockPeer(mockCtrl)
   566  		enPeer1 := NewMockPeer(mockCtrl)
   567  		enPeer2 := NewMockPeer(mockCtrl)
   568  
   569  		cnPeer1.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   570  		cnPeer2.EXPECT().ConnType().Return(common.CONSENSUSNODE).AnyTimes()
   571  
   572  		pnPeer1.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   573  		pnPeer2.EXPECT().ConnType().Return(common.PROXYNODE).AnyTimes()
   574  
   575  		enPeer1.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   576  		enPeer2.EXPECT().ConnType().Return(common.ENDPOINTNODE).AnyTimes()
   577  
   578  		setMockPeers([]*MockPeer{cnPeer1, cnPeer2, pnPeer1, pnPeer2, enPeer1, enPeer2})
   579  
   580  		assert.Equal(t, []Peer{}, peerSet.SampleResendPeersByType(common.ENDPOINTNODE))
   581  		registerPeers(t, peerSet, []Peer{cnPeer1, cnPeer2, pnPeer1, pnPeer2, enPeer1, enPeer2})
   582  		resendPeers := peerSet.SampleResendPeersByType(common.ENDPOINTNODE)
   583  
   584  		assert.Equal(t, 2, len(resendPeers))
   585  		assert.True(t, containsPeer(cnPeer1, resendPeers))
   586  		assert.True(t, containsPeer(cnPeer2, resendPeers))
   587  
   588  		mockCtrl.Finish()
   589  	}
   590  }
   591  
   592  func TestPeerSet_SampleResendPeersByType_Default(t *testing.T) {
   593  	peerSet := newPeerSet()
   594  	mockCtrl := gomock.NewController(t)
   595  	defer mockCtrl.Finish()
   596  
   597  	cnPeer1 := NewMockPeer(mockCtrl)
   598  	cnPeer2 := NewMockPeer(mockCtrl)
   599  	pnPeer1 := NewMockPeer(mockCtrl)
   600  	pnPeer2 := NewMockPeer(mockCtrl)
   601  	enPeer1 := NewMockPeer(mockCtrl)
   602  	enPeer2 := NewMockPeer(mockCtrl)
   603  
   604  	setMockPeersConnType(cnPeer1, pnPeer1, enPeer1)
   605  	setMockPeersConnType(cnPeer2, pnPeer2, enPeer2)
   606  	setMockPeers([]*MockPeer{cnPeer1, pnPeer1, enPeer1, cnPeer2, pnPeer2, enPeer2})
   607  	registerPeers(t, peerSet, []Peer{cnPeer1, pnPeer1, enPeer1, cnPeer2, pnPeer2, enPeer2})
   608  
   609  	assert.Nil(t, peerSet.SampleResendPeersByType(common.UNKNOWNNODE))
   610  	assert.Nil(t, peerSet.SampleResendPeersByType(common.BOOTNODE))
   611  	assert.Nil(t, peerSet.SampleResendPeersByType(common.CONSENSUSNODE))
   612  }
   613  
   614  func TestPeerSet_PeersWithoutBlockExceptCN(t *testing.T) {
   615  	peerSet := newPeerSet()
   616  	mockCtrl := gomock.NewController(t)
   617  	defer mockCtrl.Finish()
   618  
   619  	cnPeer1 := NewMockPeer(mockCtrl)
   620  	cnPeer2 := NewMockPeer(mockCtrl)
   621  	pnPeer1 := NewMockPeer(mockCtrl)
   622  	pnPeer2 := NewMockPeer(mockCtrl)
   623  	enPeer1 := NewMockPeer(mockCtrl)
   624  	enPeer2 := NewMockPeer(mockCtrl)
   625  
   626  	setMockPeersConnType(cnPeer1, pnPeer1, enPeer1)
   627  	setMockPeersConnType(cnPeer2, pnPeer2, enPeer2)
   628  	setMockPeers([]*MockPeer{cnPeer1, pnPeer1, enPeer1, cnPeer2, pnPeer2, enPeer2})
   629  	registerPeers(t, peerSet, []Peer{cnPeer1, pnPeer1, enPeer1, cnPeer2, pnPeer2, enPeer2})
   630  
   631  	block := newBlock(blockNum1)
   632  	pnPeer1.EXPECT().KnowsBlock(block.Hash()).Return(true).AnyTimes()
   633  	pnPeer2.EXPECT().KnowsBlock(block.Hash()).Return(false).AnyTimes()
   634  
   635  	enPeer1.EXPECT().KnowsBlock(block.Hash()).Return(false).AnyTimes()
   636  	enPeer2.EXPECT().KnowsBlock(block.Hash()).Return(true).AnyTimes()
   637  
   638  	result := peerSet.PeersWithoutBlockExceptCN(block.Hash())
   639  	assert.Equal(t, 2, len(result))
   640  	assert.False(t, containsPeer(cnPeer1, result))
   641  	assert.False(t, containsPeer(cnPeer2, result))
   642  	assert.False(t, containsPeer(pnPeer1, result))
   643  	assert.True(t, containsPeer(pnPeer2, result))
   644  	assert.True(t, containsPeer(enPeer1, result))
   645  	assert.False(t, containsPeer(enPeer2, result))
   646  }
   647  
   648  func TestPeerSet_TypePeersWithoutBlock(t *testing.T) {
   649  	peerSet := newPeerSet()
   650  	mockCtrl := gomock.NewController(t)
   651  	defer mockCtrl.Finish()
   652  
   653  	cnPeer1 := NewMockPeer(mockCtrl)
   654  	cnPeer2 := NewMockPeer(mockCtrl)
   655  	pnPeer1 := NewMockPeer(mockCtrl)
   656  	pnPeer2 := NewMockPeer(mockCtrl)
   657  	enPeer1 := NewMockPeer(mockCtrl)
   658  	enPeer2 := NewMockPeer(mockCtrl)
   659  
   660  	setMockPeersConnType(cnPeer1, pnPeer1, enPeer1)
   661  	setMockPeersConnType(cnPeer2, pnPeer2, enPeer2)
   662  	setMockPeers([]*MockPeer{cnPeer1, pnPeer1, enPeer1, cnPeer2, pnPeer2, enPeer2})
   663  	registerPeers(t, peerSet, []Peer{cnPeer1, pnPeer1, enPeer1, cnPeer2, pnPeer2, enPeer2})
   664  
   665  	block := newBlock(blockNum1)
   666  	cnPeer1.EXPECT().KnowsBlock(block.Hash()).Return(false).AnyTimes()
   667  	cnPeer2.EXPECT().KnowsBlock(block.Hash()).Return(true).AnyTimes()
   668  
   669  	pnPeer1.EXPECT().KnowsBlock(block.Hash()).Return(true).AnyTimes()
   670  	pnPeer2.EXPECT().KnowsBlock(block.Hash()).Return(false).AnyTimes()
   671  
   672  	enPeer1.EXPECT().KnowsBlock(block.Hash()).Return(false).AnyTimes()
   673  	enPeer2.EXPECT().KnowsBlock(block.Hash()).Return(true).AnyTimes()
   674  
   675  	result := peerSet.typePeersWithoutBlock(block.Hash(), common.CONSENSUSNODE)
   676  	assert.Equal(t, 1, len(result))
   677  	assert.True(t, containsPeer(cnPeer1, result))
   678  	assert.False(t, containsPeer(cnPeer2, result))
   679  
   680  	result = peerSet.typePeersWithoutBlock(block.Hash(), common.PROXYNODE)
   681  	assert.Equal(t, 1, len(result))
   682  	assert.False(t, containsPeer(pnPeer1, result))
   683  	assert.True(t, containsPeer(pnPeer2, result))
   684  
   685  	result = peerSet.typePeersWithoutBlock(block.Hash(), common.ENDPOINTNODE)
   686  	assert.Equal(t, 1, len(result))
   687  	assert.True(t, containsPeer(enPeer1, result))
   688  	assert.False(t, containsPeer(enPeer2, result))
   689  
   690  	assert.Equal(t, 0, len(peerSet.typePeersWithoutBlock(block.Hash(), common.BOOTNODE)))
   691  	assert.Equal(t, 0, len(peerSet.typePeersWithoutBlock(block.Hash(), common.UNKNOWNNODE)))
   692  }
   693  
   694  func containsPeer(target Peer, peers []Peer) bool {
   695  	for _, peer := range peers {
   696  		if target == peer {
   697  			return true
   698  		}
   699  	}
   700  	return false
   701  }
   702  
   703  func countPeerType(t common.ConnType, peers []Peer) int {
   704  	cnt := 0
   705  	for _, peer := range peers {
   706  		if t == peer.ConnType() {
   707  			cnt++
   708  		}
   709  	}
   710  	return cnt
   711  }
   712  
   713  func registerPeers(t *testing.T, ps *peerSet, peers []Peer) {
   714  	for i, p := range peers {
   715  		if err := ps.Register(p, nil); err != nil {
   716  			t.Fatalf("Failed to register peer to peerSet. index: %v, peer: %v", i, p)
   717  		}
   718  	}
   719  }