feat: custom protocol name (#962)

Co-authored-by: mzdws <8580712+mzdws@user.noreply.gitee.com>
This commit is contained in:
greenSnot 2021-08-13 10:21:50 -04:00 committed by GitHub
parent 3b33fb4b73
commit ef24fabf02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 134 additions and 29 deletions

View File

@ -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. [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 ## 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: 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:

View File

@ -57,6 +57,7 @@ const DefaultConfig = {
} }
}, },
config: { config: {
protocolPrefix: 'ipfs',
dht: { dht: {
enabled: false, enabled: false,
kBucketSize: 20, kBucketSize: 20,

View File

@ -3,7 +3,13 @@
// @ts-ignore file not listed within the file list of projects // @ts-ignore file not listed within the file list of projects
const libp2pVersion = require('../../package.json').version 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.AGENT_VERSION = `js-libp2p/${libp2pVersion}`
module.exports.MULTICODEC_IDENTIFY = '/ipfs/id/1.0.0' module.exports.MULTICODEC_IDENTIFY = '/ipfs/id/1.0.0' // deprecated
module.exports.MULTICODEC_IDENTIFY_PUSH = '/ipfs/id/push/1.0.0' 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'

View File

@ -23,7 +23,11 @@ const PeerRecord = require('../record/peer-record')
const { const {
MULTICODEC_IDENTIFY, MULTICODEC_IDENTIFY,
MULTICODEC_IDENTIFY_PUSH, 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') } = require('./consts')
const { codes } = require('../errors') const { codes } = require('../errors')
@ -39,6 +43,16 @@ const { codes } = require('../errors')
*/ */
class IdentifyService { 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 * @class
* @param {Object} options * @param {Object} options
@ -53,9 +67,13 @@ class IdentifyService {
this.handleMessage = this.handleMessage.bind(this) this.handleMessage = this.handleMessage.bind(this)
const protocolStr = IdentifyService.getProtocolStr(libp2p)
this.identifyProtocolStr = protocolStr.identifyProtocolStr
this.identifyPushProtocolStr = protocolStr.identifyPushProtocolStr
// Store self host metadata // Store self host metadata
this._host = { this._host = {
protocolVersion: PROTOCOL_VERSION, protocolVersion: `${libp2p._config.protocolPrefix}/${IDENTIFY_PROTOCOL_VERSION}`,
...libp2p._options.host ...libp2p._options.host
} }
@ -94,7 +112,7 @@ class IdentifyService {
const pushes = connections.map(async connection => { const pushes = connections.map(async connection => {
try { try {
const { stream } = await connection.newStream(MULTICODEC_IDENTIFY_PUSH) const { stream } = await connection.newStream(this.identifyPushProtocolStr)
await pipe( await pipe(
[Message.Identify.encode({ [Message.Identify.encode({
@ -129,7 +147,7 @@ class IdentifyService {
const connections = [] const connections = []
let connection let connection
for (const peer of this.peerStore.peers.values()) { 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) connections.push(connection)
} }
} }
@ -147,7 +165,7 @@ class IdentifyService {
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async identify (connection) { async identify (connection) {
const { stream } = await connection.newStream(MULTICODEC_IDENTIFY) const { stream } = await connection.newStream(this.identifyProtocolStr)
const [data] = await pipe( const [data] = await pipe(
[], [],
stream, stream,
@ -224,9 +242,9 @@ class IdentifyService {
*/ */
handleMessage ({ connection, stream, protocol }) { handleMessage ({ connection, stream, protocol }) {
switch (protocol) { switch (protocol) {
case MULTICODEC_IDENTIFY: case this.identifyProtocolStr:
return this._handleIdentify({ connection, stream }) return this._handleIdentify({ connection, stream })
case MULTICODEC_IDENTIFY_PUSH: case this.identifyPushProtocolStr:
return this._handlePush({ connection, stream }) return this._handlePush({ connection, stream })
default: default:
log.error('cannot handle unknown protocol %s', protocol) log.error('cannot handle unknown protocol %s', protocol)

View File

@ -31,7 +31,6 @@ const PersistentPeerStore = require('./peer-store/persistent')
const Registrar = require('./registrar') const Registrar = require('./registrar')
const ping = require('./ping') const ping = require('./ping')
const IdentifyService = require('./identify') const IdentifyService = require('./identify')
const IDENTIFY_PROTOCOLS = IdentifyService.multicodecs
const NatManager = require('./nat-manager') const NatManager = require('./nat-manager')
const { updateSelfPeerRecord } = require('./record/utils') const { updateSelfPeerRecord } = require('./record/utils')
@ -289,7 +288,7 @@ class Libp2p extends EventEmitter {
// Add the identify service since we can multiplex // Add the identify service since we can multiplex
this.identifyService = new IdentifyService({ libp2p: this }) 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 // Attach private network protector

View File

@ -1,6 +1,8 @@
'use strict' 'use strict'
module.exports = { module.exports = {
PROTOCOL: '/ipfs/ping/1.0.0', PROTOCOL: '/ipfs/ping/1.0.0', // deprecated
PING_LENGTH: 32 PING_LENGTH: 32,
PROTOCOL_VERSION: '1.0.0',
PROTOCOL_NAME: 'ping'
} }

View File

@ -13,7 +13,7 @@ const { toBuffer } = require('it-buffer')
const { collect, take } = require('streaming-iterables') const { collect, take } = require('streaming-iterables')
const equals = require('uint8arrays/equals') const equals = require('uint8arrays/equals')
const { PROTOCOL, PING_LENGTH } = require('./constants') const { PROTOCOL_NAME, PING_LENGTH, PROTOCOL_VERSION } = require('./constants')
/** /**
* @typedef {import('../')} Libp2p * @typedef {import('../')} Libp2p
@ -30,11 +30,12 @@ const { PROTOCOL, PING_LENGTH } = require('./constants')
* @returns {Promise<number>} * @returns {Promise<number>}
*/ */
async function ping (node, peer) { async function ping (node, peer) {
const protocol = `/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`
// @ts-ignore multiaddr might not have toB58String // @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 connection = await node.dial(peer)
const { stream } = await connection.newStream(PROTOCOL) const { stream } = await connection.newStream(protocol)
const start = Date.now() const start = Date.now()
const data = crypto.randomBytes(PING_LENGTH) const data = crypto.randomBytes(PING_LENGTH)
@ -61,7 +62,7 @@ async function ping (node, peer) {
* @param {Libp2p} node * @param {Libp2p} node
*/ */
function mount (node) { function mount (node) {
node.handle(PROTOCOL, ({ stream }) => pipe(stream, stream)) node.handle(`/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`, ({ stream }) => pipe(stream, stream))
} }
/** /**
@ -70,7 +71,7 @@ function mount (node) {
* @param {Libp2p} node * @param {Libp2p} node
*/ */
function unmount (node) { function unmount (node) {
node.unhandle(PROTOCOL) node.unhandle(`/${node._config.protocolPrefix}/${PROTOCOL_NAME}/${PROTOCOL_VERSION}`)
} }
exports = module.exports = ping exports = module.exports = ping

View File

@ -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()
})
})

View File

@ -60,7 +60,8 @@ describe('Identify', () => {
peerStore: localPeerStore, peerStore: localPeerStore,
multiaddrs: listenMaddrs, multiaddrs: listenMaddrs,
isStarted: () => true, isStarted: () => true,
_options: { host: {} } _options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
const remoteIdentify = new IdentifyService({ const remoteIdentify = new IdentifyService({
@ -70,7 +71,8 @@ describe('Identify', () => {
peerStore: remotePeerStore, peerStore: remotePeerStore,
multiaddrs: listenMaddrs, multiaddrs: listenMaddrs,
isStarted: () => true, isStarted: () => true,
_options: { host: {} } _options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
@ -119,7 +121,8 @@ describe('Identify', () => {
peerStore: localPeerStore, peerStore: localPeerStore,
multiaddrs: listenMaddrs, multiaddrs: listenMaddrs,
isStarted: () => true, isStarted: () => true,
_options: { host: { agentVersion } } _options: { host: { agentVersion } },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
@ -131,7 +134,8 @@ describe('Identify', () => {
peerStore: remotePeerStore, peerStore: remotePeerStore,
multiaddrs: listenMaddrs, multiaddrs: listenMaddrs,
isStarted: () => true, isStarted: () => true,
_options: { host: { agentVersion } } _options: { host: { agentVersion } },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
@ -180,7 +184,8 @@ describe('Identify', () => {
connectionManager: new EventEmitter(), connectionManager: new EventEmitter(),
peerStore: localPeerStore, peerStore: localPeerStore,
multiaddrs: [], multiaddrs: [],
_options: { host: {} } _options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
const remoteIdentify = new IdentifyService({ const remoteIdentify = new IdentifyService({
@ -189,7 +194,8 @@ describe('Identify', () => {
connectionManager: new EventEmitter(), connectionManager: new EventEmitter(),
peerStore: remotePeerStore, peerStore: remotePeerStore,
multiaddrs: [], multiaddrs: [],
_options: { host: {} } _options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
@ -231,7 +237,8 @@ describe('Identify', () => {
host: { host: {
agentVersion agentVersion
} }
} },
_config: { protocolPrefix: 'ipfs' }
}, },
protocols protocols
}) })
@ -261,7 +268,8 @@ describe('Identify', () => {
peerStore: localPeerStore, peerStore: localPeerStore,
multiaddrs: listenMaddrs, multiaddrs: listenMaddrs,
isStarted: () => true, isStarted: () => true,
_options: { host: {} } _options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
@ -275,7 +283,8 @@ describe('Identify', () => {
peerStore: remotePeerStore, peerStore: remotePeerStore,
multiaddrs: [], multiaddrs: [],
isStarted: () => true, isStarted: () => true,
_options: { host: {} } _options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
@ -333,7 +342,8 @@ describe('Identify', () => {
peerStore: localPeerStore, peerStore: localPeerStore,
multiaddrs: listenMaddrs, multiaddrs: listenMaddrs,
isStarted: () => true, isStarted: () => true,
_options: { host: {} } _options: { host: {} },
_config: { protocolPrefix: 'ipfs' }
} }
}) })
@ -347,6 +357,7 @@ describe('Identify', () => {
peerStore: new PeerStore({ peerId: remotePeer }), peerStore: new PeerStore({ peerId: remotePeer }),
multiaddrs: [], multiaddrs: [],
_options: { host: {} }, _options: { host: {} },
_config: { protocolPrefix: 'ipfs' },
isStarted: () => true isStarted: () => true
} }
}) })