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