Skip to content

Commit 089835e

Browse files
authored
fix: avoid sync callback in async functions (libp2p#297)
* fix: avoid sync callback in async functions * test: add error check * refactor: clean up async usage * chore: clean up * refactor: remove async waterfall usage on identify * chore: fix linting
1 parent b29679d commit 089835e

File tree

3 files changed

+76
-26
lines changed

3 files changed

+76
-26
lines changed

src/connection/manager.js

+24-25
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
const identify = require('libp2p-identify')
44
const multistream = require('multistream-select')
5-
const waterfall = require('async/waterfall')
65
const debug = require('debug')
76
const log = debug('libp2p:switch:conn-manager')
87
const once = require('once')
98
const ConnectionFSM = require('../connection')
9+
const { msHandle, msSelect, identifyDialer } = require('../utils')
1010

1111
const Circuit = require('libp2p-circuit')
1212

@@ -136,34 +136,33 @@ class ConnectionManager {
136136
}
137137

138138
// overload peerInfo to use Identify instead
139-
conn.getPeerInfo = (callback) => {
139+
conn.getPeerInfo = async (callback) => {
140140
const conn = muxedConn.newStream()
141141
const ms = new multistream.Dialer()
142142
callback = once(callback)
143143

144-
waterfall([
145-
(cb) => ms.handle(conn, cb),
146-
(cb) => ms.select(identify.multicodec, cb),
147-
// run identify and verify the peer has the same info from crypto
148-
(conn, cb) => identify.dialer(conn, cryptoPI, cb),
149-
(peerInfo, observedAddrs, cb) => {
150-
observedAddrs.forEach((oa) => {
151-
this.switch._peerInfo.multiaddrs.addSafe(oa)
152-
})
153-
cb(null, peerInfo)
154-
}
155-
], (err, peerInfo) => {
156-
if (err) {
157-
return muxedConn.end(() => {
158-
callback(err, null)
159-
})
160-
}
161-
162-
if (peerInfo) {
163-
conn.setPeerInfo(peerInfo)
164-
}
165-
callback(err, peerInfo)
166-
})
144+
let results
145+
try {
146+
await msHandle(ms, conn)
147+
const msConn = await msSelect(ms, identify.multicodec)
148+
results = await identifyDialer(msConn, cryptoPI)
149+
} catch (err) {
150+
return muxedConn.end(() => {
151+
callback(err, null)
152+
})
153+
}
154+
155+
const { peerInfo, observedAddrs } = results
156+
157+
for (var i = 0; i < observedAddrs.length; i++) {
158+
var addr = observedAddrs[i]
159+
this.switch._peerInfo.multiaddrs.addSafe(addr)
160+
}
161+
162+
if (peerInfo) {
163+
conn.setPeerInfo(peerInfo)
164+
}
165+
callback(null, peerInfo)
167166
}
168167

169168
conn.getPeerInfo((err, peerInfo) => {

src/utils.js

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
'use strict'
2+
3+
const Identify = require('libp2p-identify')
4+
5+
/**
6+
* For a given multistream, registers to handle the given connection
7+
* @param {MultistreamDialer} multistream
8+
* @param {Connection} connection
9+
* @returns {Promise}
10+
*/
11+
module.exports.msHandle = (multistream, connection) => {
12+
return new Promise((resolve, reject) => {
13+
multistream.handle(connection, (err) => {
14+
if (err) return reject(err)
15+
resolve()
16+
})
17+
})
18+
}
19+
20+
/**
21+
* For a given multistream, selects the given protocol
22+
* @param {MultistreamDialer} multistream
23+
* @param {string} protocol
24+
* @returns {Promise} Resolves the selected Connection
25+
*/
26+
module.exports.msSelect = (multistream, protocol) => {
27+
return new Promise((resolve, reject) => {
28+
multistream.select(protocol, (err, connection) => {
29+
if (err) return reject(err)
30+
resolve(connection)
31+
})
32+
})
33+
}
34+
35+
/**
36+
* Runs identify for the given connection and verifies it against the
37+
* PeerInfo provided
38+
* @param {Connection} connection
39+
* @param {PeerInfo} cryptoPeerInfo The PeerInfo determined during crypto exchange
40+
* @returns {Promise} Resolves {peerInfo, observedAddrs}
41+
*/
42+
module.exports.identifyDialer = (connection, cryptoPeerInfo) => {
43+
return new Promise((resolve, reject) => {
44+
Identify.dialer(connection, cryptoPeerInfo, (err, peerInfo, observedAddrs) => {
45+
if (err) return reject(err)
46+
resolve({ peerInfo, observedAddrs })
47+
})
48+
})
49+
}

test/dial-fsm.node.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ describe('dialFSM', () => {
125125
}
126126
})
127127

128-
const connFSM = switchA.dialFSM(switchB._peerInfo, '/closed/1.0.0', () => { })
128+
const connFSM = switchA.dialFSM(switchB._peerInfo, '/closed/1.0.0', (err) => {
129+
expect(err).to.not.exist()
130+
})
129131
connFSM.once('close', () => {
130132
expect(switchA.connection.getAllById(switchB._peerInfo.id.toB58String())).to.have.length(0).mark()
131133
})

0 commit comments

Comments
 (0)