mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-04-25 10:32:14 +00:00
feat: custom protocol name (#962)
Co-authored-by: mzdws <8580712+mzdws@user.noreply.gitee.com>
This commit is contained in:
parent
3b33fb4b73
commit
ef24fabf02
@ -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:
|
||||||
|
@ -57,6 +57,7 @@ const DefaultConfig = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
config: {
|
config: {
|
||||||
|
protocolPrefix: 'ipfs',
|
||||||
dht: {
|
dht: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
kBucketSize: 20,
|
kBucketSize: 20,
|
||||||
|
@ -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'
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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'
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
47
test/configuration/protocol-prefix.node.js
Normal file
47
test/configuration/protocol-prefix.node.js
Normal 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()
|
||||||
|
})
|
||||||
|
})
|
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user