github.com/number571/tendermint@v0.34.11-gost/internal/p2p/pex/pex_reactor_test.go (about)

     1  package pex
     2  
     3  import (
     4  	"encoding/hex"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/gogo/protobuf/proto"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/number571/tendermint/config"
    17  	"github.com/number571/tendermint/internal/p2p"
    18  	"github.com/number571/tendermint/internal/p2p/mock"
    19  	"github.com/number571/tendermint/libs/log"
    20  	tmp2p "github.com/number571/tendermint/proto/tendermint/p2p"
    21  	"github.com/number571/tendermint/types"
    22  )
    23  
    24  var (
    25  	cfg *config.P2PConfig
    26  )
    27  
    28  func init() {
    29  	cfg = config.DefaultP2PConfig()
    30  	cfg.PexReactor = true
    31  	cfg.AllowDuplicateIP = true
    32  }
    33  
    34  func TestPEXReactorBasic(t *testing.T) {
    35  	r, _ := createReactor(t, &ReactorConfig{})
    36  
    37  	assert.NotNil(t, r)
    38  	assert.NotEmpty(t, r.GetChannels())
    39  }
    40  
    41  func TestPEXReactorAddRemovePeer(t *testing.T) {
    42  	r, book := createReactor(t, &ReactorConfig{})
    43  
    44  	size := book.Size()
    45  	peer := p2p.CreateRandomPeer(false)
    46  
    47  	r.AddPeer(peer)
    48  	assert.Equal(t, size+1, book.Size())
    49  
    50  	r.RemovePeer(peer, "peer not available")
    51  
    52  	outboundPeer := p2p.CreateRandomPeer(true)
    53  
    54  	r.AddPeer(outboundPeer)
    55  	assert.Equal(t, size+1, book.Size(), "outbound peers should not be added to the address book")
    56  
    57  	r.RemovePeer(outboundPeer, "peer not available")
    58  }
    59  
    60  // --- FAIL: TestPEXReactorRunning (11.10s)
    61  // 				pex_reactor_test.go:411: expected all switches to be connected to at
    62  // 				least one peer (switches: 0 => {outbound: 1, inbound: 0}, 1 =>
    63  // 				{outbound: 0, inbound: 1}, 2 => {outbound: 0, inbound: 0}, )
    64  //
    65  // EXPLANATION: peers are getting rejected because in switch#addPeer we check
    66  // if any peer (who we already connected to) has the same IP. Even though local
    67  // peers have different IP addresses, they all have the same underlying remote
    68  // IP: 127.0.0.1.
    69  //
    70  func TestPEXReactorRunning(t *testing.T) {
    71  	N := 3
    72  	switches := make([]*p2p.Switch, N)
    73  
    74  	// directory to store address books
    75  	dir := tempDir(t)
    76  
    77  	books := make([]AddrBook, N)
    78  	logger := log.TestingLogger()
    79  
    80  	// create switches
    81  	for i := 0; i < N; i++ {
    82  		switches[i] = p2p.MakeSwitch(cfg, i, "testing", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch {
    83  			books[i] = NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", i)), false)
    84  			books[i].SetLogger(logger.With("pex", i))
    85  			sw.SetAddrBook(books[i])
    86  
    87  			sw.SetLogger(logger.With("pex", i))
    88  
    89  			r := NewReactor(books[i], &ReactorConfig{})
    90  			r.SetLogger(logger.With("pex", i))
    91  			r.SetEnsurePeersPeriod(250 * time.Millisecond)
    92  			sw.AddReactor("pex", r)
    93  
    94  			return sw
    95  		}, logger)
    96  	}
    97  
    98  	for _, sw := range switches {
    99  		err := sw.Start() // start switch and reactors
   100  		require.Nil(t, err)
   101  	}
   102  
   103  	addOtherNodeAddrToAddrBook := func(switchIndex, otherSwitchIndex int) {
   104  		addr := switches[otherSwitchIndex].NetAddress()
   105  		err := books[switchIndex].AddAddress(addr, addr)
   106  		require.NoError(t, err)
   107  	}
   108  
   109  	addOtherNodeAddrToAddrBook(0, 1)
   110  	addOtherNodeAddrToAddrBook(1, 0)
   111  	addOtherNodeAddrToAddrBook(2, 1)
   112  
   113  	assertPeersWithTimeout(t, switches, 10*time.Millisecond, 10*time.Second, N-1)
   114  
   115  	// stop them
   116  	for _, s := range switches {
   117  		err := s.Stop()
   118  		require.NoError(t, err)
   119  	}
   120  }
   121  
   122  func TestPEXReactorReceive(t *testing.T) {
   123  	r, book := createReactor(t, &ReactorConfig{})
   124  	peer := p2p.CreateRandomPeer(false)
   125  
   126  	// we have to send a request to receive responses
   127  	r.RequestAddrs(peer)
   128  
   129  	size := book.Size()
   130  	na, err := peer.NodeInfo().NetAddress()
   131  	require.NoError(t, err)
   132  	msg := mustEncode(&tmp2p.PexResponse{Addresses: NetAddressesToProto([]*types.NetAddress{na})})
   133  	r.Receive(PexChannel, peer, msg)
   134  	assert.Equal(t, size+1, book.Size())
   135  
   136  	msg = mustEncode(&tmp2p.PexRequest{})
   137  	r.Receive(PexChannel, peer, msg) // should not panic.
   138  }
   139  
   140  func TestPEXReactorRequestMessageAbuse(t *testing.T) {
   141  	r, book := createReactor(t, &ReactorConfig{})
   142  	sw := createSwitchAndAddReactors(r)
   143  	sw.SetAddrBook(book)
   144  
   145  	peer := mock.NewPeer(nil)
   146  	peerAddr := peer.SocketAddr()
   147  	p2p.AddPeerToSwitchPeerSet(sw, peer)
   148  	assert.True(t, sw.Peers().Has(peer.ID()))
   149  	err := book.AddAddress(peerAddr, peerAddr)
   150  	require.NoError(t, err)
   151  	require.True(t, book.HasAddress(peerAddr))
   152  
   153  	id := string(peer.ID())
   154  	msg := mustEncode(&tmp2p.PexRequest{})
   155  
   156  	// first time creates the entry
   157  	r.Receive(PexChannel, peer, msg)
   158  	assert.True(t, r.lastReceivedRequests.Has(id))
   159  	assert.True(t, sw.Peers().Has(peer.ID()))
   160  
   161  	// next time sets the last time value
   162  	r.Receive(PexChannel, peer, msg)
   163  	assert.True(t, r.lastReceivedRequests.Has(id))
   164  	assert.True(t, sw.Peers().Has(peer.ID()))
   165  
   166  	// third time is too many too soon - peer is removed
   167  	r.Receive(PexChannel, peer, msg)
   168  	assert.False(t, r.lastReceivedRequests.Has(id))
   169  	assert.False(t, sw.Peers().Has(peer.ID()))
   170  	assert.True(t, book.IsBanned(peerAddr))
   171  }
   172  
   173  func TestPEXReactorAddrsMessageAbuse(t *testing.T) {
   174  	r, book := createReactor(t, &ReactorConfig{})
   175  	sw := createSwitchAndAddReactors(r)
   176  	sw.SetAddrBook(book)
   177  
   178  	peer := mock.NewPeer(nil)
   179  	p2p.AddPeerToSwitchPeerSet(sw, peer)
   180  	assert.True(t, sw.Peers().Has(peer.ID()))
   181  
   182  	id := string(peer.ID())
   183  
   184  	// request addrs from the peer
   185  	r.RequestAddrs(peer)
   186  	assert.True(t, r.requestsSent.Has(id))
   187  	assert.True(t, sw.Peers().Has(peer.ID()))
   188  
   189  	msg := mustEncode(&tmp2p.PexResponse{Addresses: NetAddressesToProto([]*types.NetAddress{peer.SocketAddr()})})
   190  
   191  	// receive some addrs. should clear the request
   192  	r.Receive(PexChannel, peer, msg)
   193  	assert.False(t, r.requestsSent.Has(id))
   194  	assert.True(t, sw.Peers().Has(peer.ID()))
   195  
   196  	// receiving more unsolicited addrs causes a disconnect and ban
   197  	r.Receive(PexChannel, peer, msg)
   198  	assert.False(t, sw.Peers().Has(peer.ID()))
   199  	assert.True(t, book.IsBanned(peer.SocketAddr()))
   200  }
   201  
   202  func TestCheckSeeds(t *testing.T) {
   203  	// directory to store address books
   204  	dir := tempDir(t)
   205  
   206  	// 1. test creating peer with no seeds works
   207  	peerSwitch := testCreateDefaultPeer(dir, 0)
   208  	require.Nil(t, peerSwitch.Start())
   209  	peerSwitch.Stop() // nolint:errcheck // ignore for tests
   210  
   211  	// 2. create seed
   212  	seed := testCreateSeed(dir, 1, []*p2p.NetAddress{}, []*p2p.NetAddress{})
   213  
   214  	// 3. test create peer with online seed works
   215  	peerSwitch = testCreatePeerWithSeed(dir, 2, seed)
   216  	require.Nil(t, peerSwitch.Start())
   217  	peerSwitch.Stop() // nolint:errcheck // ignore for tests
   218  
   219  	// 4. test create peer with all seeds having unresolvable DNS fails
   220  	badPeerConfig := &ReactorConfig{
   221  		Seeds: []string{"ed3dfd27bfc4af18f67a49862f04cc100696e84d@bad.network.addr:26657",
   222  			"d824b13cb5d40fa1d8a614e089357c7eff31b670@anotherbad.network.addr:26657"},
   223  	}
   224  	peerSwitch = testCreatePeerWithConfig(dir, 2, badPeerConfig)
   225  	require.Error(t, peerSwitch.Start())
   226  	peerSwitch.Stop() // nolint:errcheck // ignore for tests
   227  
   228  	// 5. test create peer with one good seed address succeeds
   229  	badPeerConfig = &ReactorConfig{
   230  		Seeds: []string{"ed3dfd27bfc4af18f67a49862f04cc100696e84d@bad.network.addr:26657",
   231  			"d824b13cb5d40fa1d8a614e089357c7eff31b670@anotherbad.network.addr:26657",
   232  			seed.NetAddress().String()},
   233  	}
   234  	peerSwitch = testCreatePeerWithConfig(dir, 2, badPeerConfig)
   235  	require.Nil(t, peerSwitch.Start())
   236  	peerSwitch.Stop() // nolint:errcheck // ignore for tests
   237  }
   238  
   239  func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) {
   240  	// directory to store address books
   241  	dir := tempDir(t)
   242  
   243  	// 1. create seed
   244  	seed := testCreateSeed(dir, 0, []*p2p.NetAddress{}, []*p2p.NetAddress{})
   245  	require.Nil(t, seed.Start())
   246  	t.Cleanup(func() { _ = seed.Stop() })
   247  
   248  	// 2. create usual peer with only seed configured.
   249  	peer := testCreatePeerWithSeed(dir, 1, seed)
   250  	require.Nil(t, peer.Start())
   251  	t.Cleanup(func() { _ = peer.Stop() })
   252  
   253  	// 3. check that the peer connects to seed immediately
   254  	assertPeersWithTimeout(t, []*p2p.Switch{peer}, 10*time.Millisecond, 3*time.Second, 1)
   255  }
   256  
   257  func TestConnectionSpeedForPeerReceivedFromSeed(t *testing.T) {
   258  	// directory to store address books
   259  	dir := tempDir(t)
   260  
   261  	// 1. create peer
   262  	peerSwitch := testCreateDefaultPeer(dir, 1)
   263  	require.Nil(t, peerSwitch.Start())
   264  	t.Cleanup(func() { _ = peerSwitch.Stop() })
   265  
   266  	// 2. Create seed which knows about the peer
   267  	peerAddr := peerSwitch.NetAddress()
   268  	seed := testCreateSeed(dir, 2, []*p2p.NetAddress{peerAddr}, []*p2p.NetAddress{peerAddr})
   269  	require.Nil(t, seed.Start())
   270  	t.Cleanup(func() { _ = seed.Stop() })
   271  
   272  	// 3. create another peer with only seed configured.
   273  	secondPeer := testCreatePeerWithSeed(dir, 3, seed)
   274  	require.Nil(t, secondPeer.Start())
   275  	t.Cleanup(func() { _ = secondPeer.Stop() })
   276  
   277  	// 4. check that the second peer connects to seed immediately
   278  	assertPeersWithTimeout(t, []*p2p.Switch{secondPeer}, 10*time.Millisecond, 3*time.Second, 1)
   279  
   280  	// 5. check that the second peer connects to the first peer immediately
   281  	assertPeersWithTimeout(t, []*p2p.Switch{secondPeer}, 10*time.Millisecond, 1*time.Second, 2)
   282  }
   283  
   284  func TestPEXReactorSeedMode(t *testing.T) {
   285  	// directory to store address books
   286  	dir := tempDir(t)
   287  
   288  	pexRConfig := &ReactorConfig{SeedMode: true, SeedDisconnectWaitPeriod: 10 * time.Millisecond}
   289  	pexR, book := createReactor(t, pexRConfig)
   290  	sw := createSwitchAndAddReactors(pexR)
   291  
   292  	sw.SetAddrBook(book)
   293  	require.NoError(t, sw.Start())
   294  	t.Cleanup(func() { _ = sw.Stop() })
   295  
   296  	assert.Zero(t, sw.Peers().Size())
   297  
   298  	peerSwitch := testCreateDefaultPeer(dir, 1)
   299  	require.NoError(t, peerSwitch.Start())
   300  	t.Cleanup(func() { _ = peerSwitch.Stop() })
   301  
   302  	// 1. Test crawlPeers dials the peer
   303  	pexR.crawlPeers([]*p2p.NetAddress{peerSwitch.NetAddress()})
   304  	assert.Equal(t, 1, sw.Peers().Size())
   305  	assert.True(t, sw.Peers().Has(peerSwitch.NodeInfo().ID()))
   306  
   307  	// 2. attemptDisconnects should not disconnect because of wait period
   308  	pexR.attemptDisconnects()
   309  	assert.Equal(t, 1, sw.Peers().Size())
   310  
   311  	// sleep for SeedDisconnectWaitPeriod
   312  	time.Sleep(pexRConfig.SeedDisconnectWaitPeriod + 1*time.Millisecond)
   313  
   314  	// 3. attemptDisconnects should disconnect after wait period
   315  	pexR.attemptDisconnects()
   316  	assert.Equal(t, 0, sw.Peers().Size())
   317  }
   318  
   319  func TestPEXReactorDoesNotDisconnectFromPersistentPeerInSeedMode(t *testing.T) {
   320  	// directory to store address books
   321  	dir := tempDir(t)
   322  
   323  	pexRConfig := &ReactorConfig{SeedMode: true, SeedDisconnectWaitPeriod: 1 * time.Millisecond}
   324  	pexR, book := createReactor(t, pexRConfig)
   325  	sw := createSwitchAndAddReactors(pexR)
   326  
   327  	sw.SetAddrBook(book)
   328  	require.NoError(t, sw.Start())
   329  	t.Cleanup(func() { _ = sw.Stop() })
   330  
   331  	assert.Zero(t, sw.Peers().Size())
   332  
   333  	peerSwitch := testCreatePeerWithConfig(dir, 1, pexRConfig)
   334  	require.NoError(t, peerSwitch.Start())
   335  	t.Cleanup(func() { _ = peerSwitch.Stop() })
   336  
   337  	require.NoError(t, sw.AddPersistentPeers([]string{peerSwitch.NetAddress().String()}))
   338  
   339  	// 1. Test crawlPeers dials the peer
   340  	pexR.crawlPeers([]*p2p.NetAddress{peerSwitch.NetAddress()})
   341  	assert.Equal(t, 1, sw.Peers().Size())
   342  	assert.True(t, sw.Peers().Has(peerSwitch.NodeInfo().ID()))
   343  
   344  	// sleep for SeedDisconnectWaitPeriod
   345  	time.Sleep(pexRConfig.SeedDisconnectWaitPeriod + 1*time.Millisecond)
   346  
   347  	// 2. attemptDisconnects should not disconnect because the peer is persistent
   348  	pexR.attemptDisconnects()
   349  	assert.Equal(t, 1, sw.Peers().Size())
   350  }
   351  
   352  func TestPEXReactorDialsPeerUpToMaxAttemptsInSeedMode(t *testing.T) {
   353  	// directory to store address books
   354  	pexR, book := createReactor(t, &ReactorConfig{SeedMode: true})
   355  	sw := createSwitchAndAddReactors(pexR)
   356  
   357  	sw.SetAddrBook(book)
   358  	// No need to start sw since crawlPeers is called manually here.
   359  
   360  	peer := mock.NewPeer(nil)
   361  	addr := peer.SocketAddr()
   362  
   363  	require.NoError(t, book.AddAddress(addr, addr))
   364  
   365  	assert.True(t, book.HasAddress(addr))
   366  
   367  	// imitate maxAttemptsToDial reached
   368  	pexR.attemptsToDial.Store(addr.DialString(), _attemptsToDial{maxAttemptsToDial + 1, time.Now()})
   369  	pexR.crawlPeers([]*p2p.NetAddress{addr})
   370  
   371  	assert.False(t, book.HasAddress(addr))
   372  }
   373  
   374  // connect a peer to a seed, wait a bit, then stop it.
   375  // this should give it time to request addrs and for the seed
   376  // to call FlushStop, and allows us to test calling Stop concurrently
   377  // with FlushStop. Before a fix, this non-deterministically reproduced
   378  // https://github.com/number571/tendermint/issues/3231.
   379  func TestPEXReactorSeedModeFlushStop(t *testing.T) {
   380  	t.Skip("flaky test, will be replaced by new P2P stack")
   381  	N := 2
   382  	switches := make([]*p2p.Switch, N)
   383  
   384  	// directory to store address books
   385  	dir := tempDir(t)
   386  
   387  	books := make([]AddrBook, N)
   388  	logger := log.TestingLogger()
   389  
   390  	// create switches
   391  	for i := 0; i < N; i++ {
   392  		switches[i] = p2p.MakeSwitch(cfg, i, "testing", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch {
   393  			books[i] = NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", i)), false)
   394  			books[i].SetLogger(logger.With("pex", i))
   395  			sw.SetAddrBook(books[i])
   396  
   397  			sw.SetLogger(logger.With("pex", i))
   398  
   399  			config := &ReactorConfig{}
   400  			if i == 0 {
   401  				// first one is a seed node
   402  				config = &ReactorConfig{SeedMode: true}
   403  			}
   404  			r := NewReactor(books[i], config)
   405  			r.SetLogger(logger.With("pex", i))
   406  			r.SetEnsurePeersPeriod(250 * time.Millisecond)
   407  			sw.AddReactor("pex", r)
   408  
   409  			return sw
   410  		}, logger)
   411  	}
   412  
   413  	for _, sw := range switches {
   414  		err := sw.Start() // start switch and reactors
   415  		require.Nil(t, err)
   416  	}
   417  
   418  	reactor := switches[0].Reactors()["pex"].(*Reactor)
   419  	peerID := switches[1].NodeInfo().ID()
   420  
   421  	assert.NoError(t, switches[1].DialPeerWithAddress(switches[0].NetAddress()))
   422  
   423  	// sleep up to a second while waiting for the peer to send us a message.
   424  	// this isn't perfect since it's possible the peer sends us a msg and we FlushStop
   425  	// before this loop catches it. but non-deterministically it works pretty well.
   426  	for i := 0; i < 1000; i++ {
   427  		v := reactor.lastReceivedRequests.Get(string(peerID))
   428  		if v != nil {
   429  			break
   430  		}
   431  		time.Sleep(time.Millisecond)
   432  	}
   433  
   434  	// by now the FlushStop should have happened. Try stopping the peer.
   435  	// it should be safe to do this.
   436  	peers := switches[0].Peers().List()
   437  	for _, peer := range peers {
   438  		err := peer.Stop()
   439  		require.NoError(t, err)
   440  	}
   441  
   442  	// stop the switches
   443  	for _, s := range switches {
   444  		err := s.Stop()
   445  		require.NoError(t, err)
   446  	}
   447  }
   448  
   449  func TestPEXReactorDoesNotAddPrivatePeersToAddrBook(t *testing.T) {
   450  	peer := p2p.CreateRandomPeer(false)
   451  
   452  	pexR, book := createReactor(t, &ReactorConfig{})
   453  	book.AddPrivateIDs([]string{string(peer.NodeInfo().ID())})
   454  
   455  	// we have to send a request to receive responses
   456  	pexR.RequestAddrs(peer)
   457  
   458  	size := book.Size()
   459  	na, err := peer.NodeInfo().NetAddress()
   460  	require.NoError(t, err)
   461  
   462  	msg := mustEncode(&tmp2p.PexResponse{Addresses: NetAddressesToProto([]*types.NetAddress{na})})
   463  	pexR.Receive(PexChannel, peer, msg)
   464  	assert.Equal(t, size, book.Size())
   465  
   466  	pexR.AddPeer(peer)
   467  	assert.Equal(t, size, book.Size())
   468  }
   469  
   470  func TestPEXReactorDialPeer(t *testing.T) {
   471  	pexR, book := createReactor(t, &ReactorConfig{})
   472  	sw := createSwitchAndAddReactors(pexR)
   473  
   474  	sw.SetAddrBook(book)
   475  
   476  	peer := mock.NewPeer(nil)
   477  	addr := peer.SocketAddr()
   478  
   479  	assert.Equal(t, 0, pexR.AttemptsToDial(addr))
   480  
   481  	// 1st unsuccessful attempt
   482  	err := pexR.dialPeer(addr)
   483  	require.Error(t, err)
   484  
   485  	assert.Equal(t, 1, pexR.AttemptsToDial(addr))
   486  
   487  	// 2nd unsuccessful attempt
   488  	err = pexR.dialPeer(addr)
   489  	require.Error(t, err)
   490  
   491  	// must be skipped because it is too early
   492  	assert.Equal(t, 1, pexR.AttemptsToDial(addr))
   493  
   494  	if !testing.Short() {
   495  		time.Sleep(3 * time.Second)
   496  
   497  		// 3rd attempt
   498  		err = pexR.dialPeer(addr)
   499  		require.Error(t, err)
   500  
   501  		assert.Equal(t, 2, pexR.AttemptsToDial(addr))
   502  	}
   503  }
   504  
   505  func assertPeersWithTimeout(
   506  	t *testing.T,
   507  	switches []*p2p.Switch,
   508  	checkPeriod, timeout time.Duration,
   509  	nPeers int,
   510  ) {
   511  	var (
   512  		ticker    = time.NewTicker(checkPeriod)
   513  		remaining = timeout
   514  	)
   515  
   516  	for {
   517  		select {
   518  		case <-ticker.C:
   519  			// check peers are connected
   520  			allGood := true
   521  			for _, s := range switches {
   522  				outbound, inbound, _ := s.NumPeers()
   523  				if outbound+inbound < nPeers {
   524  					allGood = false
   525  					break
   526  				}
   527  			}
   528  			remaining -= checkPeriod
   529  			if remaining < 0 {
   530  				remaining = 0
   531  			}
   532  			if allGood {
   533  				return
   534  			}
   535  		case <-time.After(remaining):
   536  			numPeersStr := ""
   537  			for i, s := range switches {
   538  				outbound, inbound, _ := s.NumPeers()
   539  				numPeersStr += fmt.Sprintf("%d => {outbound: %d, inbound: %d}, ", i, outbound, inbound)
   540  			}
   541  			t.Errorf(
   542  				"expected all switches to be connected to at least %d peer(s) (switches: %s)",
   543  				nPeers, numPeersStr,
   544  			)
   545  			return
   546  		}
   547  	}
   548  }
   549  
   550  // Creates a peer with the provided config
   551  func testCreatePeerWithConfig(dir string, id int, config *ReactorConfig) *p2p.Switch {
   552  	peer := p2p.MakeSwitch(
   553  		cfg,
   554  		id,
   555  		"127.0.0.1",
   556  		"123.123.123",
   557  		func(i int, sw *p2p.Switch) *p2p.Switch {
   558  			book := NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", id)), false)
   559  			book.SetLogger(log.TestingLogger())
   560  			sw.SetAddrBook(book)
   561  
   562  			sw.SetLogger(log.TestingLogger())
   563  
   564  			r := NewReactor(
   565  				book,
   566  				config,
   567  			)
   568  			r.SetLogger(log.TestingLogger())
   569  			sw.AddReactor("pex", r)
   570  			return sw
   571  		},
   572  		log.TestingLogger(),
   573  	)
   574  	return peer
   575  }
   576  
   577  // Creates a peer with the default config
   578  func testCreateDefaultPeer(dir string, id int) *p2p.Switch {
   579  	return testCreatePeerWithConfig(dir, id, &ReactorConfig{})
   580  }
   581  
   582  // Creates a seed which knows about the provided addresses / source address pairs.
   583  // Starting and stopping the seed is left to the caller
   584  func testCreateSeed(dir string, id int, knownAddrs, srcAddrs []*p2p.NetAddress) *p2p.Switch {
   585  	seed := p2p.MakeSwitch(
   586  		cfg,
   587  		id,
   588  		"127.0.0.1",
   589  		"123.123.123",
   590  		func(i int, sw *p2p.Switch) *p2p.Switch {
   591  			book := NewAddrBook(filepath.Join(dir, "addrbookSeed.json"), false)
   592  			book.SetLogger(log.TestingLogger())
   593  			for j := 0; j < len(knownAddrs); j++ {
   594  				book.AddAddress(knownAddrs[j], srcAddrs[j]) // nolint:errcheck // ignore for tests
   595  				book.MarkGood(knownAddrs[j].ID)
   596  			}
   597  			sw.SetAddrBook(book)
   598  
   599  			sw.SetLogger(log.TestingLogger())
   600  
   601  			r := NewReactor(book, &ReactorConfig{})
   602  			r.SetLogger(log.TestingLogger())
   603  			sw.AddReactor("pex", r)
   604  			return sw
   605  		},
   606  		log.TestingLogger(),
   607  	)
   608  	return seed
   609  }
   610  
   611  // Creates a peer which knows about the provided seed.
   612  // Starting and stopping the peer is left to the caller
   613  func testCreatePeerWithSeed(dir string, id int, seed *p2p.Switch) *p2p.Switch {
   614  	conf := &ReactorConfig{
   615  		Seeds: []string{seed.NetAddress().String()},
   616  	}
   617  	return testCreatePeerWithConfig(dir, id, conf)
   618  }
   619  
   620  func createReactor(t *testing.T, conf *ReactorConfig) (r *Reactor, book AddrBook) {
   621  	// directory to store address book
   622  	book = NewAddrBook(filepath.Join(tempDir(t), "addrbook.json"), true)
   623  	book.SetLogger(log.TestingLogger())
   624  
   625  	r = NewReactor(book, conf)
   626  	r.SetLogger(log.TestingLogger())
   627  	return
   628  }
   629  
   630  func createSwitchAndAddReactors(reactors ...p2p.Reactor) *p2p.Switch {
   631  	sw := p2p.MakeSwitch(cfg, 0, "127.0.0.1", "123.123.123", func(i int, sw *p2p.Switch) *p2p.Switch {
   632  		for _, r := range reactors {
   633  			sw.AddReactor(r.String(), r)
   634  		}
   635  		return sw
   636  	}, log.TestingLogger())
   637  	return sw
   638  }
   639  
   640  func TestPexVectors(t *testing.T) {
   641  	addr := tmp2p.PexAddress{
   642  		ID:   "1",
   643  		IP:   "127.0.0.1",
   644  		Port: 9090,
   645  	}
   646  
   647  	testCases := []struct {
   648  		testName string
   649  		msg      proto.Message
   650  		expBytes string
   651  	}{
   652  		{"PexRequest", &tmp2p.PexRequest{}, "0a00"},
   653  		{"PexAddrs", &tmp2p.PexResponse{Addresses: []tmp2p.PexAddress{addr}}, "12130a110a013112093132372e302e302e31188247"},
   654  	}
   655  
   656  	for _, tc := range testCases {
   657  		tc := tc
   658  
   659  		bz := mustEncode(tc.msg)
   660  
   661  		require.Equal(t, tc.expBytes, hex.EncodeToString(bz), tc.testName)
   662  	}
   663  }
   664  
   665  // FIXME: This function is used in place of testing.TB.TempDir()
   666  // as the latter seems to cause test cases to fail when it is
   667  // unable to remove the temporary directory once  the test case
   668  // execution terminates. This seems to  happen often with pex
   669  // reactor test cases.
   670  //
   671  // References:
   672  // https://github.com/number571/tendermint/pull/5733
   673  // https://github.com/number571/tendermint/issues/5732
   674  func tempDir(t *testing.T) string {
   675  	t.Helper()
   676  	dir, err := ioutil.TempDir("", "")
   677  	require.NoError(t, err)
   678  	t.Cleanup(func() { _ = os.RemoveAll(dir) })
   679  	return dir
   680  }