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