Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: custom protocol name #962

Merged
merged 13 commits into from
Aug 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions doc/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,26 @@ By default under nodejs libp2p will attempt to use [UPnP](https://en.wikipedia.o

[NAT-PMP](http://miniupnp.free.fr/nat-pmp.html) is a feature of some modern routers which performs a similar job to UPnP. NAT-PMP is disabled by default, if enabled libp2p will try to use NAT-PMP and will fall back to UPnP if it fails.

#### Configuring protocol name

Changing the protocol name prefix can isolate default public network (IPFS) for custom purposes.

```js
const node = await Libp2p.create({
config: {
protocolPrefix: 'ipfs' // default
}
})
/*
protocols: [
"/ipfs/id/1.0.0", // identify service protocol (if we have multiplexers)
"/ipfs/id/push/1.0.0", // identify service push protocol (if we have multiplexers)
"/ipfs/ping/1.0.0", // built-in ping protocol
]
*/
```


## Configuration examples

As libp2p is designed to be a modular networking library, its usage will vary based on individual project needs. We've included links to some existing project configurations for your reference, in case you wish to replicate their configuration:
Expand Down
1 change: 1 addition & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const DefaultConfig = {
}
},
config: {
protocolPrefix: 'ipfs',
dht: {
enabled: false,
kBucketSize: 20,
Expand Down
12 changes: 9 additions & 3 deletions src/identify/consts.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
// @ts-ignore file not listed within the file list of projects
const libp2pVersion = require('../../package.json').version

module.exports.PROTOCOL_VERSION = 'ipfs/0.1.0'
module.exports.PROTOCOL_VERSION = 'ipfs/0.1.0' // deprecated
module.exports.AGENT_VERSION = `js-libp2p/${libp2pVersion}`
module.exports.MULTICODEC_IDENTIFY = '/ipfs/id/1.0.0'
module.exports.MULTICODEC_IDENTIFY_PUSH = '/ipfs/id/push/1.0.0'
module.exports.MULTICODEC_IDENTIFY = '/ipfs/id/1.0.0' // deprecated
module.exports.MULTICODEC_IDENTIFY_PUSH = '/ipfs/id/push/1.0.0' // deprecated

module.exports.IDENTIFY_PROTOCOL_VERSION = '0.1.0'
module.exports.MULTICODEC_IDENTIFY_PROTOCOL_NAME = 'id'
module.exports.MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME = 'id/push'
module.exports.MULTICODEC_IDENTIFY_PROTOCOL_VERSION = '1.0.0'
module.exports.MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION = '1.0.0'
32 changes: 25 additions & 7 deletions src/identify/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ const PeerRecord = require('../record/peer-record')
const {
MULTICODEC_IDENTIFY,
MULTICODEC_IDENTIFY_PUSH,
PROTOCOL_VERSION
IDENTIFY_PROTOCOL_VERSION,
MULTICODEC_IDENTIFY_PROTOCOL_NAME,
MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME,
MULTICODEC_IDENTIFY_PROTOCOL_VERSION,
MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION
} = require('./consts')

const { codes } = require('../errors')
Expand All @@ -39,6 +43,16 @@ const { codes } = require('../errors')
*/

class IdentifyService {
/**
* @param {import('../')} libp2p
*/
static getProtocolStr (libp2p) {
return {
identifyProtocolStr: `/${libp2p._config.protocolPrefix}/${MULTICODEC_IDENTIFY_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PROTOCOL_VERSION}`,
identifyPushProtocolStr: `/${libp2p._config.protocolPrefix}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_NAME}/${MULTICODEC_IDENTIFY_PUSH_PROTOCOL_VERSION}`
}
}

/**
* @class
* @param {Object} options
Expand All @@ -53,9 +67,13 @@ class IdentifyService {

this.handleMessage = this.handleMessage.bind(this)

const protocolStr = IdentifyService.getProtocolStr(libp2p)
this.identifyProtocolStr = protocolStr.identifyProtocolStr
this.identifyPushProtocolStr = protocolStr.identifyPushProtocolStr

// Store self host metadata
this._host = {
protocolVersion: PROTOCOL_VERSION,
protocolVersion: `${libp2p._config.protocolPrefix}/${IDENTIFY_PROTOCOL_VERSION}`,
...libp2p._options.host
}

Expand Down Expand Up @@ -94,7 +112,7 @@ class IdentifyService {

const pushes = connections.map(async connection => {
try {
const { stream } = await connection.newStream(MULTICODEC_IDENTIFY_PUSH)
const { stream } = await connection.newStream(this.identifyPushProtocolStr)

await pipe(
[Message.Identify.encode({
Expand Down Expand Up @@ -129,7 +147,7 @@ class IdentifyService {
const connections = []
let connection
for (const peer of this.peerStore.peers.values()) {
if (peer.protocols.includes(MULTICODEC_IDENTIFY_PUSH) && (connection = this.connectionManager.get(peer.id))) {
if (peer.protocols.includes(this.identifyPushProtocolStr) && (connection = this.connectionManager.get(peer.id))) {
connections.push(connection)
}
}
Expand All @@ -147,7 +165,7 @@ class IdentifyService {
* @returns {Promise<void>}
*/
async identify (connection) {
const { stream } = await connection.newStream(MULTICODEC_IDENTIFY)
const { stream } = await connection.newStream(this.identifyProtocolStr)
const [data] = await pipe(
[],
stream,
Expand Down Expand Up @@ -224,9 +242,9 @@ class IdentifyService {
*/
handleMessage ({ connection, stream, protocol }) {
switch (protocol) {
case MULTICODEC_IDENTIFY:
case this.identifyProtocolStr:
return this._handleIdentify({ connection, stream })
case MULTICODEC_IDENTIFY_PUSH:
case this.identifyPushProtocolStr:
return this._handlePush({ connection, stream })
default:
log.error('cannot handle unknown protocol %s', protocol)
Expand Down
3 changes: 1 addition & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const PersistentPeerStore = require('./peer-store/persistent')
const Registrar = require('./registrar')
const ping = require('./ping')
const IdentifyService = require('./identify')
const IDENTIFY_PROTOCOLS = IdentifyService.multicodecs
const NatManager = require('./nat-manager')
const { updateSelfPeerRecord } = require('./record/utils')

Expand Down Expand Up @@ -289,7 +288,7 @@ class Libp2p extends EventEmitter {

// Add the identify service since we can multiplex
this.identifyService = new IdentifyService({ libp2p: this })
this.handle(Object.values(IDENTIFY_PROTOCOLS), this.identifyService.handleMessage)
this.handle(Object.values(IdentifyService.getProtocolStr(this)), this.identifyService.handleMessage)
}

// Attach private network protector
Expand Down
6 changes: 4 additions & 2 deletions src/ping/constants.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use strict'

module.exports = {
PROTOCOL: '/ipfs/ping/1.0.0',
PING_LENGTH: 32
PROTOCOL: '/ipfs/ping/1.0.0', // deprecated
PING_LENGTH: 32,
PROTOCOL_VERSION: '1.0.0',
PROTOCOL_NAME: 'ping'
}
11 changes: 6 additions & 5 deletions src/ping/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const { toBuffer } = require('it-buffer')
const { collect, take } = require('streaming-iterables')
const equals = require('uint8arrays/equals')

const { PROTOCOL, PING_LENGTH } = require('./constants')
const { PROTOCOL_NAME, PING_LENGTH, PROTOCOL_VERSION } = require('./constants')

/**
* @typedef {import('../')} Libp2p
Expand All @@ -30,11 +30,12 @@ const { PROTOCOL, PING_LENGTH } = require('./constants')
* @returns {Promise<number>}
*/
async function ping (node, peer) {
const protocol = `/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`
// @ts-ignore multiaddr might not have toB58String
log('dialing %s to %s', PROTOCOL, peer.toB58String ? peer.toB58String() : peer)
log('dialing %s to %s', protocol, peer.toB58String ? peer.toB58String() : peer)

const connection = await node.dial(peer)
const { stream } = await connection.newStream(PROTOCOL)
const { stream } = await connection.newStream(protocol)

const start = Date.now()
const data = crypto.randomBytes(PING_LENGTH)
Expand All @@ -61,7 +62,7 @@ async function ping (node, peer) {
* @param {Libp2p} node
*/
function mount (node) {
node.handle(PROTOCOL, ({ stream }) => pipe(stream, stream))
node.handle(`/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`, ({ stream }) => pipe(stream, stream))
}

/**
Expand All @@ -70,7 +71,7 @@ function mount (node) {
* @param {Libp2p} node
*/
function unmount (node) {
node.unhandle(PROTOCOL)
node.unhandle(`/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`)
}

exports = module.exports = ping
Expand Down
47 changes: 47 additions & 0 deletions test/configuration/protocol-prefix.node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict'
/* eslint-env mocha */

const { expect } = require('aegir/utils/chai')
const mergeOptions = require('merge-options')

const { create } = require('../../src')
const { baseOptions } = require('./utils')

describe('Protocol prefix is configurable', () => {
let libp2p

it('protocolPrefix is provided', async () => {
const testProtocol = 'test-protocol'
libp2p = await create(mergeOptions(baseOptions, {
config: {
protocolPrefix: testProtocol
}
}))

const protocols = libp2p.peerStore.protoBook.get(libp2p.peerId);
[
'/libp2p/circuit/relay/0.1.0',
`/${testProtocol}/id/1.0.0`,
`/${testProtocol}/id/push/1.0.0`,
`/${testProtocol}/ping/1.0.0`
].forEach((i, idx) => {
expect(protocols[idx]).equals(i)
})
await libp2p.stop()
})

it('protocolPrefix is not provided', async () => {
libp2p = await create(baseOptions)

const protocols = libp2p.peerStore.protoBook.get(libp2p.peerId);
[
'/libp2p/circuit/relay/0.1.0',
'/ipfs/id/1.0.0',
'/ipfs/id/push/1.0.0',
'/ipfs/ping/1.0.0'
].forEach((i, idx) => {
expect(protocols[idx]).equals(i)
})
await libp2p.stop()
})
})
31 changes: 21 additions & 10 deletions test/identify/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ describe('Identify', () => {
peerStore: localPeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true,
_options: { host: {} }
_options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
}
})
const remoteIdentify = new IdentifyService({
Expand All @@ -70,7 +71,8 @@ describe('Identify', () => {
peerStore: remotePeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true,
_options: { host: {} }
_options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
}
})

Expand Down Expand Up @@ -119,7 +121,8 @@ describe('Identify', () => {
peerStore: localPeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true,
_options: { host: { agentVersion } }
_options: { host: { agentVersion } },
_config: { protocolPrefix: 'ipfs' }
}
})

Expand All @@ -131,7 +134,8 @@ describe('Identify', () => {
peerStore: remotePeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true,
_options: { host: { agentVersion } }
_options: { host: { agentVersion } },
_config: { protocolPrefix: 'ipfs' }
}
})

Expand Down Expand Up @@ -180,7 +184,8 @@ describe('Identify', () => {
connectionManager: new EventEmitter(),
peerStore: localPeerStore,
multiaddrs: [],
_options: { host: {} }
_options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
}
})
const remoteIdentify = new IdentifyService({
Expand All @@ -189,7 +194,8 @@ describe('Identify', () => {
connectionManager: new EventEmitter(),
peerStore: remotePeerStore,
multiaddrs: [],
_options: { host: {} }
_options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
}
})

Expand Down Expand Up @@ -231,7 +237,8 @@ describe('Identify', () => {
host: {
agentVersion
}
}
},
_config: { protocolPrefix: 'ipfs' }
},
protocols
})
Expand Down Expand Up @@ -261,7 +268,8 @@ describe('Identify', () => {
peerStore: localPeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true,
_options: { host: {} }
_options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
}
})

Expand All @@ -275,7 +283,8 @@ describe('Identify', () => {
peerStore: remotePeerStore,
multiaddrs: [],
isStarted: () => true,
_options: { host: {} }
_options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
}
})

Expand Down Expand Up @@ -333,7 +342,8 @@ describe('Identify', () => {
peerStore: localPeerStore,
multiaddrs: listenMaddrs,
isStarted: () => true,
_options: { host: {} }
_options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
}
})

Expand All @@ -347,6 +357,7 @@ describe('Identify', () => {
peerStore: new PeerStore({ peerId: remotePeer }),
multiaddrs: [],
_options: { host: {} },
_config: { protocolPrefix: 'ipfs' },
isStarted: () => true
}
})
Expand Down