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