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

Commit 9c60909

Browse files
daviddiasalanshaw
authored andcommitted
feat: (BREAKING CHANGE) new libp2p configuration (#1401)
BREAKING CHANGE: libp2p configuration has changed * old: `libp2p.modules.discovery` * new: `libp2p.modules.peerDiscovery` License: MIT Signed-off-by: David Dias <[email protected]> License: MIT Signed-off-by: Alan Shaw <[email protected]>
1 parent 7b5f955 commit 9c60909

File tree

11 files changed

+208
-130
lines changed

11 files changed

+208
-130
lines changed

README.md

+13-7
Original file line numberDiff line numberDiff line change
@@ -224,22 +224,28 @@ Creates and returns an instance of an IPFS node. Use the `options` argument to s
224224

225225
- `pass` (string): A passphrase to encrypt/decrypt your keys.
226226

227+
- `relay` (object): Configure circuit relay (see the [circuit relay tutorial](https://github.com/ipfs/js-ipfs/tree/master/examples/circuit-relaying) to learn more).
228+
- `enabled` (boolean): Enable circuit relay dialer and listener. (Default: `false`)
229+
- `hop` (object)
230+
- `enabled` (boolean): Make this node a relay (other nodes can connect *through* it). (Default: `false`)
231+
- `active` (boolean): Make this an *active* relay node. Active relay nodes will attempt to dial a destination peer even if that peer is not yet connected to the relay. (Default: `false`)
232+
227233
- `EXPERIMENTAL` (object): Enable and configure experimental features.
228234
- `pubsub` (boolean): Enable libp2p pub-sub. (Default: `false`)
229235
- `sharding` (boolean): Enable directory sharding. Directories that have many child objects will be represented by multiple DAG nodes instead of just one. It can improve lookup performance when a directory has several thousand files or more. (Default: `false`)
230236
- `dht` (boolean): Enable KadDHT. **This is currently not interopable with `go-ipfs`.**
231-
- `relay` (object): Configure circuit relay (see the [circuit relay tutorial](https://github.com/ipfs/js-ipfs/tree/master/examples/circuit-relaying) to learn more).
232-
- `enabled` (boolean): Enable circuit relay dialer and listener. (Default: `false`)
233-
- `hop` (object)
234-
- `enabled` (boolean): Make this node a relay (other nodes can connect *through* it). (Default: `false`)
235-
- `active` (boolean): Make this an *active* relay node. Active relay nodes will attempt to dial a destination peer even if that peer is not yet connected to the relay. (Default: `false`)
236237

237238
- `config` (object) Modify the default IPFS node config. Find the Node.js defaults at [`src/core/runtime/config-nodejs.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-nodejs.js) and the browser defaults at [`src/core/runtime/config-browser.js`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-browser.js). This object will be *merged* with the default config; it will not replace it.
238239

239240
- `libp2p` (object) add custom modules to the libp2p stack of your node
240241
- `modules` (object):
241-
- `transport` (Array<[libp2p.Transport](https://github.com/libp2p/interface-transport)>): An array of additional Libp2p transport instances to use. See [libp2p/interface-transport](https://github.com/libp2p/interface-transport) for details.
242-
- `discovery` (Array<[libp2p.PeerDiscovery](https://github.com/libp2p/interface-peer-discovery)>): An array of additional Libp2p peer discovery instances to use. See [libp2p/peer-discovery](https://github.com/libp2p/interface-peer-discovery) for details.
242+
- `transport` (Array<[libp2p.Transport](https://github.com/libp2p/interface-transport)>): An array of Libp2p transport classes/instances to use _instead_ of the defaults. See [libp2p/interface-transport](https://github.com/libp2p/interface-transport) for details.
243+
- `peerDiscovery` (Array<[libp2p.PeerDiscovery](https://github.com/libp2p/interface-peer-discovery)>): An array of Libp2p peer discovery classes/instances to use _instead_ of the defaults. See [libp2p/peer-discovery](https://github.com/libp2p/interface-peer-discovery) for details. If passing a class, configuration can be passed using the config section below under the key corresponding to you module's unique `tag` (a static property on the class)
244+
- `config` (object):
245+
- `peerDiscovery` (object):
246+
- `[PeerDiscovery.tag]` (object): configuration for a peer discovery module
247+
- `enabled` (boolean): whether this module is enabled or disabled
248+
- `[custom config]` (any): other keys are specific to the module
243249

244250
#### Events
245251

examples/circuit-relaying/README.md

+17-23
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Here is a simple diagram depicting how a typical circuit-relay connection might
2222
+---------------------+
2323
```
2424

25-
`Node A` tries to connect to `Node B` but, UH-OH! There is a firewall in between that's preventing it from happening. If both `Node A` and `Node B` know about a relay, they can use it to establish the connection.
25+
`Node A` tries to connect to `Node B` but, UH-OH! There is a firewall in between that's preventing it from happening. If both `Node A` and `Node B` know about a relay, they can use it to establish the connection.
2626

2727
This is what it looks like, in simplified steps:
2828

@@ -60,7 +60,7 @@ There are a couple of caveats and features to be aware of:
6060

6161
#### A word on circuit relay addresses
6262

63-
A circuit relay address is a [multiaddress](https://multiformats.io/multiaddr/) that describes how to either connect to a peer over a relay (or relays), or allow a peer to announce it is reachable over a particular relay or any relay it is already connected to.
63+
A circuit relay address is a [multiaddress](https://multiformats.io/multiaddr/) that describes how to either connect to a peer over a relay (or relays), or allow a peer to announce it is reachable over a particular relay or any relay it is already connected to.
6464

6565
Circuit relay addresses are very flexible and can describe many different aspects of how to esablish the relayed connection. In its simplest form, it looks something like this:
6666

@@ -78,8 +78,8 @@ We can take it a step further and encode the same information for the destinatio
7878

7979
- `/ip4/127.0.0.1/tcp/65000/ipfs/QmRelay/p2p-circuit`
8080

81-
If a node is configured with this address, it will use the specified host (`/ip4/127.0.0.1/tcp/65000/ipfs/QmRelay`) as a relay and it will be reachable over this relay.
82-
- There could multiple addresses of this sort specified in the config, in which case the node will be reachable over all of them.
81+
If a node is configured with this address, it will use the specified host (`/ip4/127.0.0.1/tcp/65000/ipfs/QmRelay`) as a relay and it will be reachable over this relay.
82+
- There could multiple addresses of this sort specified in the config, in which case the node will be reachable over all of them.
8383
- This is useful if, for example, the node is behind a firewall but wants to be reachable from the outside over a specific relay.
8484

8585
Other use-cases are also supported by this scheme, e.g. we can have multiple hops (circuit-relay nodes) encoded in the address, something planed for future releases.
@@ -153,7 +153,7 @@ In order to enable the relay functionality in `go-ipfs` we need to edit it's con
153153
}
154154
```
155155

156-
The two options we're looking for are `DisableRelay` and `EnableRelayHop`. We want the former (`DisableRelay`) set to `false` and the latter (`EnableRelayHop`) to `true`, just like in the example above. That should set our go node as a relay.
156+
The two options we're looking for are `DisableRelay` and `EnableRelayHop`. We want the former (`DisableRelay`) set to `false` and the latter (`EnableRelayHop`) to `true`, just like in the example above. That should set our go node as a relay.
157157

158158
We also need to make sure our go node can be dialed from the browser. For that, we need to enable a transport that both the browser and the go node can communicate over. We will use the web sockets transport, although there are others that can be used, such as `webrtc-star` and `websocket-star`. To enable the transport and set the interface and port we need to edit the `~/.ipfs/config` one more time. Let's find the `Swarm` array and add our desired address there. I picked `/ip4/0.0.0.0/tcp/4004/ws` because it is a port I know is not being used by anything on my machine, but we can also use port `0` so that the OS chooses a random available port for us — either one should work.
159159

@@ -173,15 +173,11 @@ We need to go through similar steps to enable circuit relay in `jsipfs`. However
173173

174174
Just as we did with `go-ipfs`, go ahead and edit `js-ipfs` config file located under `~/.jsipfs/config`. Let's add the following config:
175175

176-
(Note that the "EXPERIMENTAL" section might be missing from the config file. In that case, just go ahead and add it)
177-
178176
```js
179-
"EXPERIMENTAL": {
180-
"relay": {
181-
"enabled": true,
182-
"hop": {
183-
"enabled": true
184-
}
177+
"relay": {
178+
"enabled": true,
179+
"hop": {
180+
"enabled": true
185181
}
186182
}
187183
```
@@ -247,7 +243,7 @@ Gateway (readonly) is listening on: /ip4/127.0.0.1/tcp/9090
247243
Daemon is ready
248244
```
249245

250-
Look out for an address similar to `/ip4/127.0.0.1/tcp/4003/ws/ipfs/Qm...`. Note it down somewhere, and let's move on to the next step.
246+
Look out for an address similar to `/ip4/127.0.0.1/tcp/4003/ws/ipfs/Qm...`. Note it down somewhere, and let's move on to the next step.
251247

252248
### 2. Configure and run the bundled example
253249

@@ -270,7 +266,7 @@ The bundled example is a simple chat app that uses another cool ipfs feature - [
270266

271267
### 3. Connect the two browser nodes to the circuit relay
272268

273-
In order for our browser nodes to be able to messages each other, we need to get them connected. But to do that, we need to use a relay - browser nodes can't be connected directly because of lack of socket support.
269+
In order for our browser nodes to be able to messages each other, we need to get them connected. But to do that, we need to use a relay - browser nodes can't be connected directly because of lack of socket support.
274270

275271
Remember the caveat above `Currently a Relay will only work if it already has a connection to the STOP node`? This means that we need to connect our browser nodes to the relay node first.
276272

@@ -304,21 +300,19 @@ Thats it!
304300

305301
### So what just happened?
306302

307-
Good question!
303+
Good question!
308304

309305
- We used [js-ipfs](htpps://github.com/ipfs/js-ipfs) running in the browser with circuit relay enabled:
310-
- _Notice the `EXPERIMENTAL.relay.enabled` below_
306+
- _Notice the `relay.enabled` below_
311307

312308
you can find it in [src/app.js](src/app.js)
313309
```js
314310
const ipfs = new IPFS({
315311
repo: repo(),
316-
EXPERIMENTAL: {
317-
relay: {
318-
enabled: true,
319-
hop: {
320-
enabled: true
321-
}
312+
relay: {
313+
enabled: true,
314+
hop: {
315+
enabled: true
322316
}
323317
},
324318
config: {

package.json

+11-10
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
},
6262
"homepage": "https://github.com/ipfs/js-ipfs#readme",
6363
"devDependencies": {
64-
"aegir": "^13.1.0",
64+
"aegir": "^14.0.0",
6565
"buffer-loader": "~0.0.1",
6666
"chai": "^4.1.2",
6767
"delay": "^2.0.0",
@@ -73,7 +73,7 @@
7373
"expose-loader": "~0.7.5",
7474
"form-data": "^2.3.2",
7575
"hat": "0.0.3",
76-
"interface-ipfs-core": "~0.69.0",
76+
"interface-ipfs-core": "~0.69.2",
7777
"ipfsd-ctl": "~0.37.3",
7878
"mocha": "^5.1.1",
7979
"ncp": "^2.0.0",
@@ -86,6 +86,7 @@
8686
"transform-loader": "~0.2.4"
8787
},
8888
"dependencies": {
89+
"@nodeutils/defaults-deep": "^1.1.0",
8990
"async": "^2.6.0",
9091
"big.js": "^5.1.2",
9192
"binary-querystring": "~0.1.2",
@@ -105,12 +106,12 @@
105106
"hapi-set-header": "^1.0.2",
106107
"hoek": "^5.0.3",
107108
"human-to-milliseconds": "^1.0.0",
108-
"interface-datastore": "^0.4.1",
109+
"interface-datastore": "~0.4.1",
109110
"ipfs-api": "^22.1.1",
110111
"ipfs-bitswap": "~0.20.0",
111112
"ipfs-block": "~0.7.1",
112113
"ipfs-block-service": "~0.14.0",
113-
"ipfs-http-response": "^0.1.2",
114+
"ipfs-http-response": "~0.1.2",
114115
"ipfs-multipart": "~0.1.0",
115116
"ipfs-repo": "~0.22.1",
116117
"ipfs-unixfs": "~0.1.15",
@@ -124,18 +125,18 @@
124125
"joi": "^13.2.0",
125126
"joi-browser": "^13.0.1",
126127
"joi-multiaddr": "^2.0.0",
127-
"libp2p": "~0.20.4",
128+
"libp2p": "~0.22.0",
128129
"libp2p-circuit": "~0.2.0",
129130
"libp2p-floodsub": "~0.15.0",
130131
"libp2p-kad-dht": "~0.10.0",
131132
"libp2p-keychain": "~0.3.1",
132-
"libp2p-mdns": "~0.11.0",
133-
"libp2p-mplex": "~0.7.0",
134-
"libp2p-railing": "~0.8.1",
133+
"libp2p-mdns": "~0.12.0",
134+
"libp2p-mplex": "~0.8.0",
135+
"libp2p-railing": "~0.9.2",
135136
"libp2p-secio": "~0.10.0",
136137
"libp2p-tcp": "~0.12.0",
137-
"libp2p-webrtc-star": "~0.15.0",
138-
"libp2p-websocket-star": "~0.8.0",
138+
"libp2p-webrtc-star": "~0.15.3",
139+
"libp2p-websocket-star": "~0.8.1",
139140
"libp2p-websockets": "~0.12.0",
140141
"lodash": "^4.17.10",
141142
"mafmt": "^6.0.0",

src/core/components/libp2p.js

+38-17
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
const Node = require('../runtime/libp2p-nodejs')
55
const promisify = require('promisify-es6')
66
const get = require('lodash/get')
7+
const defaultsDeep = require('@nodeutils/defaults-deep')
78

89
module.exports = function libp2p (self) {
910
return {
@@ -15,27 +16,47 @@ module.exports = function libp2p (self) {
1516
return callback(err)
1617
}
1718

18-
const options = {
19-
mdns: get(config, 'Discovery.MDNS.Enabled'),
20-
webRTCStar: get(config, 'Discovery.webRTCStar.Enabled'),
21-
bootstrap: get(config, 'Bootstrap'),
22-
modules: self._libp2pModules,
23-
// EXPERIMENTAL
24-
pubsub: get(self._options, 'EXPERIMENTAL.pubsub', false),
25-
dht: get(self._options, 'EXPERIMENTAL.dht', false),
26-
relay: {
27-
enabled: get(self._options, 'EXPERIMENTAL.relay.enabled',
28-
get(config, 'EXPERIMENTAL.relay.enabled', false)),
29-
hop: {
30-
enabled: get(self._options, 'EXPERIMENTAL.relay.hop.enabled',
31-
get(config, 'EXPERIMENTAL.relay.hop.enabled', false)),
32-
active: get(self._options, 'EXPERIMENTAL.relay.hop.active',
33-
get(config, 'EXPERIMENTAL.relay.hop.active', false))
19+
const libp2pDefaults = {
20+
peerInfo: self._peerInfo,
21+
peerBook: self._peerInfoBook,
22+
config: {
23+
peerDiscovery: {
24+
mdns: {
25+
enabled: get(self._options, 'config.Discovery.MDNS.Enabled',
26+
get(config, 'Discovery.MDNS.Enabled', true))
27+
},
28+
webRTCStar: {
29+
enabled: get(self._options, 'config.Discovery.webRTCStar.Enabled',
30+
get(config, 'Discovery.webRTCStar.Enabled', true))
31+
},
32+
bootstrap: {
33+
list: get(self._options, 'config.Bootstrap',
34+
get(config, 'Bootstrap', []))
35+
}
36+
},
37+
relay: {
38+
enabled: get(self._options, 'relay.enabled',
39+
get(config, 'relay.enabled', false)),
40+
hop: {
41+
enabled: get(self._options, 'relay.hop.enabled',
42+
get(config, 'relay.hop.enabled', false)),
43+
active: get(self._options, 'relay.hop.active',
44+
get(config, 'relay.hop.active', false))
45+
}
46+
},
47+
EXPERIMENTAL: {
48+
dht: get(self._options, 'EXPERIMENTAL.dht', false),
49+
pubsub: get(self._options, 'EXPERIMENTAL.pubsub', false)
3450
}
3551
}
3652
}
3753

38-
self._libp2pNode = new Node(self._peerInfo, self._peerInfoBook, options)
54+
const libp2pOptions = defaultsDeep(
55+
get(self._options, 'libp2p', {}),
56+
libp2pDefaults
57+
)
58+
59+
self._libp2pNode = new Node(libp2pOptions)
3960

4061
self._libp2pNode.on('peer:discovery', (peerInfo) => {
4162
const dial = () => {

src/core/config.js

+7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ const schema = Joi.object().keys({
1313
).allow(null),
1414
start: Joi.boolean(),
1515
pass: Joi.string().allow(''),
16+
relay: Joi.object().keys({
17+
enabled: Joi.boolean(),
18+
hop: Joi.object().keys({
19+
enabled: Joi.boolean(),
20+
active: Joi.boolean()
21+
}).allow(null)
22+
}).allow(null),
1623
EXPERIMENTAL: Joi.object().keys({
1724
pubsub: Joi.boolean(),
1825
sharding: Joi.boolean(),

src/core/index.js

-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ class IPFS extends EventEmitter {
3434
}
3535

3636
options = config.validate(options || {})
37-
this._libp2pModules = options.libp2p && options.libp2p.modules
3837

3938
extend(this._options, options)
4039

@@ -120,9 +119,6 @@ class IPFS extends EventEmitter {
120119
if (this._options.EXPERIMENTAL.dht) {
121120
this.log('EXPERIMENTAL Kademlia DHT is enabled')
122121
}
123-
if (this._options.EXPERIMENTAL.relay) {
124-
this.log('EXPERIMENTAL Relay is enabled')
125-
}
126122

127123
this.state = require('./state')(this)
128124

src/core/runtime/libp2p-browser.js

+42-26
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,54 @@ const WebRTCStar = require('libp2p-webrtc-star')
55
const WebSocketStar = require('libp2p-websocket-star')
66
const Multiplex = require('libp2p-mplex')
77
const SECIO = require('libp2p-secio')
8-
const Railing = require('libp2p-railing')
8+
const Bootstrap = require('libp2p-railing')
99
const libp2p = require('libp2p')
10+
const defaultsDeep = require('@nodeutils/defaults-deep')
1011

1112
class Node extends libp2p {
12-
constructor (peerInfo, peerBook, options) {
13-
options = options || {}
14-
const wrtcstar = new WebRTCStar({id: peerInfo.id})
15-
const wsstar = new WebSocketStar({id: peerInfo.id})
16-
17-
const modules = {
18-
transport: [new WS(), wrtcstar, wsstar],
19-
connection: {
20-
muxer: [Multiplex],
21-
crypto: [SECIO]
13+
constructor (_options) {
14+
const wrtcstar = new WebRTCStar({id: _options.peerInfo.id})
15+
const wsstar = new WebSocketStar({id: _options.peerInfo.id})
16+
17+
const defaults = {
18+
modules: {
19+
transport: [
20+
WS,
21+
wrtcstar,
22+
wsstar
23+
],
24+
streamMuxer: [
25+
Multiplex
26+
],
27+
connEncryption: [
28+
SECIO
29+
],
30+
peerDiscovery: [
31+
wrtcstar.discovery,
32+
wsstar.discovery,
33+
Bootstrap
34+
]
2235
},
23-
discovery: [wrtcstar.discovery, wsstar.discovery]
24-
}
25-
26-
if (options.bootstrap) {
27-
const r = new Railing(options.bootstrap)
28-
modules.discovery.push(r)
29-
}
30-
31-
if (options.modules && options.modules.transport) {
32-
options.modules.transport.forEach((t) => modules.transport.push(t))
33-
}
34-
35-
if (options.modules && options.modules.discovery) {
36-
options.modules.discovery.forEach((d) => modules.discovery.push(d))
36+
config: {
37+
peerDiscovery: {
38+
bootstrap: {
39+
enabled: true
40+
},
41+
webRTCStar: {
42+
enabled: true
43+
},
44+
websocketStar: {
45+
enabled: true
46+
}
47+
},
48+
EXPERIMENTAL: {
49+
dht: false,
50+
pubsub: false
51+
}
52+
}
3753
}
3854

39-
super(modules, peerInfo, peerBook, options)
55+
super(defaultsDeep(_options, defaults))
4056
}
4157
}
4258

0 commit comments

Comments
 (0)