You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

818 lines
22 KiB

  1. package pex_test
  2. import (
  3. "context"
  4. "strings"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/require"
  8. dbm "github.com/tendermint/tm-db"
  9. "github.com/tendermint/tendermint/crypto/ed25519"
  10. "github.com/tendermint/tendermint/internal/p2p"
  11. "github.com/tendermint/tendermint/internal/p2p/p2ptest"
  12. "github.com/tendermint/tendermint/internal/p2p/pex"
  13. "github.com/tendermint/tendermint/libs/log"
  14. proto "github.com/tendermint/tendermint/proto/tendermint/p2p"
  15. "github.com/tendermint/tendermint/types"
  16. )
  17. const (
  18. checkFrequency = 500 * time.Millisecond
  19. defaultBufferSize = 2
  20. shortWait = 10 * time.Second
  21. longWait = 60 * time.Second
  22. firstNode = 0
  23. secondNode = 1
  24. thirdNode = 2
  25. fourthNode = 3
  26. )
  27. func TestReactorBasic(t *testing.T) {
  28. // start a network with one mock reactor and one "real" reactor
  29. testNet := setupNetwork(t, testOptions{
  30. MockNodes: 1,
  31. TotalNodes: 2,
  32. })
  33. testNet.connectAll(t)
  34. testNet.start(t)
  35. // assert that the mock node receives a request from the real node
  36. testNet.listenForRequest(t, secondNode, firstNode, shortWait)
  37. // assert that when a mock node sends a request it receives a response (and
  38. // the correct one)
  39. testNet.sendRequest(t, firstNode, secondNode, true)
  40. testNet.listenForResponse(t, secondNode, firstNode, shortWait, []proto.PexAddressV2(nil))
  41. }
  42. func TestReactorConnectFullNetwork(t *testing.T) {
  43. testNet := setupNetwork(t, testOptions{
  44. TotalNodes: 4,
  45. })
  46. // make every node be only connected with one other node (it actually ends up
  47. // being two because of two way connections but oh well)
  48. testNet.connectN(t, 1)
  49. testNet.start(t)
  50. // assert that all nodes add each other in the network
  51. for idx := 0; idx < len(testNet.nodes); idx++ {
  52. testNet.requireNumberOfPeers(t, idx, len(testNet.nodes)-1, longWait)
  53. }
  54. }
  55. func TestReactorSendsRequestsTooOften(t *testing.T) {
  56. r := setupSingle(t)
  57. badNode := newNodeID(t, "b")
  58. r.pexInCh <- p2p.Envelope{
  59. From: badNode,
  60. Message: &proto.PexRequestV2{},
  61. }
  62. resp := <-r.pexOutCh
  63. msg, ok := resp.Message.(*proto.PexResponseV2)
  64. require.True(t, ok)
  65. require.Empty(t, msg.Addresses)
  66. r.pexInCh <- p2p.Envelope{
  67. From: badNode,
  68. Message: &proto.PexRequestV2{},
  69. }
  70. peerErr := <-r.pexErrCh
  71. require.Error(t, peerErr.Err)
  72. require.Empty(t, r.pexOutCh)
  73. require.Contains(t, peerErr.Err.Error(), "peer sent a request too close after a prior one")
  74. require.Equal(t, badNode, peerErr.NodeID)
  75. }
  76. func TestReactorSendsResponseWithoutRequest(t *testing.T) {
  77. testNet := setupNetwork(t, testOptions{
  78. MockNodes: 1,
  79. TotalNodes: 3,
  80. })
  81. testNet.connectAll(t)
  82. testNet.start(t)
  83. // firstNode sends the secondNode an unrequested response
  84. // NOTE: secondNode will send a request by default during startup so we send
  85. // two responses to counter that.
  86. testNet.sendResponse(t, firstNode, secondNode, []int{thirdNode}, true)
  87. testNet.sendResponse(t, firstNode, secondNode, []int{thirdNode}, true)
  88. // secondNode should evict the firstNode
  89. testNet.listenForPeerUpdate(t, secondNode, firstNode, p2p.PeerStatusDown, shortWait)
  90. }
  91. func TestReactorNeverSendsTooManyPeers(t *testing.T) {
  92. testNet := setupNetwork(t, testOptions{
  93. MockNodes: 1,
  94. TotalNodes: 2,
  95. })
  96. testNet.connectAll(t)
  97. testNet.start(t)
  98. testNet.addNodes(t, 110)
  99. nodes := make([]int, 110)
  100. for i := 0; i < len(nodes); i++ {
  101. nodes[i] = i + 2
  102. }
  103. testNet.addAddresses(t, secondNode, nodes)
  104. // first we check that even although we have 110 peers, honest pex reactors
  105. // only send 100 (test if secondNode sends firstNode 100 addresses)
  106. testNet.pingAndlistenForNAddresses(t, secondNode, firstNode, shortWait, 100)
  107. }
  108. func TestReactorErrorsOnReceivingTooManyPeers(t *testing.T) {
  109. r := setupSingle(t)
  110. peer := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID(t)}
  111. added, err := r.manager.Add(peer)
  112. require.NoError(t, err)
  113. require.True(t, added)
  114. addresses := make([]proto.PexAddressV2, 101)
  115. for i := 0; i < len(addresses); i++ {
  116. nodeAddress := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID(t)}
  117. addresses[i] = proto.PexAddressV2{
  118. URL: nodeAddress.String(),
  119. }
  120. }
  121. r.peerCh <- p2p.PeerUpdate{
  122. NodeID: peer.NodeID,
  123. Status: p2p.PeerStatusUp,
  124. }
  125. select {
  126. // wait for a request and then send a response with too many addresses
  127. case req := <-r.pexOutCh:
  128. if _, ok := req.Message.(*proto.PexRequestV2); !ok {
  129. t.Fatal("expected v2 pex request")
  130. }
  131. r.pexInCh <- p2p.Envelope{
  132. From: peer.NodeID,
  133. Message: &proto.PexResponseV2{
  134. Addresses: addresses,
  135. },
  136. }
  137. case <-time.After(10 * time.Second):
  138. t.Fatal("pex failed to send a request within 10 seconds")
  139. }
  140. peerErr := <-r.pexErrCh
  141. require.Error(t, peerErr.Err)
  142. require.Empty(t, r.pexOutCh)
  143. require.Contains(t, peerErr.Err.Error(), "peer sent too many addresses")
  144. require.Equal(t, peer.NodeID, peerErr.NodeID)
  145. }
  146. func TestReactorSmallPeerStoreInALargeNetwork(t *testing.T) {
  147. testNet := setupNetwork(t, testOptions{
  148. TotalNodes: 8,
  149. MaxPeers: 4,
  150. MaxConnected: 3,
  151. BufferSize: 8,
  152. })
  153. testNet.connectN(t, 1)
  154. testNet.start(t)
  155. // test that all nodes reach full capacity
  156. for _, nodeID := range testNet.nodes {
  157. require.Eventually(t, func() bool {
  158. // nolint:scopelint
  159. return testNet.network.Nodes[nodeID].PeerManager.PeerRatio() >= 0.9
  160. }, longWait, checkFrequency)
  161. }
  162. }
  163. func TestReactorLargePeerStoreInASmallNetwork(t *testing.T) {
  164. testNet := setupNetwork(t, testOptions{
  165. TotalNodes: 3,
  166. MaxPeers: 25,
  167. MaxConnected: 25,
  168. BufferSize: 5,
  169. })
  170. testNet.connectN(t, 1)
  171. testNet.start(t)
  172. // assert that all nodes add each other in the network
  173. for idx := 0; idx < len(testNet.nodes); idx++ {
  174. testNet.requireNumberOfPeers(t, idx, len(testNet.nodes)-1, longWait)
  175. }
  176. }
  177. func TestReactorWithNetworkGrowth(t *testing.T) {
  178. testNet := setupNetwork(t, testOptions{
  179. TotalNodes: 5,
  180. BufferSize: 5,
  181. })
  182. testNet.connectAll(t)
  183. testNet.start(t)
  184. // assert that all nodes add each other in the network
  185. for idx := 0; idx < len(testNet.nodes); idx++ {
  186. testNet.requireNumberOfPeers(t, idx, len(testNet.nodes)-1, shortWait)
  187. }
  188. // now we inject 10 more nodes
  189. testNet.addNodes(t, 10)
  190. for i := 5; i < testNet.total; i++ {
  191. node := testNet.nodes[i]
  192. require.NoError(t, testNet.reactors[node].Start())
  193. require.True(t, testNet.reactors[node].IsRunning())
  194. // we connect all new nodes to a single entry point and check that the
  195. // node can distribute the addresses to all the others
  196. testNet.connectPeers(t, 0, i)
  197. }
  198. require.Len(t, testNet.reactors, 15)
  199. // assert that all nodes add each other in the network
  200. for idx := 0; idx < len(testNet.nodes); idx++ {
  201. testNet.requireNumberOfPeers(t, idx, len(testNet.nodes)-1, longWait)
  202. }
  203. }
  204. func TestReactorIntegrationWithLegacyHandleRequest(t *testing.T) {
  205. testNet := setupNetwork(t, testOptions{
  206. MockNodes: 1,
  207. TotalNodes: 3,
  208. })
  209. testNet.connectAll(t)
  210. testNet.start(t)
  211. t.Log(testNet.nodes)
  212. // mock node sends a V1 Pex message to the second node
  213. testNet.sendRequest(t, firstNode, secondNode, false)
  214. addrs := testNet.getAddressesFor(t, []int{thirdNode})
  215. testNet.listenForLegacyResponse(t, secondNode, firstNode, shortWait, addrs)
  216. }
  217. func TestReactorIntegrationWithLegacyHandleResponse(t *testing.T) {
  218. testNet := setupNetwork(t, testOptions{
  219. MockNodes: 1,
  220. TotalNodes: 4,
  221. BufferSize: 4,
  222. })
  223. testNet.connectPeers(t, firstNode, secondNode)
  224. testNet.connectPeers(t, firstNode, thirdNode)
  225. testNet.connectPeers(t, firstNode, fourthNode)
  226. testNet.start(t)
  227. testNet.listenForRequest(t, secondNode, firstNode, shortWait)
  228. // send a v1 response instead
  229. testNet.sendResponse(t, firstNode, secondNode, []int{thirdNode, fourthNode}, false)
  230. testNet.requireNumberOfPeers(t, secondNode, len(testNet.nodes)-1, shortWait)
  231. }
  232. type singleTestReactor struct {
  233. reactor *pex.ReactorV2
  234. pexInCh chan p2p.Envelope
  235. pexOutCh chan p2p.Envelope
  236. pexErrCh chan p2p.PeerError
  237. pexCh *p2p.Channel
  238. peerCh chan p2p.PeerUpdate
  239. manager *p2p.PeerManager
  240. }
  241. func setupSingle(t *testing.T) *singleTestReactor {
  242. t.Helper()
  243. nodeID := newNodeID(t, "a")
  244. chBuf := 2
  245. pexInCh := make(chan p2p.Envelope, chBuf)
  246. pexOutCh := make(chan p2p.Envelope, chBuf)
  247. pexErrCh := make(chan p2p.PeerError, chBuf)
  248. pexCh := p2p.NewChannel(
  249. p2p.ChannelID(pex.PexChannel),
  250. new(proto.PexMessage),
  251. pexInCh,
  252. pexOutCh,
  253. pexErrCh,
  254. )
  255. peerCh := make(chan p2p.PeerUpdate, chBuf)
  256. peerUpdates := p2p.NewPeerUpdates(peerCh, chBuf)
  257. peerManager, err := p2p.NewPeerManager(nodeID, dbm.NewMemDB(), p2p.PeerManagerOptions{})
  258. require.NoError(t, err)
  259. reactor := pex.NewReactorV2(log.TestingLogger(), peerManager, pexCh, peerUpdates)
  260. require.NoError(t, reactor.Start())
  261. t.Cleanup(func() {
  262. err := reactor.Stop()
  263. if err != nil {
  264. t.Fatal(err)
  265. }
  266. pexCh.Close()
  267. peerUpdates.Close()
  268. })
  269. return &singleTestReactor{
  270. reactor: reactor,
  271. pexInCh: pexInCh,
  272. pexOutCh: pexOutCh,
  273. pexErrCh: pexErrCh,
  274. pexCh: pexCh,
  275. peerCh: peerCh,
  276. manager: peerManager,
  277. }
  278. }
  279. type reactorTestSuite struct {
  280. network *p2ptest.Network
  281. logger log.Logger
  282. reactors map[types.NodeID]*pex.ReactorV2
  283. pexChannels map[types.NodeID]*p2p.Channel
  284. peerChans map[types.NodeID]chan p2p.PeerUpdate
  285. peerUpdates map[types.NodeID]*p2p.PeerUpdates
  286. nodes []types.NodeID
  287. mocks []types.NodeID
  288. total int
  289. opts testOptions
  290. }
  291. type testOptions struct {
  292. MockNodes int
  293. TotalNodes int
  294. BufferSize int
  295. MaxPeers uint16
  296. MaxConnected uint16
  297. }
  298. // setup setups a test suite with a network of nodes. Mocknodes represent the
  299. // hollow nodes that the test can listen and send on
  300. func setupNetwork(t *testing.T, opts testOptions) *reactorTestSuite {
  301. t.Helper()
  302. require.Greater(t, opts.TotalNodes, opts.MockNodes)
  303. if opts.BufferSize == 0 {
  304. opts.BufferSize = defaultBufferSize
  305. }
  306. networkOpts := p2ptest.NetworkOptions{
  307. NumNodes: opts.TotalNodes,
  308. BufferSize: opts.BufferSize,
  309. NodeOpts: p2ptest.NodeOptions{
  310. MaxPeers: opts.MaxPeers,
  311. MaxConnected: opts.MaxConnected,
  312. },
  313. }
  314. chBuf := opts.BufferSize
  315. realNodes := opts.TotalNodes - opts.MockNodes
  316. rts := &reactorTestSuite{
  317. logger: log.TestingLogger().With("testCase", t.Name()),
  318. network: p2ptest.MakeNetwork(t, networkOpts),
  319. reactors: make(map[types.NodeID]*pex.ReactorV2, realNodes),
  320. pexChannels: make(map[types.NodeID]*p2p.Channel, opts.TotalNodes),
  321. peerChans: make(map[types.NodeID]chan p2p.PeerUpdate, opts.TotalNodes),
  322. peerUpdates: make(map[types.NodeID]*p2p.PeerUpdates, opts.TotalNodes),
  323. total: opts.TotalNodes,
  324. opts: opts,
  325. }
  326. // NOTE: we don't assert that the channels get drained after stopping the
  327. // reactor
  328. rts.pexChannels = rts.network.MakeChannelsNoCleanup(
  329. t, pex.ChannelDescriptor(), new(proto.PexMessage), chBuf,
  330. )
  331. idx := 0
  332. for nodeID := range rts.network.Nodes {
  333. rts.peerChans[nodeID] = make(chan p2p.PeerUpdate, chBuf)
  334. rts.peerUpdates[nodeID] = p2p.NewPeerUpdates(rts.peerChans[nodeID], chBuf)
  335. rts.network.Nodes[nodeID].PeerManager.Register(rts.peerUpdates[nodeID])
  336. // the first nodes in the array are always mock nodes
  337. if idx < opts.MockNodes {
  338. rts.mocks = append(rts.mocks, nodeID)
  339. } else {
  340. rts.reactors[nodeID] = pex.NewReactorV2(
  341. rts.logger.With("nodeID", nodeID),
  342. rts.network.Nodes[nodeID].PeerManager,
  343. rts.pexChannels[nodeID],
  344. rts.peerUpdates[nodeID],
  345. )
  346. }
  347. rts.nodes = append(rts.nodes, nodeID)
  348. idx++
  349. }
  350. require.Len(t, rts.reactors, realNodes)
  351. t.Cleanup(func() {
  352. for nodeID, reactor := range rts.reactors {
  353. if reactor.IsRunning() {
  354. require.NoError(t, reactor.Stop())
  355. require.False(t, reactor.IsRunning())
  356. }
  357. rts.pexChannels[nodeID].Close()
  358. rts.peerUpdates[nodeID].Close()
  359. }
  360. for _, nodeID := range rts.mocks {
  361. rts.pexChannels[nodeID].Close()
  362. rts.peerUpdates[nodeID].Close()
  363. }
  364. })
  365. return rts
  366. }
  367. // starts up the pex reactors for each node
  368. func (r *reactorTestSuite) start(t *testing.T) {
  369. t.Helper()
  370. for _, reactor := range r.reactors {
  371. require.NoError(t, reactor.Start())
  372. require.True(t, reactor.IsRunning())
  373. }
  374. }
  375. func (r *reactorTestSuite) addNodes(t *testing.T, nodes int) {
  376. t.Helper()
  377. for i := 0; i < nodes; i++ {
  378. node := r.network.MakeNode(t, p2ptest.NodeOptions{
  379. MaxPeers: r.opts.MaxPeers,
  380. MaxConnected: r.opts.MaxConnected,
  381. })
  382. r.network.Nodes[node.NodeID] = node
  383. nodeID := node.NodeID
  384. r.pexChannels[nodeID] = node.MakeChannelNoCleanup(
  385. t, pex.ChannelDescriptor(), new(proto.PexMessage), r.opts.BufferSize,
  386. )
  387. r.peerChans[nodeID] = make(chan p2p.PeerUpdate, r.opts.BufferSize)
  388. r.peerUpdates[nodeID] = p2p.NewPeerUpdates(r.peerChans[nodeID], r.opts.BufferSize)
  389. r.network.Nodes[nodeID].PeerManager.Register(r.peerUpdates[nodeID])
  390. r.reactors[nodeID] = pex.NewReactorV2(
  391. r.logger.With("nodeID", nodeID),
  392. r.network.Nodes[nodeID].PeerManager,
  393. r.pexChannels[nodeID],
  394. r.peerUpdates[nodeID],
  395. )
  396. r.nodes = append(r.nodes, nodeID)
  397. r.total++
  398. }
  399. }
  400. func (r *reactorTestSuite) listenFor(
  401. t *testing.T,
  402. node types.NodeID,
  403. conditional func(msg p2p.Envelope) bool,
  404. assertion func(t *testing.T, msg p2p.Envelope) bool,
  405. waitPeriod time.Duration,
  406. ) {
  407. timesUp := time.After(waitPeriod)
  408. for {
  409. select {
  410. case envelope := <-r.pexChannels[node].In:
  411. if conditional(envelope) && assertion(t, envelope) {
  412. return
  413. }
  414. case <-timesUp:
  415. require.Fail(t, "timed out waiting for message",
  416. "node=%v, waitPeriod=%s", node, waitPeriod)
  417. }
  418. }
  419. }
  420. func (r *reactorTestSuite) listenForRequest(t *testing.T, fromNode, toNode int, waitPeriod time.Duration) {
  421. r.logger.Info("Listening for request", "from", fromNode, "to", toNode)
  422. to, from := r.checkNodePair(t, toNode, fromNode)
  423. conditional := func(msg p2p.Envelope) bool {
  424. _, ok := msg.Message.(*proto.PexRequestV2)
  425. return ok && msg.From == from
  426. }
  427. assertion := func(t *testing.T, msg p2p.Envelope) bool {
  428. require.Equal(t, &proto.PexRequestV2{}, msg.Message)
  429. return true
  430. }
  431. r.listenFor(t, to, conditional, assertion, waitPeriod)
  432. }
  433. func (r *reactorTestSuite) pingAndlistenForNAddresses(
  434. t *testing.T,
  435. fromNode, toNode int,
  436. waitPeriod time.Duration,
  437. addresses int,
  438. ) {
  439. r.logger.Info("Listening for addresses", "from", fromNode, "to", toNode)
  440. to, from := r.checkNodePair(t, toNode, fromNode)
  441. conditional := func(msg p2p.Envelope) bool {
  442. _, ok := msg.Message.(*proto.PexResponseV2)
  443. return ok && msg.From == from
  444. }
  445. assertion := func(t *testing.T, msg p2p.Envelope) bool {
  446. m, ok := msg.Message.(*proto.PexResponseV2)
  447. if !ok {
  448. require.Fail(t, "expected pex response v2")
  449. return true
  450. }
  451. // assert the same amount of addresses
  452. if len(m.Addresses) == addresses {
  453. return true
  454. }
  455. // if we didn't get the right length, we wait and send the
  456. // request again
  457. time.Sleep(300 * time.Millisecond)
  458. r.sendRequest(t, toNode, fromNode, true)
  459. return false
  460. }
  461. r.sendRequest(t, toNode, fromNode, true)
  462. r.listenFor(t, to, conditional, assertion, waitPeriod)
  463. }
  464. func (r *reactorTestSuite) listenForResponse(
  465. t *testing.T,
  466. fromNode, toNode int,
  467. waitPeriod time.Duration,
  468. addresses []proto.PexAddressV2,
  469. ) {
  470. r.logger.Info("Listening for response", "from", fromNode, "to", toNode)
  471. to, from := r.checkNodePair(t, toNode, fromNode)
  472. conditional := func(msg p2p.Envelope) bool {
  473. _, ok := msg.Message.(*proto.PexResponseV2)
  474. r.logger.Info("message", msg, "ok", ok)
  475. return ok && msg.From == from
  476. }
  477. assertion := func(t *testing.T, msg p2p.Envelope) bool {
  478. require.Equal(t, &proto.PexResponseV2{Addresses: addresses}, msg.Message)
  479. return true
  480. }
  481. r.listenFor(t, to, conditional, assertion, waitPeriod)
  482. }
  483. func (r *reactorTestSuite) listenForLegacyResponse(
  484. t *testing.T,
  485. fromNode, toNode int,
  486. waitPeriod time.Duration,
  487. addresses []proto.PexAddress,
  488. ) {
  489. r.logger.Info("Listening for response", "from", fromNode, "to", toNode)
  490. to, from := r.checkNodePair(t, toNode, fromNode)
  491. conditional := func(msg p2p.Envelope) bool {
  492. _, ok := msg.Message.(*proto.PexResponse)
  493. return ok && msg.From == from
  494. }
  495. assertion := func(t *testing.T, msg p2p.Envelope) bool {
  496. require.Equal(t, &proto.PexResponse{Addresses: addresses}, msg.Message)
  497. return true
  498. }
  499. r.listenFor(t, to, conditional, assertion, waitPeriod)
  500. }
  501. func (r *reactorTestSuite) listenForPeerUpdate(
  502. t *testing.T,
  503. onNode, withNode int,
  504. status p2p.PeerStatus,
  505. waitPeriod time.Duration,
  506. ) {
  507. on, with := r.checkNodePair(t, onNode, withNode)
  508. sub := r.network.Nodes[on].PeerManager.Subscribe()
  509. defer sub.Close()
  510. timesUp := time.After(waitPeriod)
  511. for {
  512. select {
  513. case peerUpdate := <-sub.Updates():
  514. if peerUpdate.NodeID == with {
  515. require.Equal(t, status, peerUpdate.Status)
  516. return
  517. }
  518. case <-timesUp:
  519. require.Fail(t, "timed out waiting for peer status", "%v with status %v",
  520. with, status)
  521. return
  522. }
  523. }
  524. }
  525. func (r *reactorTestSuite) getV2AddressesFor(nodes []int) []proto.PexAddressV2 {
  526. addresses := make([]proto.PexAddressV2, len(nodes))
  527. for idx, node := range nodes {
  528. nodeID := r.nodes[node]
  529. addresses[idx] = proto.PexAddressV2{
  530. URL: r.network.Nodes[nodeID].NodeAddress.String(),
  531. }
  532. }
  533. return addresses
  534. }
  535. func (r *reactorTestSuite) getAddressesFor(t *testing.T, nodes []int) []proto.PexAddress {
  536. addresses := make([]proto.PexAddress, len(nodes))
  537. for idx, node := range nodes {
  538. nodeID := r.nodes[node]
  539. nodeAddrs := r.network.Nodes[nodeID].NodeAddress
  540. endpoints, err := nodeAddrs.Resolve(context.Background())
  541. require.NoError(t, err)
  542. require.Len(t, endpoints, 1)
  543. addresses[idx] = proto.PexAddress{
  544. ID: string(nodeAddrs.NodeID),
  545. IP: endpoints[0].IP.String(),
  546. Port: uint32(endpoints[0].Port),
  547. }
  548. }
  549. return addresses
  550. }
  551. func (r *reactorTestSuite) sendRequest(t *testing.T, fromNode, toNode int, v2 bool) {
  552. to, from := r.checkNodePair(t, toNode, fromNode)
  553. if v2 {
  554. r.pexChannels[from].Out <- p2p.Envelope{
  555. To: to,
  556. Message: &proto.PexRequestV2{},
  557. }
  558. } else {
  559. r.pexChannels[from].Out <- p2p.Envelope{
  560. To: to,
  561. Message: &proto.PexRequest{},
  562. }
  563. }
  564. }
  565. func (r *reactorTestSuite) sendResponse(
  566. t *testing.T,
  567. fromNode, toNode int,
  568. withNodes []int,
  569. v2 bool,
  570. ) {
  571. from, to := r.checkNodePair(t, fromNode, toNode)
  572. if v2 {
  573. addrs := r.getV2AddressesFor(withNodes)
  574. r.pexChannels[from].Out <- p2p.Envelope{
  575. To: to,
  576. Message: &proto.PexResponseV2{
  577. Addresses: addrs,
  578. },
  579. }
  580. } else {
  581. addrs := r.getAddressesFor(t, withNodes)
  582. r.pexChannels[from].Out <- p2p.Envelope{
  583. To: to,
  584. Message: &proto.PexResponse{
  585. Addresses: addrs,
  586. },
  587. }
  588. }
  589. }
  590. func (r *reactorTestSuite) requireNumberOfPeers(
  591. t *testing.T,
  592. nodeIndex, numPeers int,
  593. waitPeriod time.Duration,
  594. ) {
  595. t.Helper()
  596. require.Eventuallyf(t, func() bool {
  597. actualNumPeers := len(r.network.Nodes[r.nodes[nodeIndex]].PeerManager.Peers())
  598. return actualNumPeers >= numPeers
  599. }, waitPeriod, checkFrequency, "peer failed to connect with the asserted amount of peers "+
  600. "index=%d, node=%q, waitPeriod=%s expected=%d actual=%d",
  601. nodeIndex, r.nodes[nodeIndex], waitPeriod, numPeers,
  602. len(r.network.Nodes[r.nodes[nodeIndex]].PeerManager.Peers()),
  603. )
  604. }
  605. func (r *reactorTestSuite) connectAll(t *testing.T) {
  606. r.connectN(t, r.total-1)
  607. }
  608. // connects all nodes with n other nodes
  609. func (r *reactorTestSuite) connectN(t *testing.T, n int) {
  610. if n >= r.total {
  611. require.Fail(t, "connectN: n must be less than the size of the network - 1")
  612. }
  613. for i := 0; i < r.total; i++ {
  614. for j := 0; j < n; j++ {
  615. r.connectPeers(t, i, (i+j+1)%r.total)
  616. }
  617. }
  618. }
  619. // connects node1 to node2
  620. func (r *reactorTestSuite) connectPeers(t *testing.T, sourceNode, targetNode int) {
  621. t.Helper()
  622. node1, node2 := r.checkNodePair(t, sourceNode, targetNode)
  623. r.logger.Info("connecting peers", "sourceNode", sourceNode, "targetNode", targetNode)
  624. n1 := r.network.Nodes[node1]
  625. if n1 == nil {
  626. require.Fail(t, "connectPeers: source node %v is not part of the testnet", node1)
  627. return
  628. }
  629. n2 := r.network.Nodes[node2]
  630. if n2 == nil {
  631. require.Fail(t, "connectPeers: target node %v is not part of the testnet", node2)
  632. return
  633. }
  634. sourceSub := n1.PeerManager.Subscribe()
  635. defer sourceSub.Close()
  636. targetSub := n2.PeerManager.Subscribe()
  637. defer targetSub.Close()
  638. sourceAddress := n1.NodeAddress
  639. r.logger.Debug("source address", "address", sourceAddress)
  640. targetAddress := n2.NodeAddress
  641. r.logger.Debug("target address", "address", targetAddress)
  642. added, err := n1.PeerManager.Add(targetAddress)
  643. require.NoError(t, err)
  644. if !added {
  645. r.logger.Debug("nodes already know about one another",
  646. "sourceNode", sourceNode, "targetNode", targetNode)
  647. return
  648. }
  649. select {
  650. case peerUpdate := <-targetSub.Updates():
  651. require.Equal(t, p2p.PeerUpdate{
  652. NodeID: node1,
  653. Status: p2p.PeerStatusUp,
  654. }, peerUpdate)
  655. r.logger.Debug("target connected with source")
  656. case <-time.After(2 * time.Second):
  657. require.Fail(t, "timed out waiting for peer", "%v accepting %v",
  658. targetNode, sourceNode)
  659. }
  660. select {
  661. case peerUpdate := <-sourceSub.Updates():
  662. require.Equal(t, p2p.PeerUpdate{
  663. NodeID: node2,
  664. Status: p2p.PeerStatusUp,
  665. }, peerUpdate)
  666. r.logger.Debug("source connected with target")
  667. case <-time.After(2 * time.Second):
  668. require.Fail(t, "timed out waiting for peer", "%v dialing %v",
  669. sourceNode, targetNode)
  670. }
  671. added, err = n2.PeerManager.Add(sourceAddress)
  672. require.NoError(t, err)
  673. require.True(t, added)
  674. }
  675. // nolint: unused
  676. func (r *reactorTestSuite) pexAddresses(t *testing.T, nodeIndices []int) []proto.PexAddress {
  677. var addresses []proto.PexAddress
  678. for _, i := range nodeIndices {
  679. if i < len(r.nodes) {
  680. require.Fail(t, "index for pex address is greater than number of nodes")
  681. }
  682. nodeAddrs := r.network.Nodes[r.nodes[i]].NodeAddress
  683. ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
  684. endpoints, err := nodeAddrs.Resolve(ctx)
  685. cancel()
  686. require.NoError(t, err)
  687. for _, endpoint := range endpoints {
  688. if endpoint.IP != nil {
  689. addresses = append(addresses, proto.PexAddress{
  690. ID: string(nodeAddrs.NodeID),
  691. IP: endpoint.IP.String(),
  692. Port: uint32(endpoint.Port),
  693. })
  694. }
  695. }
  696. }
  697. return addresses
  698. }
  699. func (r *reactorTestSuite) checkNodePair(t *testing.T, first, second int) (types.NodeID, types.NodeID) {
  700. require.NotEqual(t, first, second)
  701. require.Less(t, first, r.total)
  702. require.Less(t, second, r.total)
  703. return r.nodes[first], r.nodes[second]
  704. }
  705. func (r *reactorTestSuite) addAddresses(t *testing.T, node int, addrs []int) {
  706. peerManager := r.network.Nodes[r.nodes[node]].PeerManager
  707. for _, addr := range addrs {
  708. require.Less(t, addr, r.total)
  709. address := r.network.Nodes[r.nodes[addr]].NodeAddress
  710. added, err := peerManager.Add(address)
  711. require.NoError(t, err)
  712. require.True(t, added)
  713. }
  714. }
  715. func newNodeID(t *testing.T, id string) types.NodeID {
  716. nodeID, err := types.NewNodeID(strings.Repeat(id, 2*types.NodeIDByteLength))
  717. require.NoError(t, err)
  718. return nodeID
  719. }
  720. func randomNodeID(t *testing.T) types.NodeID {
  721. return types.NodeIDFromPubKey(ed25519.GenPrivKey().PubKey())
  722. }