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