Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit e8e9b91

Browse files
author
Alan Shaw
authored
feat: pass libp2pOptions to the bundle function (#2591)
This allows bundle creation by merging/overriding option defaults instead of creating them in their entirety from scratch. e.g. ```js const ipfs = await IPFS.create({ libp2p: ({ libp2pOptions, peerInfo }) => { libp2pOptions.transports.push(...) return new Libp2p(defaultOptions) } }) ``` License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
1 parent 06340ec commit e8e9b91

File tree

4 files changed

+164
-132
lines changed

4 files changed

+164
-132
lines changed

src/core/components/libp2p.js

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,20 @@ module.exports = function libp2p (self, config) {
1313
const options = self._options || {}
1414
config = config || {}
1515

16-
// Always create libp2p via a bundle function
17-
const createBundle = typeof options.libp2p === 'function'
18-
? options.libp2p
19-
: defaultBundle
20-
2116
const { datastore } = self._repo
2217
const peerInfo = self._peerInfo
2318
const peerBook = self._peerInfoBook
24-
const libp2p = createBundle({ options, config, datastore, peerInfo, peerBook })
19+
20+
const libp2pOptions = getLibp2pOptions({ options, config, datastore, peerInfo, peerBook })
21+
let libp2p
22+
23+
if (typeof options.libp2p === 'function') {
24+
libp2p = options.libp2p({ libp2pOptions, options, config, datastore, peerInfo, peerBook })
25+
} else {
26+
// Required inline to reduce startup time
27+
const Libp2p = require('libp2p')
28+
libp2p = new Libp2p(mergeOptions(libp2pOptions, get(options, 'libp2p', {})))
29+
}
2530

2631
libp2p.on('stop', () => {
2732
// Clear our addresses so we can start clean
@@ -39,7 +44,7 @@ module.exports = function libp2p (self, config) {
3944
return libp2p
4045
}
4146

42-
function defaultBundle ({ datastore, peerInfo, peerBook, options, config }) {
47+
function getLibp2pOptions ({ options, config, datastore, peerInfo, peerBook }) {
4348
// Set up Delegate Routing based on the presence of Delegates in the config
4449
let contentRouting
4550
let peerRouting
@@ -80,7 +85,12 @@ function defaultBundle ({ datastore, peerInfo, peerBook, options, config }) {
8085
peerBook,
8186
modules: {
8287
contentRouting,
83-
peerRouting,
88+
peerRouting
89+
}
90+
}
91+
92+
const libp2pOptions = {
93+
modules: {
8494
pubsub: getPubsubRouter()
8595
},
8696
config: {
@@ -133,9 +143,14 @@ function defaultBundle ({ datastore, peerInfo, peerBook, options, config }) {
133143
})
134144
}
135145

136-
const libp2pOptions = mergeOptions(libp2pDefaults, get(options, 'libp2p', {}))
137146
// Required inline to reduce startup time
138147
// Note: libp2p-nodejs gets replaced by libp2p-browser when webpacked/browserified
139-
const Node = require('../runtime/libp2p-nodejs')
140-
return new Node(libp2pOptions)
148+
const getEnvLibp2pOptions = require('../runtime/libp2p-nodejs')
149+
150+
// Merge defaults with Node.js/browser/other environments options and configuration
151+
return mergeOptions(
152+
libp2pDefaults,
153+
getEnvLibp2pOptions({ options, config, datastore, peerInfo, peerBook }),
154+
libp2pOptions
155+
)
141156
}

src/core/runtime/libp2p-browser.js

Lines changed: 51 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,73 +8,65 @@ const SECIO = require('libp2p-secio')
88
const Bootstrap = require('libp2p-bootstrap')
99
const KadDHT = require('libp2p-kad-dht')
1010
const GossipSub = require('libp2p-gossipsub')
11-
const libp2p = require('libp2p')
12-
const mergeOptions = require('merge-options')
1311
const multiaddr = require('multiaddr')
1412

15-
class Node extends libp2p {
16-
constructor (_options) {
17-
const wrtcstar = new WebRTCStar({ id: _options.peerInfo.id })
13+
module.exports = ({ peerInfo, options }) => {
14+
const wrtcstar = new WebRTCStar({ id: peerInfo.id })
1815

19-
// this can be replaced once optional listening is supported with the below code. ref: https://github.com/libp2p/interface-transport/issues/41
20-
// const wsstar = new WebSocketStar({ id: _options.peerInfo.id })
21-
const wsstarServers = _options.peerInfo.multiaddrs.toArray().map(String).filter(addr => addr.includes('p2p-websocket-star'))
22-
_options.peerInfo.multiaddrs.replace(wsstarServers.map(multiaddr), '/p2p-websocket-star') // the ws-star-multi module will replace this with the chosen ws-star servers
23-
const wsstar = new WebSocketStarMulti({ servers: wsstarServers, id: _options.peerInfo.id, ignore_no_online: !wsstarServers.length || _options.wsStarIgnoreErrors })
16+
// this can be replaced once optional listening is supported with the below code. ref: https://github.com/libp2p/interface-transport/issues/41
17+
// const wsstar = new WebSocketStar({ id: _options.peerInfo.id })
18+
const wsstarServers = peerInfo.multiaddrs.toArray().map(String).filter(addr => addr.includes('p2p-websocket-star'))
19+
peerInfo.multiaddrs.replace(wsstarServers.map(multiaddr), '/p2p-websocket-star') // the ws-star-multi module will replace this with the chosen ws-star servers
20+
const wsstar = new WebSocketStarMulti({ servers: wsstarServers, id: peerInfo.id, ignore_no_online: !wsstarServers.length || options.wsStarIgnoreErrors })
2421

25-
const defaults = {
26-
switch: {
27-
denyTTL: 2 * 60 * 1e3, // 2 minute base
28-
denyAttempts: 5, // back off 5 times
29-
maxParallelDials: 100,
30-
maxColdCalls: 25,
31-
dialTimeout: 20e3
32-
},
33-
modules: {
34-
transport: [
35-
WS,
36-
wrtcstar,
37-
wsstar
38-
],
39-
streamMuxer: [
40-
Multiplex
41-
],
42-
connEncryption: [
43-
SECIO
44-
],
45-
peerDiscovery: [
46-
wrtcstar.discovery,
47-
wsstar.discovery,
48-
Bootstrap
49-
],
50-
dht: KadDHT,
51-
pubsub: GossipSub
52-
},
53-
config: {
54-
peerDiscovery: {
55-
autoDial: true,
56-
bootstrap: {
57-
enabled: true
58-
},
59-
webRTCStar: {
60-
enabled: true
61-
},
62-
websocketStar: {
63-
enabled: true
64-
}
22+
return {
23+
switch: {
24+
denyTTL: 2 * 60 * 1e3, // 2 minute base
25+
denyAttempts: 5, // back off 5 times
26+
maxParallelDials: 100,
27+
maxColdCalls: 25,
28+
dialTimeout: 20e3
29+
},
30+
modules: {
31+
transport: [
32+
WS,
33+
wrtcstar,
34+
wsstar
35+
],
36+
streamMuxer: [
37+
Multiplex
38+
],
39+
connEncryption: [
40+
SECIO
41+
],
42+
peerDiscovery: [
43+
wrtcstar.discovery,
44+
wsstar.discovery,
45+
Bootstrap
46+
],
47+
dht: KadDHT,
48+
pubsub: GossipSub
49+
},
50+
config: {
51+
peerDiscovery: {
52+
autoDial: true,
53+
bootstrap: {
54+
enabled: true
6555
},
66-
dht: {
67-
enabled: false
56+
webRTCStar: {
57+
enabled: true
6858
},
69-
pubsub: {
70-
enabled: true,
71-
emitSelf: true
59+
websocketStar: {
60+
enabled: true
7261
}
62+
},
63+
dht: {
64+
enabled: false
65+
},
66+
pubsub: {
67+
enabled: true,
68+
emitSelf: true
7369
}
7470
}
75-
76-
super(mergeOptions(defaults, _options))
7771
}
7872
}
79-
80-
module.exports = Node

src/core/runtime/libp2p-nodejs.js

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,75 +9,67 @@ const KadDHT = require('libp2p-kad-dht')
99
const GossipSub = require('libp2p-gossipsub')
1010
const Multiplex = require('pull-mplex')
1111
const SECIO = require('libp2p-secio')
12-
const libp2p = require('libp2p')
13-
const mergeOptions = require('merge-options')
1412
const multiaddr = require('multiaddr')
1513

16-
class Node extends libp2p {
17-
constructor (_options) {
18-
// this can be replaced once optional listening is supported with the below code. ref: https://github.com/libp2p/interface-transport/issues/41
19-
// const wsstar = new WebSocketStar({ id: _options.peerInfo.id })
20-
const wsstarServers = _options.peerInfo.multiaddrs.toArray().map(String).filter(addr => addr.includes('p2p-websocket-star'))
21-
_options.peerInfo.multiaddrs.replace(wsstarServers.map(multiaddr), '/p2p-websocket-star') // the ws-star-multi module will replace this with the chosen ws-star servers
22-
const wsstar = new WebSocketStarMulti({ servers: wsstarServers, id: _options.peerInfo.id, ignore_no_online: !wsstarServers.length || _options.wsStarIgnoreErrors })
14+
module.exports = ({ peerInfo, options }) => {
15+
// this can be replaced once optional listening is supported with the below code. ref: https://github.com/libp2p/interface-transport/issues/41
16+
// const wsstar = new WebSocketStar({ id: _options.peerInfo.id })
17+
const wsstarServers = peerInfo.multiaddrs.toArray().map(String).filter(addr => addr.includes('p2p-websocket-star'))
18+
peerInfo.multiaddrs.replace(wsstarServers.map(multiaddr), '/p2p-websocket-star') // the ws-star-multi module will replace this with the chosen ws-star servers
19+
const wsstar = new WebSocketStarMulti({ servers: wsstarServers, id: peerInfo.id, ignore_no_online: !wsstarServers.length || options.wsStarIgnoreErrors })
2320

24-
const defaults = {
25-
switch: {
26-
denyTTL: 2 * 60 * 1e3, // 2 minute base
27-
denyAttempts: 5, // back off 5 times
28-
maxParallelDials: 150,
29-
maxColdCalls: 50,
30-
dialTimeout: 10e3 // Be strict with dial time
31-
},
32-
modules: {
33-
transport: [
34-
TCP,
35-
WS,
36-
wsstar
37-
],
38-
streamMuxer: [
39-
Multiplex
40-
],
41-
connEncryption: [
42-
SECIO
43-
],
44-
peerDiscovery: [
45-
MulticastDNS,
46-
Bootstrap,
47-
wsstar.discovery
48-
],
49-
dht: KadDHT,
50-
pubsub: GossipSub
51-
},
52-
config: {
53-
peerDiscovery: {
54-
autoDial: true,
55-
mdns: {
56-
enabled: true
57-
},
58-
bootstrap: {
59-
enabled: true
60-
},
61-
websocketStar: {
62-
enabled: true
63-
}
21+
return {
22+
switch: {
23+
denyTTL: 2 * 60 * 1e3, // 2 minute base
24+
denyAttempts: 5, // back off 5 times
25+
maxParallelDials: 150,
26+
maxColdCalls: 50,
27+
dialTimeout: 10e3 // Be strict with dial time
28+
},
29+
modules: {
30+
transport: [
31+
TCP,
32+
WS,
33+
wsstar
34+
],
35+
streamMuxer: [
36+
Multiplex
37+
],
38+
connEncryption: [
39+
SECIO
40+
],
41+
peerDiscovery: [
42+
MulticastDNS,
43+
Bootstrap,
44+
wsstar.discovery
45+
],
46+
dht: KadDHT,
47+
pubsub: GossipSub
48+
},
49+
config: {
50+
peerDiscovery: {
51+
autoDial: true,
52+
mdns: {
53+
enabled: true
6454
},
65-
dht: {
66-
kBucketSize: 20,
67-
enabled: false,
68-
randomWalk: {
69-
enabled: false
70-
}
55+
bootstrap: {
56+
enabled: true
7157
},
72-
pubsub: {
73-
enabled: true,
74-
emitSelf: true
58+
websocketStar: {
59+
enabled: true
60+
}
61+
},
62+
dht: {
63+
kBucketSize: 20,
64+
enabled: false,
65+
randomWalk: {
66+
enabled: false
7567
}
68+
},
69+
pubsub: {
70+
enabled: true,
71+
emitSelf: true
7672
}
7773
}
78-
79-
super(mergeOptions(defaults, _options))
8074
}
8175
}
82-
83-
module.exports = Node

test/core/libp2p.spec.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,39 @@ describe('libp2p customization', function () {
107107
done()
108108
})
109109
})
110+
111+
it('should pass libp2p options to libp2p bundle function', (done) => {
112+
class DummyTransport {
113+
filter () {
114+
return []
115+
}
116+
}
117+
118+
const ipfs = {
119+
_repo: {
120+
datastore
121+
},
122+
_peerInfo: peerInfo,
123+
_peerBook: peerBook,
124+
// eslint-disable-next-line no-console
125+
_print: console.log,
126+
_options: {
127+
libp2p: ({ libp2pOptions, peerInfo }) => {
128+
libp2pOptions.modules.transport = [DummyTransport]
129+
return new Libp2p(libp2pOptions)
130+
}
131+
}
132+
}
133+
134+
_libp2p = libp2pComponent(ipfs, testConfig)
135+
136+
_libp2p.start((err) => {
137+
expect(err).to.not.exist()
138+
expect(_libp2p._transport).to.have.length(1)
139+
expect(_libp2p._transport[0] instanceof DummyTransport).to.equal(true)
140+
done()
141+
})
142+
})
110143
})
111144

112145
describe('options', () => {

0 commit comments

Comments
 (0)