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.

641 lines
18 KiB

  1. package p2p_test
  2. import (
  3. "context"
  4. "io"
  5. "net"
  6. "testing"
  7. "time"
  8. "github.com/fortytw2/leaktest"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. "github.com/tendermint/tendermint/crypto/ed25519"
  12. "github.com/tendermint/tendermint/libs/bytes"
  13. "github.com/tendermint/tendermint/p2p"
  14. )
  15. // transportFactory is used to set up transports for tests.
  16. type transportFactory func(t *testing.T) p2p.Transport
  17. // testTransports is a registry of transport factories for withTransports().
  18. var testTransports = map[string]transportFactory{}
  19. // withTransports is a test helper that runs a test against all transports
  20. // registered in testTransports.
  21. func withTransports(t *testing.T, tester func(*testing.T, transportFactory)) {
  22. t.Helper()
  23. for name, transportFactory := range testTransports {
  24. transportFactory := transportFactory
  25. t.Run(name, func(t *testing.T) {
  26. t.Cleanup(leaktest.Check(t))
  27. tester(t, transportFactory)
  28. })
  29. }
  30. }
  31. func TestTransport_AcceptClose(t *testing.T) {
  32. // Just test accept unblock on close, happy path is tested widely elsewhere.
  33. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  34. a := makeTransport(t)
  35. // In-progress Accept should error on concurrent close.
  36. errCh := make(chan error, 1)
  37. go func() {
  38. time.Sleep(200 * time.Millisecond)
  39. errCh <- a.Close()
  40. }()
  41. _, err := a.Accept()
  42. require.Error(t, err)
  43. require.Equal(t, io.EOF, err)
  44. require.NoError(t, <-errCh)
  45. // Closed transport should return error immediately.
  46. _, err = a.Accept()
  47. require.Error(t, err)
  48. require.Equal(t, io.EOF, err)
  49. })
  50. }
  51. func TestTransport_DialEndpoints(t *testing.T) {
  52. ipTestCases := []struct {
  53. ip net.IP
  54. ok bool
  55. }{
  56. {net.IPv4zero, true},
  57. {net.IPv6zero, true},
  58. {nil, false},
  59. {net.IPv4bcast, false},
  60. {net.IPv4allsys, false},
  61. {[]byte{1, 2, 3}, false},
  62. {[]byte{1, 2, 3, 4, 5}, false},
  63. }
  64. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  65. a := makeTransport(t)
  66. endpoints := a.Endpoints()
  67. require.NotEmpty(t, endpoints)
  68. endpoint := endpoints[0]
  69. // Spawn a goroutine to simply accept any connections until closed.
  70. go func() {
  71. for {
  72. conn, err := a.Accept()
  73. if err != nil {
  74. return
  75. }
  76. _ = conn.Close()
  77. }
  78. }()
  79. // Dialing self should work.
  80. conn, err := a.Dial(ctx, endpoint)
  81. require.NoError(t, err)
  82. require.NoError(t, conn.Close())
  83. // Dialing empty endpoint should error.
  84. _, err = a.Dial(ctx, p2p.Endpoint{})
  85. require.Error(t, err)
  86. // Dialing without protocol should error.
  87. noProtocol := endpoint
  88. noProtocol.Protocol = ""
  89. _, err = a.Dial(ctx, noProtocol)
  90. require.Error(t, err)
  91. // Dialing with invalid protocol should error.
  92. fooProtocol := endpoint
  93. fooProtocol.Protocol = "foo"
  94. _, err = a.Dial(ctx, fooProtocol)
  95. require.Error(t, err)
  96. // Tests for networked endpoints (with IP).
  97. if len(endpoint.IP) > 0 && endpoint.Protocol != p2p.MemoryProtocol {
  98. for _, tc := range ipTestCases {
  99. tc := tc
  100. t.Run(tc.ip.String(), func(t *testing.T) {
  101. e := endpoint
  102. e.IP = tc.ip
  103. conn, err := a.Dial(ctx, e)
  104. if tc.ok {
  105. require.NoError(t, conn.Close())
  106. require.NoError(t, err)
  107. } else {
  108. require.Error(t, err, "endpoint=%s", e)
  109. }
  110. })
  111. }
  112. // Non-networked endpoints should error.
  113. noIP := endpoint
  114. noIP.IP = nil
  115. noIP.Port = 0
  116. noIP.Path = "foo"
  117. _, err := a.Dial(ctx, noIP)
  118. require.Error(t, err)
  119. } else {
  120. // Tests for non-networked endpoints (no IP).
  121. noPath := endpoint
  122. noPath.Path = ""
  123. _, err = a.Dial(ctx, noPath)
  124. require.Error(t, err)
  125. }
  126. })
  127. }
  128. func TestTransport_Dial(t *testing.T) {
  129. // Most just tests dial failures, happy path is tested widely elsewhere.
  130. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  131. a := makeTransport(t)
  132. b := makeTransport(t)
  133. require.NotEmpty(t, a.Endpoints())
  134. require.NotEmpty(t, b.Endpoints())
  135. aEndpoint := a.Endpoints()[0]
  136. bEndpoint := b.Endpoints()[0]
  137. // Context cancellation should error. We can't test timeouts since we'd
  138. // need a non-responsive endpoint.
  139. cancelCtx, cancel := context.WithCancel(ctx)
  140. cancel()
  141. _, err := a.Dial(cancelCtx, bEndpoint)
  142. require.Error(t, err)
  143. require.Equal(t, err, context.Canceled)
  144. // Unavailable endpoint should error.
  145. err = b.Close()
  146. require.NoError(t, err)
  147. _, err = a.Dial(ctx, bEndpoint)
  148. require.Error(t, err)
  149. // Dialing from a closed transport should still work.
  150. errCh := make(chan error, 1)
  151. go func() {
  152. conn, err := a.Accept()
  153. if err == nil {
  154. _ = conn.Close()
  155. }
  156. errCh <- err
  157. }()
  158. conn, err := b.Dial(ctx, aEndpoint)
  159. require.NoError(t, err)
  160. require.NoError(t, conn.Close())
  161. require.NoError(t, <-errCh)
  162. })
  163. }
  164. func TestTransport_Endpoints(t *testing.T) {
  165. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  166. a := makeTransport(t)
  167. b := makeTransport(t)
  168. // Both transports return valid and different endpoints.
  169. aEndpoints := a.Endpoints()
  170. bEndpoints := b.Endpoints()
  171. require.NotEmpty(t, aEndpoints)
  172. require.NotEmpty(t, bEndpoints)
  173. require.NotEqual(t, aEndpoints, bEndpoints)
  174. for _, endpoint := range append(aEndpoints, bEndpoints...) {
  175. err := endpoint.Validate()
  176. require.NoError(t, err, "invalid endpoint %q", endpoint)
  177. }
  178. // When closed, the transport should no longer return any endpoints.
  179. err := a.Close()
  180. require.NoError(t, err)
  181. require.Empty(t, a.Endpoints())
  182. require.NotEmpty(t, b.Endpoints())
  183. })
  184. }
  185. func TestTransport_Protocols(t *testing.T) {
  186. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  187. a := makeTransport(t)
  188. protocols := a.Protocols()
  189. endpoints := a.Endpoints()
  190. require.NotEmpty(t, protocols)
  191. require.NotEmpty(t, endpoints)
  192. for _, endpoint := range endpoints {
  193. require.Contains(t, protocols, endpoint.Protocol)
  194. }
  195. })
  196. }
  197. func TestTransport_String(t *testing.T) {
  198. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  199. a := makeTransport(t)
  200. require.NotEmpty(t, a.String())
  201. })
  202. }
  203. func TestConnection_Handshake(t *testing.T) {
  204. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  205. a := makeTransport(t)
  206. b := makeTransport(t)
  207. ab, ba := dialAccept(t, a, b)
  208. // A handshake should pass the given keys and NodeInfo.
  209. aKey := ed25519.GenPrivKey()
  210. aInfo := p2p.NodeInfo{
  211. NodeID: p2p.NodeIDFromPubKey(aKey.PubKey()),
  212. ProtocolVersion: p2p.NewProtocolVersion(1, 2, 3),
  213. ListenAddr: "listenaddr",
  214. Network: "network",
  215. Version: "1.2.3",
  216. Channels: bytes.HexBytes([]byte{0xf0, 0x0f}),
  217. Moniker: "moniker",
  218. Other: p2p.NodeInfoOther{
  219. TxIndex: "txindex",
  220. RPCAddress: "rpc.domain.com",
  221. },
  222. }
  223. bKey := ed25519.GenPrivKey()
  224. bInfo := p2p.NodeInfo{NodeID: p2p.NodeIDFromPubKey(bKey.PubKey())}
  225. errCh := make(chan error, 1)
  226. go func() {
  227. // Must use assert due to goroutine.
  228. peerInfo, peerKey, err := ba.Handshake(ctx, bInfo, bKey)
  229. if err == nil {
  230. assert.Equal(t, aInfo, peerInfo)
  231. assert.Equal(t, aKey.PubKey(), peerKey)
  232. }
  233. errCh <- err
  234. }()
  235. peerInfo, peerKey, err := ab.Handshake(ctx, aInfo, aKey)
  236. require.NoError(t, err)
  237. require.Equal(t, bInfo, peerInfo)
  238. require.Equal(t, bKey.PubKey(), peerKey)
  239. require.NoError(t, <-errCh)
  240. })
  241. }
  242. func TestConnection_HandshakeCancel(t *testing.T) {
  243. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  244. a := makeTransport(t)
  245. b := makeTransport(t)
  246. // Handshake should error on context cancellation.
  247. ab, ba := dialAccept(t, a, b)
  248. timeoutCtx, cancel := context.WithTimeout(ctx, 1*time.Minute)
  249. cancel()
  250. _, _, err := ab.Handshake(timeoutCtx, p2p.NodeInfo{}, ed25519.GenPrivKey())
  251. require.Error(t, err)
  252. require.Equal(t, context.Canceled, err)
  253. _ = ab.Close()
  254. _ = ba.Close()
  255. // Handshake should error on context timeout.
  256. ab, ba = dialAccept(t, a, b)
  257. timeoutCtx, cancel = context.WithTimeout(ctx, 200*time.Millisecond)
  258. defer cancel()
  259. _, _, err = ab.Handshake(timeoutCtx, p2p.NodeInfo{}, ed25519.GenPrivKey())
  260. require.Error(t, err)
  261. require.Equal(t, context.DeadlineExceeded, err)
  262. _ = ab.Close()
  263. _ = ba.Close()
  264. })
  265. }
  266. func TestConnection_FlushClose(t *testing.T) {
  267. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  268. a := makeTransport(t)
  269. b := makeTransport(t)
  270. ab, _ := dialAcceptHandshake(t, a, b)
  271. // FIXME: FlushClose should be removed (and replaced by separate Flush
  272. // and Close calls if necessary). We can't reliably test it, so we just
  273. // make sure it closes both ends and that it's idempotent.
  274. err := ab.FlushClose()
  275. require.NoError(t, err)
  276. _, _, err = ab.ReceiveMessage()
  277. require.Error(t, err)
  278. require.Equal(t, io.EOF, err)
  279. _, err = ab.SendMessage(chID, []byte("closed"))
  280. require.Error(t, err)
  281. require.Equal(t, io.EOF, err)
  282. err = ab.FlushClose()
  283. require.NoError(t, err)
  284. })
  285. }
  286. func TestConnection_LocalRemoteEndpoint(t *testing.T) {
  287. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  288. a := makeTransport(t)
  289. b := makeTransport(t)
  290. ab, ba := dialAcceptHandshake(t, a, b)
  291. // Local and remote connection endpoints correspond to each other.
  292. require.NotEmpty(t, ab.LocalEndpoint())
  293. require.NotEmpty(t, ba.LocalEndpoint())
  294. require.Equal(t, ab.LocalEndpoint(), ba.RemoteEndpoint())
  295. require.Equal(t, ab.RemoteEndpoint(), ba.LocalEndpoint())
  296. })
  297. }
  298. func TestConnection_SendReceive(t *testing.T) {
  299. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  300. a := makeTransport(t)
  301. b := makeTransport(t)
  302. ab, ba := dialAcceptHandshake(t, a, b)
  303. // Can send and receive a to b.
  304. ok, err := ab.SendMessage(chID, []byte("foo"))
  305. require.NoError(t, err)
  306. require.True(t, ok)
  307. ch, msg, err := ba.ReceiveMessage()
  308. require.NoError(t, err)
  309. require.Equal(t, []byte("foo"), msg)
  310. require.Equal(t, chID, ch)
  311. // Can send and receive b to a.
  312. _, err = ba.SendMessage(chID, []byte("bar"))
  313. require.NoError(t, err)
  314. _, msg, err = ab.ReceiveMessage()
  315. require.NoError(t, err)
  316. require.Equal(t, []byte("bar"), msg)
  317. // TrySendMessage also works.
  318. ok, err = ba.TrySendMessage(chID, []byte("try"))
  319. require.NoError(t, err)
  320. require.True(t, ok)
  321. ch, msg, err = ab.ReceiveMessage()
  322. require.NoError(t, err)
  323. require.Equal(t, []byte("try"), msg)
  324. require.Equal(t, chID, ch)
  325. // Connections should still be active after closing the transports.
  326. err = a.Close()
  327. require.NoError(t, err)
  328. err = b.Close()
  329. require.NoError(t, err)
  330. _, err = ab.SendMessage(chID, []byte("still here"))
  331. require.NoError(t, err)
  332. ch, msg, err = ba.ReceiveMessage()
  333. require.NoError(t, err)
  334. require.Equal(t, chID, ch)
  335. require.Equal(t, []byte("still here"), msg)
  336. // Close one side of the connection. Both sides should then error
  337. // with io.EOF when trying to send or receive.
  338. err = ba.Close()
  339. require.NoError(t, err)
  340. _, _, err = ab.ReceiveMessage()
  341. require.Error(t, err)
  342. require.Equal(t, io.EOF, err)
  343. _, err = ab.SendMessage(chID, []byte("closed"))
  344. require.Error(t, err)
  345. require.Equal(t, io.EOF, err)
  346. _, _, err = ba.ReceiveMessage()
  347. require.Error(t, err)
  348. require.Equal(t, io.EOF, err)
  349. _, err = ba.SendMessage(chID, []byte("closed"))
  350. require.Error(t, err)
  351. require.Equal(t, io.EOF, err)
  352. })
  353. }
  354. func TestConnection_Status(t *testing.T) {
  355. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  356. a := makeTransport(t)
  357. b := makeTransport(t)
  358. ab, _ := dialAcceptHandshake(t, a, b)
  359. // FIXME: This isn't implemented in all transports, so for now we just
  360. // check that it doesn't panic, which isn't really much of a test.
  361. ab.Status()
  362. })
  363. }
  364. func TestConnection_String(t *testing.T) {
  365. withTransports(t, func(t *testing.T, makeTransport transportFactory) {
  366. a := makeTransport(t)
  367. b := makeTransport(t)
  368. ab, _ := dialAccept(t, a, b)
  369. require.NotEmpty(t, ab.String())
  370. })
  371. }
  372. func TestEndpoint_NodeAddress(t *testing.T) {
  373. var (
  374. ip4 = []byte{1, 2, 3, 4}
  375. ip4in6 = net.IPv4(1, 2, 3, 4)
  376. ip6 = []byte{0xb1, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
  377. id = p2p.NodeID("00112233445566778899aabbccddeeff00112233")
  378. )
  379. testcases := []struct {
  380. endpoint p2p.Endpoint
  381. expect p2p.NodeAddress
  382. }{
  383. // Valid endpoints.
  384. {
  385. p2p.Endpoint{Protocol: "tcp", IP: ip4, Port: 8080, Path: "path"},
  386. p2p.NodeAddress{Protocol: "tcp", Hostname: "1.2.3.4", Port: 8080, Path: "path"},
  387. },
  388. {
  389. p2p.Endpoint{Protocol: "tcp", IP: ip4in6, Port: 8080, Path: "path"},
  390. p2p.NodeAddress{Protocol: "tcp", Hostname: "1.2.3.4", Port: 8080, Path: "path"},
  391. },
  392. {
  393. p2p.Endpoint{Protocol: "tcp", IP: ip6, Port: 8080, Path: "path"},
  394. p2p.NodeAddress{Protocol: "tcp", Hostname: "b10c::1", Port: 8080, Path: "path"},
  395. },
  396. {
  397. p2p.Endpoint{Protocol: "memory", Path: "foo"},
  398. p2p.NodeAddress{Protocol: "memory", Path: "foo"},
  399. },
  400. {
  401. p2p.Endpoint{Protocol: "memory", Path: string(id)},
  402. p2p.NodeAddress{Protocol: "memory", Path: string(id)},
  403. },
  404. // Partial (invalid) endpoints.
  405. {p2p.Endpoint{}, p2p.NodeAddress{}},
  406. {p2p.Endpoint{Protocol: "tcp"}, p2p.NodeAddress{Protocol: "tcp"}},
  407. {p2p.Endpoint{IP: net.IPv4(1, 2, 3, 4)}, p2p.NodeAddress{Hostname: "1.2.3.4"}},
  408. {p2p.Endpoint{Port: 8080}, p2p.NodeAddress{}},
  409. {p2p.Endpoint{Path: "path"}, p2p.NodeAddress{Path: "path"}},
  410. }
  411. for _, tc := range testcases {
  412. tc := tc
  413. t.Run(tc.endpoint.String(), func(t *testing.T) {
  414. // Without NodeID.
  415. expect := tc.expect
  416. require.Equal(t, expect, tc.endpoint.NodeAddress(""))
  417. // With NodeID.
  418. expect.NodeID = id
  419. require.Equal(t, expect, tc.endpoint.NodeAddress(expect.NodeID))
  420. })
  421. }
  422. }
  423. func TestEndpoint_String(t *testing.T) {
  424. var (
  425. ip4 = []byte{1, 2, 3, 4}
  426. ip4in6 = net.IPv4(1, 2, 3, 4)
  427. ip6 = []byte{0xb1, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
  428. nodeID = p2p.NodeID("00112233445566778899aabbccddeeff00112233")
  429. )
  430. testcases := []struct {
  431. endpoint p2p.Endpoint
  432. expect string
  433. }{
  434. // Non-networked endpoints.
  435. {p2p.Endpoint{Protocol: "memory", Path: string(nodeID)}, "memory:" + string(nodeID)},
  436. {p2p.Endpoint{Protocol: "file", Path: "foo"}, "file:///foo"},
  437. {p2p.Endpoint{Protocol: "file", Path: "👋"}, "file:///%F0%9F%91%8B"},
  438. // IPv4 endpoints.
  439. {p2p.Endpoint{Protocol: "tcp", IP: ip4}, "tcp://1.2.3.4"},
  440. {p2p.Endpoint{Protocol: "tcp", IP: ip4in6}, "tcp://1.2.3.4"},
  441. {p2p.Endpoint{Protocol: "tcp", IP: ip4, Port: 8080}, "tcp://1.2.3.4:8080"},
  442. {p2p.Endpoint{Protocol: "tcp", IP: ip4, Port: 8080, Path: "/path"}, "tcp://1.2.3.4:8080/path"},
  443. {p2p.Endpoint{Protocol: "tcp", IP: ip4, Path: "path/👋"}, "tcp://1.2.3.4/path/%F0%9F%91%8B"},
  444. // IPv6 endpoints.
  445. {p2p.Endpoint{Protocol: "tcp", IP: ip6}, "tcp://b10c::1"},
  446. {p2p.Endpoint{Protocol: "tcp", IP: ip6, Port: 8080}, "tcp://[b10c::1]:8080"},
  447. {p2p.Endpoint{Protocol: "tcp", IP: ip6, Port: 8080, Path: "/path"}, "tcp://[b10c::1]:8080/path"},
  448. {p2p.Endpoint{Protocol: "tcp", IP: ip6, Path: "path/👋"}, "tcp://b10c::1/path/%F0%9F%91%8B"},
  449. // Partial (invalid) endpoints.
  450. {p2p.Endpoint{}, ""},
  451. {p2p.Endpoint{Protocol: "tcp"}, "tcp:"},
  452. {p2p.Endpoint{IP: []byte{1, 2, 3, 4}}, "1.2.3.4"},
  453. {p2p.Endpoint{IP: []byte{0xb1, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}}, "b10c::1"},
  454. {p2p.Endpoint{Port: 8080}, ""},
  455. {p2p.Endpoint{Path: "foo"}, "/foo"},
  456. }
  457. for _, tc := range testcases {
  458. tc := tc
  459. t.Run(tc.expect, func(t *testing.T) {
  460. require.Equal(t, tc.expect, tc.endpoint.String())
  461. })
  462. }
  463. }
  464. func TestEndpoint_Validate(t *testing.T) {
  465. var (
  466. ip4 = []byte{1, 2, 3, 4}
  467. ip4in6 = net.IPv4(1, 2, 3, 4)
  468. ip6 = []byte{0xb1, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
  469. )
  470. testcases := []struct {
  471. endpoint p2p.Endpoint
  472. expectValid bool
  473. }{
  474. // Valid endpoints.
  475. {p2p.Endpoint{Protocol: "tcp", IP: ip4}, true},
  476. {p2p.Endpoint{Protocol: "tcp", IP: ip4in6}, true},
  477. {p2p.Endpoint{Protocol: "tcp", IP: ip6}, true},
  478. {p2p.Endpoint{Protocol: "tcp", IP: ip4, Port: 8008}, true},
  479. {p2p.Endpoint{Protocol: "tcp", IP: ip4, Port: 8080, Path: "path"}, true},
  480. {p2p.Endpoint{Protocol: "memory", Path: "path"}, true},
  481. // Invalid endpoints.
  482. {p2p.Endpoint{}, false},
  483. {p2p.Endpoint{IP: ip4}, false},
  484. {p2p.Endpoint{Protocol: "tcp"}, false},
  485. {p2p.Endpoint{Protocol: "tcp", IP: []byte{1, 2, 3}}, false},
  486. {p2p.Endpoint{Protocol: "tcp", Port: 8080, Path: "path"}, false},
  487. }
  488. for _, tc := range testcases {
  489. tc := tc
  490. t.Run(tc.endpoint.String(), func(t *testing.T) {
  491. err := tc.endpoint.Validate()
  492. if tc.expectValid {
  493. require.NoError(t, err)
  494. } else {
  495. require.Error(t, err)
  496. }
  497. })
  498. }
  499. }
  500. // dialAccept is a helper that dials b from a and returns both sides of the
  501. // connection.
  502. func dialAccept(t *testing.T, a, b p2p.Transport) (p2p.Connection, p2p.Connection) {
  503. t.Helper()
  504. endpoints := b.Endpoints()
  505. require.NotEmpty(t, endpoints, "peer not listening on any endpoints")
  506. ctx, cancel := context.WithTimeout(ctx, time.Second)
  507. defer cancel()
  508. acceptCh := make(chan p2p.Connection, 1)
  509. errCh := make(chan error, 1)
  510. go func() {
  511. conn, err := b.Accept()
  512. errCh <- err
  513. acceptCh <- conn
  514. }()
  515. dialConn, err := a.Dial(ctx, endpoints[0])
  516. require.NoError(t, err)
  517. acceptConn := <-acceptCh
  518. require.NoError(t, <-errCh)
  519. t.Cleanup(func() {
  520. _ = dialConn.Close()
  521. _ = acceptConn.Close()
  522. })
  523. return dialConn, acceptConn
  524. }
  525. // dialAcceptHandshake is a helper that dials and handshakes b from a and
  526. // returns both sides of the connection.
  527. func dialAcceptHandshake(t *testing.T, a, b p2p.Transport) (p2p.Connection, p2p.Connection) {
  528. t.Helper()
  529. ab, ba := dialAccept(t, a, b)
  530. ctx, cancel := context.WithTimeout(ctx, time.Second)
  531. defer cancel()
  532. errCh := make(chan error, 1)
  533. go func() {
  534. privKey := ed25519.GenPrivKey()
  535. nodeInfo := p2p.NodeInfo{NodeID: p2p.NodeIDFromPubKey(privKey.PubKey())}
  536. _, _, err := ba.Handshake(ctx, nodeInfo, privKey)
  537. errCh <- err
  538. }()
  539. privKey := ed25519.GenPrivKey()
  540. nodeInfo := p2p.NodeInfo{NodeID: p2p.NodeIDFromPubKey(privKey.PubKey())}
  541. _, _, err := ab.Handshake(ctx, nodeInfo, privKey)
  542. require.NoError(t, err)
  543. timer := time.NewTimer(2 * time.Second)
  544. defer timer.Stop()
  545. select {
  546. case err := <-errCh:
  547. require.NoError(t, err)
  548. case <-timer.C:
  549. require.Fail(t, "handshake timed out")
  550. }
  551. return ab, ba
  552. }