Skip to content

Commit fde8227

Browse files
committed
Change default config from JSON file to JS module
Because the default config was a JSON file, it was treated as a singleton object. In some parts of the code, data got added to it, leading to race conditions when creating multiple nodes simultaneously. To make that harder to do accidentally, the default config is now a *function* that returns a unique configuration object on each call. Fixes ipfs#1316. License: MIT Signed-off-by: Rob Brackett <rob@robbrackett.com>
1 parent 64c3bfb commit fde8227

File tree

9 files changed

+66
-12
lines changed

9 files changed

+66
-12
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ Creates and returns an instance of an IPFS node. Use the `options` argument to s
227227
- `enabled` (boolean): Make this node a relay (other nodes can connect *through* it). (Default: `false`)
228228
- `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`)
229229

230-
- `config` (object) Modify the default IPFS node config. Find the Node.js defaults at [`src/core/runtime/config-nodejs.json`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-nodejs.json) and the browser defaults at [`src/core/runtime/config-browser.json`](https://github.com/ipfs/js-ipfs/tree/master/src/core/runtime/config-browser.json). This object will be *merged* with the default config; it will not replace it.
230+
- `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.
231231

232232
- `libp2p` (object) add custom modules to the libp2p stack of your node
233233
- `modules` (object):

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"main": "src/core/index.js",
99
"browser": {
1010
"./src/core/components/init-assets.js": false,
11-
"./src/core/runtime/config-nodejs.json": "./src/core/runtime/config-browser.json",
11+
"./src/core/runtime/config-nodejs.js": "./src/core/runtime/config-browser.js",
1212
"./src/core/runtime/libp2p-nodejs.js": "./src/core/runtime/libp2p-browser.js",
1313
"./src/core/runtime/repo-nodejs.js": "./src/core/runtime/repo-browser.js",
1414
"./src/core/runtime/dns-nodejs.js": "./src/core/runtime/dns-browser.js",

src/core/components/bootstrap.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22

3-
const defaultNodes = require('../runtime/config-nodejs.json').Bootstrap
3+
const defaultConfig = require('../runtime/config-nodejs.js')
44
const isMultiaddr = require('mafmt').IPFS.matches
55
const promisify = require('promisify-es6')
66

@@ -41,7 +41,7 @@ module.exports = function bootstrap (self) {
4141
return callback(err)
4242
}
4343
if (args.default) {
44-
config.Bootstrap = defaultNodes
44+
config.Bootstrap = defaultConfig().Bootstrap
4545
} else if (multiaddr && config.Bootstrap.indexOf(multiaddr) === -1) {
4646
config.Bootstrap.push(multiaddr)
4747
}
@@ -51,7 +51,7 @@ module.exports = function bootstrap (self) {
5151
}
5252

5353
callback(null, {
54-
Peers: args.default ? defaultNodes : [multiaddr]
54+
Peers: args.default ? defaultConfig().Bootstrap : [multiaddr]
5555
})
5656
})
5757
})

src/core/components/init.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const peerId = require('peer-id')
44
const waterfall = require('async/waterfall')
55
const parallel = require('async/parallel')
66
const promisify = require('promisify-es6')
7-
const config = require('../runtime/config-nodejs.json')
7+
const defaultConfig = require('../runtime/config-nodejs.js')
88
const Keychain = require('libp2p-keychain')
99

1010
const addDefaultAssets = require('./init-assets')
@@ -37,6 +37,7 @@ module.exports = function init (self) {
3737
opts.emptyRepo = opts.emptyRepo || false
3838
opts.bits = Number(opts.bits) || 2048
3939
opts.log = opts.log || function () {}
40+
const config = defaultConfig()
4041
let privateKey
4142
waterfall([
4243
// Verify repo does not yet exist.

src/core/runtime/config-browser.json renamed to src/core/runtime/config-browser.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
{
1+
'use strict'
2+
3+
module.exports = () => ({
24
"Addresses": {
35
"Swarm": [
46
],
@@ -24,4 +26,4 @@
2426
"/dns4/wss0.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic",
2527
"/dns4/wss1.bootstrap.libp2p.io/tcp/443/wss/ipfs/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6"
2628
]
27-
}
29+
})

src/core/runtime/config-nodejs.json renamed to src/core/runtime/config-nodejs.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
{
1+
'use strict'
2+
3+
module.exports = () => ({
24
"Addresses": {
35
"Swarm": [
46
"/ip4/0.0.0.0/tcp/4002",
@@ -37,4 +39,4 @@
3739
"/dns4/wss0.bootstrap.libp2p.io/tcp/443/wss/ipfs/QmZMxNdpMkewiVZLMRxaNxUeZpDUb34pWjZ1kZvsd16Zic",
3840
"/dns4/wss1.bootstrap.libp2p.io/tcp/443/wss/ipfs/Qmbut9Ywz9YEDrz8ySBSgWyJk41Uvm2QJPhwDJzJyGFsD6"
3941
]
40-
}
42+
})

test/bootstrapers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const dirtyChai = require('dirty-chai')
66
const expect = chai.expect
77
chai.use(dirtyChai)
88
const IPFS = require('..')
9-
const list = require('../src/core/runtime/config-browser.json').Bootstrap
9+
const list = require('../src/core/runtime/config-browser.js')().Bootstrap
1010

1111
/*
1212
* These tests were graciously made for lgierth, so that he can test the

test/core/create-node.spec.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const dirtyChai = require('dirty-chai')
77
const expect = chai.expect
88
chai.use(dirtyChai)
99
const series = require('async/series')
10+
const waterfall = require('async/waterfall')
11+
const parallel = require('async/parallel')
1012
const os = require('os')
1113
const path = require('path')
1214
const hat = require('hat')
@@ -305,4 +307,51 @@ describe('create node', function () {
305307
(cb) => node.stop(cb)
306308
], done)
307309
})
310+
311+
it('does not share identity with a simultaneously created node', function (done) {
312+
this.timeout(80 * 1000)
313+
314+
let _nodeNumber = 0;
315+
function createNode () {
316+
_nodeNumber++;
317+
return new IPFS({
318+
repo: createTempRepo(),
319+
init: { emptyRepo: true },
320+
config: {
321+
Addresses: {
322+
API: `/ip4/127.0.0.1/tcp/${5010 + _nodeNumber}`,
323+
Gateway: `/ip4/127.0.0.1/tcp/${9090 + _nodeNumber}`,
324+
Swarm: [
325+
`/ip4/0.0.0.0/tcp/${4010 + _nodeNumber * 2}`,
326+
`/ip4/127.0.0.1/tcp/${4011 + _nodeNumber * 2}/ws`
327+
]
328+
},
329+
Bootstrap: []
330+
}
331+
})
332+
}
333+
334+
const nodeA = createNode()
335+
const nodeB = createNode()
336+
337+
waterfall([
338+
(cb) => parallel([
339+
(cb) => nodeA.once('start', cb),
340+
(cb) => nodeB.once('start', cb)
341+
], cb),
342+
(_, cb) => parallel([
343+
(cb) => nodeA.id(cb),
344+
(cb) => nodeB.id(cb)
345+
], cb),
346+
([idA, idB], cb) => {
347+
expect(idA.id).to.not.equal(idB.id)
348+
cb()
349+
}
350+
], (error) => {
351+
parallel([
352+
(cb) => nodeA.stop(cb),
353+
(cb) => nodeB.stop(cb)
354+
], (stopError) => done(error || stopError))
355+
})
356+
})
308357
})

test/http-api/inject/bootstrap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
const expect = require('chai').expect
55
const qs = require('qs')
6-
const defaultList = require('../../../src/core/runtime/config-nodejs.json').Bootstrap
6+
const defaultList = require('../../../src/core/runtime/config-nodejs.js')().Bootstrap
77

88
module.exports = (http) => {
99
describe('/bootstrap', () => {

0 commit comments

Comments
 (0)