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