Skip to content

Commit c4ede4d

Browse files
feat: use libp2p 0.28.x (#217)
Updates the bitswap module to use new features in `[email protected]`. `peer-info` has been deprecated, `js-libp2p` has changed how it gathers its listening multiaddr, the `ConnectionManager`, `PeerStore` and `DHT` APIs have all be updated. BREAKING CHANGE: Requires `[email protected]` or above Co-authored-by: Jacob Heun <[email protected]>
1 parent b5e05e2 commit c4ede4d

File tree

9 files changed

+116
-78
lines changed

9 files changed

+116
-78
lines changed

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
"iso-random-stream": "^1.1.1",
5353
"it-all": "^1.0.2",
5454
"it-drain": "^1.0.1",
55-
"libp2p": "^0.27.0",
56-
"libp2p-kad-dht": "^0.18.3",
55+
"libp2p": "^0.28.0",
56+
"libp2p-kad-dht": "^0.19.1",
5757
"libp2p-mplex": "^0.9.2",
5858
"libp2p-secio": "^0.12.1",
5959
"libp2p-tcp": "^0.14.2",
@@ -65,9 +65,7 @@
6565
"p-defer": "^3.0.0",
6666
"p-event": "^4.1.0",
6767
"p-wait-for": "^3.1.0",
68-
"peer-book": "~0.9.0",
6968
"peer-id": "^0.13.5",
70-
"peer-info": "^0.17.0",
7169
"promisify-es6": "^1.0.3",
7270
"rimraf": "^3.0.0",
7371
"sinon": "^9.0.0",
@@ -84,6 +82,7 @@
8482
"it-length-prefixed": "^3.0.0",
8583
"it-pipe": "^1.1.0",
8684
"just-debounce-it": "^1.1.0",
85+
"libp2p-interfaces": "^0.3.0",
8786
"moving-average": "^1.0.0",
8887
"multicodec": "^1.0.0",
8988
"multihashing-async": "^0.8.0",

src/index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const statsKeys = [
3737
class Bitswap {
3838
constructor (libp2p, blockstore, options) {
3939
this._libp2p = libp2p
40-
this._log = logger(this.peerInfo.id)
40+
this._log = logger(this.peerId)
4141

4242
this._options = Object.assign({}, defaultOptions, options)
4343

@@ -54,16 +54,16 @@ class Bitswap {
5454
// local database
5555
this.blockstore = blockstore
5656

57-
this.engine = new DecisionEngine(this.peerInfo.id, blockstore, this.network, this._stats)
57+
this.engine = new DecisionEngine(this.peerId, blockstore, this.network, this._stats)
5858

5959
// handle message sending
60-
this.wm = new WantManager(this.peerInfo.id, this.network, this._stats)
60+
this.wm = new WantManager(this.peerId, this.network, this._stats)
6161

62-
this.notifications = new Notifications(this.peerInfo.id)
62+
this.notifications = new Notifications(this.peerId)
6363
}
6464

65-
get peerInfo () {
66-
return this._libp2p.peerInfo
65+
get peerId () {
66+
return this._libp2p.peerId
6767
}
6868

6969
// handle messages received through the network

src/network.js

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
const lp = require('it-length-prefixed')
44
const pipe = require('it-pipe')
55

6+
const MulticodecTopology = require('libp2p-interfaces/src/topology/multicodec-topology')
7+
68
const Message = require('./types/message')
79
const CONSTANTS = require('./constants')
810
const logger = require('./utils').logger
@@ -13,7 +15,7 @@ const BITSWAP120 = '/ipfs/bitswap/1.2.0'
1315

1416
class Network {
1517
constructor (libp2p, bitswap, options, stats) {
16-
this._log = logger(libp2p.peerInfo.id, 'network')
18+
this._log = logger(libp2p.peerId, 'network')
1719
options = options || {}
1820
this.libp2p = libp2p
1921
this.bitswap = bitswap
@@ -37,14 +39,21 @@ class Network {
3739
this._running = true
3840
this.libp2p.handle(this.protocols, this._onConnection)
3941

40-
this.libp2p.on('peer:connect', this._onPeerConnect)
41-
this.libp2p.on('peer:disconnect', this._onPeerDisconnect)
42+
// register protocol with topology
43+
const topology = new MulticodecTopology({
44+
multicodecs: this.protocols,
45+
handlers: {
46+
onConnect: this._onPeerConnect,
47+
onDisconnect: this._onPeerDisconnect
48+
}
49+
})
50+
this._registrarId = this.libp2p.registrar.register(topology)
4251

4352
// All existing connections are like new ones for us
4453
for (const peer of this.libp2p.peerStore.peers.values()) {
45-
if (this.libp2p.registrar.getConnection(peer)) {
46-
this._onPeerConnect(peer)
47-
}
54+
const conn = this.libp2p.connectionManager.get(peer.id)
55+
56+
conn && this._onPeerConnect(conn)
4857
}
4958
}
5059

@@ -54,8 +63,8 @@ class Network {
5463
// Unhandle both, libp2p doesn't care if it's not already handled
5564
this.libp2p.unhandle(this.protocols)
5665

57-
this.libp2p.removeListener('peer:connect', this._onPeerConnect)
58-
this.libp2p.removeListener('peer:disconnect', this._onPeerDisconnect)
66+
// unregister protocol and handlers
67+
this.libp2p.registrar.unregister(this._registrarId)
5968
}
6069

6170
/**
@@ -92,12 +101,12 @@ class Network {
92101
}
93102
}
94103

95-
_onPeerConnect (peerInfo) {
96-
this.bitswap._onPeerConnected(peerInfo.id)
104+
_onPeerConnect (peerId) {
105+
this.bitswap._onPeerConnected(peerId)
97106
}
98107

99-
_onPeerDisconnect (peerInfo) {
100-
this.bitswap._onPeerDisconnected(peerInfo.id)
108+
_onPeerDisconnect (peerId) {
109+
this.bitswap._onPeerDisconnected(peerId)
101110
}
102111

103112
/**
@@ -181,7 +190,7 @@ class Network {
181190
/**
182191
* Connects to another peer
183192
*
184-
* @param {PeerInfo|PeerId|Multiaddr} peer
193+
* @param {PeerId|Multiaddr} peer
185194
* @param {Object} options
186195
* @param {AbortSignal} options.abortSignal
187196
* @returns {Promise<Connection>}

test/bitswap-stats.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ describe('bitswap stats', () => {
169169
bs2 = bitswaps[1]
170170
bs2.start()
171171

172-
await libp2pNodes[0].dial(libp2pNodes[1].peerInfo)
172+
const ma = `${libp2pNodes[1].multiaddrs[0]}/p2p/${libp2pNodes[1].peerId.toB58String()}`
173+
await libp2pNodes[0].dial(ma)
173174

174175
block = await makeBlock()
175176

@@ -212,7 +213,7 @@ describe('bitswap stats', () => {
212213
})
213214

214215
it('has peer stats', async () => {
215-
const peerStats = bs2.stat().forPeer(libp2pNodes[0].peerInfo.id)
216+
const peerStats = bs2.stat().forPeer(libp2pNodes[0].peerId)
216217
expect(peerStats).to.exist()
217218

218219
const stats = await pEvent(peerStats, 'update')

test/bitswap.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
'use strict'
33

44
const { expect } = require('aegir/utils/chai')
5-
const delay = require('delay')
65
const PeerId = require('peer-id')
76
const sinon = require('sinon')
7+
const pWaitFor = require('p-wait-for')
88

99
const Bitswap = require('../src')
1010

@@ -38,9 +38,12 @@ describe('bitswap without DHT', function () {
3838
])
3939

4040
// connect 0 -> 1 && 1 -> 2
41+
const ma1 = `${nodes[1].libp2pNode.multiaddrs[0]}/p2p/${nodes[1].libp2pNode.peerId.toB58String()}`
42+
const ma2 = `${nodes[2].libp2pNode.multiaddrs[0]}/p2p/${nodes[2].libp2pNode.peerId.toB58String()}`
43+
4144
await Promise.all([
42-
nodes[0].libp2pNode.dial(nodes[1].libp2pNode.peerInfo),
43-
nodes[1].libp2pNode.dial(nodes[2].libp2pNode.peerInfo)
45+
nodes[0].libp2pNode.dial(ma1),
46+
nodes[1].libp2pNode.dial(ma2)
4447
])
4548
})
4649

@@ -132,9 +135,19 @@ describe('bitswap with DHT', function () {
132135
])
133136

134137
// connect 0 -> 1 && 1 -> 2
138+
const ma1 = `${nodes[1].libp2pNode.multiaddrs[0]}/p2p/${nodes[1].libp2pNode.peerId.toB58String()}`
139+
const ma2 = `${nodes[2].libp2pNode.multiaddrs[0]}/p2p/${nodes[2].libp2pNode.peerId.toB58String()}`
140+
141+
await Promise.all([
142+
nodes[0].libp2pNode.dial(ma1),
143+
nodes[1].libp2pNode.dial(ma2)
144+
])
145+
146+
// await dht routing table are updated
135147
await Promise.all([
136-
nodes[0].libp2pNode.dial(nodes[1].libp2pNode.peerInfo),
137-
nodes[1].libp2pNode.dial(nodes[2].libp2pNode.peerInfo)
148+
pWaitFor(() => nodes[0].libp2pNode._dht.routingTable.size >= 1),
149+
pWaitFor(() => nodes[1].libp2pNode._dht.routingTable.size >= 2),
150+
pWaitFor(() => nodes[2].libp2pNode._dht.routingTable.size >= 1)
138151
])
139152
})
140153

@@ -148,10 +161,11 @@ describe('bitswap with DHT', function () {
148161

149162
it('put a block in 2, get it in 0', async () => {
150163
const block = await makeBlock()
164+
const provideSpy = sinon.spy(nodes[2].libp2pNode._dht, 'provide')
151165
await nodes[2].bitswap.put(block)
152166

153-
// Give put time to process
154-
await delay(100)
167+
// wait for the DHT to finish providing
168+
await provideSpy.returnValues[0]
155169

156170
const blockRetrieved = await nodes[0].bitswap.get(block.cid)
157171
expect(block.data).to.eql(blockRetrieved.data)

test/network/network.node.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ describe('network', () => {
7676

7777
it('connectTo fail', async () => {
7878
try {
79-
await networkA.connectTo(p2pB.peerInfo.id)
79+
await networkA.connectTo(p2pB.peerId)
8080
assert.fail()
8181
} catch (err) {
8282
expect(err).to.exist()
@@ -87,24 +87,26 @@ describe('network', () => {
8787
var counter = 0
8888

8989
bitswapMockA._onPeerConnected = (peerId) => {
90-
expect(peerId.toB58String()).to.equal(p2pB.peerInfo.id.toB58String())
90+
expect(peerId.toB58String()).to.equal(p2pB.peerId.toB58String())
9191
counter++
9292
}
9393

9494
bitswapMockB._onPeerConnected = (peerId) => {
95-
expect(peerId.toB58String()).to.equal(p2pA.peerInfo.id.toB58String())
95+
expect(peerId.toB58String()).to.equal(p2pA.peerId.toB58String())
9696
counter++
9797
}
9898

99-
await p2pA.dial(p2pB.peerInfo)
99+
const ma = `${p2pB.multiaddrs[0]}/p2p/${p2pB.peerId.toB58String()}`
100+
await p2pA.dial(ma)
100101

101102
await pWaitFor(() => counter >= 2)
102103
bitswapMockA._onPeerConnected = () => {}
103104
bitswapMockB._onPeerConnected = () => {}
104105
})
105106

106107
it('connectTo success', async () => {
107-
await networkA.connectTo(p2pB.peerInfo)
108+
const ma = `${p2pB.multiaddrs[0]}/p2p/${p2pB.peerId.toB58String()}`
109+
await networkA.connectTo(ma)
108110
})
109111

110112
const versions = [{
@@ -134,7 +136,8 @@ describe('network', () => {
134136

135137
bitswapMockB._receiveError = (err) => deferred.reject(err)
136138

137-
const { stream } = await p2pA.dialProtocol(p2pB.peerInfo, '/ipfs/bitswap/' + version.num)
139+
const ma = `${p2pB.multiaddrs[0]}/p2p/${p2pB.peerId.toB58String()}`
140+
const { stream } = await p2pA.dialProtocol(ma, '/ipfs/bitswap/' + version.num)
138141
await pipe(
139142
[version.serialize(msg)],
140143
lp.encode(),
@@ -165,11 +168,12 @@ describe('network', () => {
165168

166169
bitswapMockB._receiveError = deferred.reject
167170

168-
await networkA.sendMessage(p2pB.peerInfo.id, msg)
171+
await networkA.sendMessage(p2pB.peerId, msg)
169172
})
170173

171174
it('dial to peer on Bitswap 1.0.0', async () => {
172-
const { protocol } = await p2pA.dialProtocol(p2pC.peerInfo, ['/ipfs/bitswap/1.1.0', '/ipfs/bitswap/1.0.0'])
175+
const ma = `${p2pC.multiaddrs[0]}/p2p/${p2pC.peerId.toB58String()}`
176+
const { protocol } = await p2pA.dialProtocol(ma, ['/ipfs/bitswap/1.1.0', '/ipfs/bitswap/1.0.0'])
173177

174178
expect(protocol).to.equal('/ipfs/bitswap/1.0.0')
175179
})
@@ -194,7 +198,7 @@ describe('network', () => {
194198

195199
bitswapMockC._receiveError = deferred.reject
196200

197-
await networkA.sendMessage(p2pC.peerInfo.id, msg)
201+
await networkA.sendMessage(p2pC.peerId, msg)
198202
await deferred.promise
199203
})
200204

@@ -208,16 +212,17 @@ describe('network', () => {
208212
networkA.start()
209213
networkB.start()
210214

211-
// FIXME: have to already be connected as sendMessage only accepts a peer id, not a PeerInfo
212-
await p2pA.dial(p2pB.peerInfo)
215+
// In a real network scenario, peers will be discovered and their addresses
216+
// will be added to the addressBook before bitswap kicks in
217+
p2pA.peerStore.addressBook.set(p2pB.peerId, p2pB.multiaddrs)
213218

214219
const deferred = pDefer()
215220

216221
bitswapMockB._receiveMessage = () => {
217222
deferred.resolve()
218223
}
219224

220-
await networkA.sendMessage(p2pB.peerInfo.id, new Message(true))
225+
await networkA.sendMessage(p2pB.peerId, new Message(true))
221226

222227
return deferred
223228
})

test/utils/connect-all.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const without = require('lodash.without')
55
module.exports = async (nodes) => {
66
for (const node of nodes) {
77
for (const otherNode of without(nodes, node)) {
8-
await node.libp2pNode.dial(otherNode.bitswap.peerInfo)
8+
await node.libp2pNode.dial(otherNode.bitswap.peerId)
99
}
1010
}
1111
}

test/utils/create-libp2p-node.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ const MPLEX = require('libp2p-mplex')
55
const SECIO = require('libp2p-secio')
66
const libp2p = require('libp2p')
77
const KadDHT = require('libp2p-kad-dht')
8-
const PeerInfo = require('peer-info')
98
const PeerId = require('peer-id')
9+
1010
const defaultsDeep = require('@nodeutils/defaults-deep')
1111

1212
class Node extends libp2p {
@@ -38,10 +38,13 @@ class Node extends libp2p {
3838

3939
async function createLibp2pNode (options = {}) {
4040
const id = await PeerId.create({ bits: 512 })
41-
const peerInfo = new PeerInfo(id)
42-
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
43-
options.peerInfo = peerInfo
44-
const node = new Node(options)
41+
const node = new Node({
42+
peerId: id,
43+
addresses: {
44+
listen: ['/ip4/0.0.0.0/tcp/0']
45+
},
46+
...options
47+
})
4548
await node.start()
4649

4750
return node

0 commit comments

Comments
 (0)