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

Two peers with same Identity #1316

Closed
vmx opened this issue Apr 19, 2018 · 2 comments · Fixed by #1324
Closed

Two peers with same Identity #1316

vmx opened this issue Apr 19, 2018 · 2 comments · Fixed by #1324

Comments

@vmx
Copy link
Member

vmx commented Apr 19, 2018

If you create two nodes in parallel, then they end up having the same Identity. When the script below is run you end up with configuration files which contain the same Identity:

$ diff /tmp/peera/config /tmp/peerb/config
4,5c4,5
<       "/ip4/0.0.0.0/tcp/4012",
<       "/ip4/127.0.0.1/tcp/4013/ws"
---
>       "/ip4/0.0.0.0/tcp/4022",
>       "/ip4/127.0.0.1/tcp/4023/ws"
7,8c7,8
<     "API": "/ip4/127.0.0.1/tcp/5012",
<     "Gateway": "/ip4/127.0.0.1/tcp/9091"
---
>     "API": "/ip4/127.0.0.1/tcp/5022",
>     "Gateway": "/ip4/127.0.0.1/tcp/9092"

I tried this on js-ipfs master (64c3bfb).

I debugged it a bit, but then I hit a dead end. I don't really understand how the initial configuration is created. It seems that some default configuration is written to disk, which is then overridden.

'use strict'

const IPFS = require('ipfs')


const configA = {
  "Addresses": {
    "API": "/ip4/127.0.0.1/tcp/5012",
    "Gateway": "/ip4/127.0.0.1/tcp/9091",
    "Swarm": [
      "/ip4/0.0.0.0/tcp/4012",
      "/ip4/127.0.0.1/tcp/4013/ws"
    ]
  },
  "Bootstrap": []
}
const peerA = new IPFS({
  repo: '/tmp/peera',
  config: configA,
  init: {
    emptyRepo: true
  }
})
peerA.on('ready', () => {
  console.log('peerA ready')
})

const configB = {
  "Addresses": {
    "API": "/ip4/127.0.0.1/tcp/5022",
    "Gateway": "/ip4/127.0.0.1/tcp/9092",
    "Swarm": [
      "/ip4/0.0.0.0/tcp/4022",
      "/ip4/127.0.0.1/tcp/4023/ws"
    ]
  },
  "Bootstrap": []
}
const peerB = new IPFS({
  repo: '/tmp/peerb',
  config: configB,
  init: {
    emptyRepo: true
  }
})
peerB.on('ready', () => {
  console.log('peerB ready')
})
@Mr0grog
Copy link
Contributor

Mr0grog commented Apr 19, 2018

Oh, geez, I see the problem. In init.js, we pull in the default config as a singleton JSON object, then we proceed to customize it without first making a copy. So any nodes in the same process are making changes to the same singleton.

I wonder if a better solution is to make it a function that returns a new config object. Otherwise every consumer needs to be careful about copying first.

Mr0grog added a commit to Mr0grog/js-ipfs that referenced this issue Apr 23, 2018
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>
@daviddias
Copy link
Member

Excellent catch! Thanks for fixing it @Mr0grog on #1324 👌🏽

daviddias pushed a commit that referenced this issue Apr 30, 2018
…ing it doubly used (#1324)

* 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 #1316.

License: MIT
Signed-off-by: Rob Brackett <rob@robbrackett.com>

* Fix lint errors

License: MIT
Signed-off-by: Rob Brackett <rob@robbrackett.com>
This was referenced Nov 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants