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