diff --git a/doc/API.md b/doc/API.md index ee4af9c7d3..7937cf8370 100644 --- a/doc/API.md +++ b/doc/API.md @@ -85,17 +85,17 @@ Creates an instance of Libp2p. | Name | Type | Description | |------|------|-------------| | options | `object` | libp2p options | -| options.modules | [`Array`](./CONFIGURATION.md#modules) | libp2p modules to use | +| options.modules | [`Array`](./CONFIGURATION.md#modules) | libp2p [modules](./CONFIGURATION.md#modules) to use | | [options.addresses] | `{ listen: Array, announce: Array, noAnnounce: Array }` | Addresses for transport listening and to advertise to the network | | [options.config] | `object` | libp2p modules configuration and core configuration | -| [options.connectionManager] | [`object`](./CONFIGURATION.md#configuring-connection-manager) | libp2p Connection Manager configuration | -| [options.transportManager] | [`object`](./CONFIGURATION.md#configuring-transport-manager) | libp2p transport manager configuration | +| [options.connectionManager] | [`object`](./CONFIGURATION.md#configuring-connection-manager) | libp2p Connection Manager [configuration](./CONFIGURATION.md#configuring-connection-manager) | +| [options.transportManager] | [`object`](./CONFIGURATION.md#configuring-transport-manager) | libp2p transport manager [configuration]((./CONFIGURATION.md#configuring-transport-manager)) | | [options.datastore] | `object` | must implement [ipfs/interface-datastore](https://github.com/ipfs/interface-datastore) (in memory datastore will be used if not provided) | -| [options.dialer] | [`object`](./CONFIGURATION.md#configuring-dialing) | libp2p Dialer configuration -| [options.keychain] | [`object`](./CONFIGURATION.md#setup-with-keychain) | keychain configuration | -| [options.metrics] | [`object`](./CONFIGURATION.md#configuring-metrics) | libp2p Metrics configuration +| [options.dialer] | [`object`](./CONFIGURATION.md#configuring-dialing) | libp2p Dialer [configuration]((./CONFIGURATION.md#configuring-dialing)) +| [options.keychain] | [`object`](./CONFIGURATION.md#setup-with-keychain) | keychain [configuration]((./CONFIGURATION.md#setup-with-keychain)) | +| [options.metrics] | [`object`](./CONFIGURATION.md#configuring-metrics) | libp2p Metrics [configuration]((./CONFIGURATION.md#configuring-metrics)) | | [options.peerId] | [`PeerId`][peer-id] | peerId instance (it will be created if not provided) | -| [options.peerStore] | [`object`](./CONFIGURATION.md#configuring-peerstore) | libp2p PeerStore configuration | +| [options.peerStore] | [`object`](./CONFIGURATION.md#configuring-peerstore) | libp2p PeerStore [configuration]((./CONFIGURATION.md#configuring-peerstore)) | For Libp2p configurations and modules details read the [Configuration Document](./CONFIGURATION.md). diff --git a/doc/CONFIGURATION.md b/doc/CONFIGURATION.md index 490f389034..72acb8683f 100644 --- a/doc/CONFIGURATION.md +++ b/doc/CONFIGURATION.md @@ -52,7 +52,7 @@ The libp2p ecosystem contains at least one module for each of these subsystems. After selecting the modules to use, it is also possible to configure each one according to your needs. -Bear in mind that only a **transport** and **connection encryption** are required, while all the other subsystems are optional. +Bear in mind that a **transport** and **connection encryption** are **required**, while all the other subsystems are optional. ### Transport diff --git a/examples/discovery-mechanisms/2.js b/examples/discovery-mechanisms/2.js index 2beb812e00..3481675c7b 100644 --- a/examples/discovery-mechanisms/2.js +++ b/examples/discovery-mechanisms/2.js @@ -21,7 +21,7 @@ const createNode = async () => { }, config: { peerDiscovery: { - mdns: { + [MulticastDNS.tag]: { interval: 20e3, enabled: true } diff --git a/src/errors.js b/src/errors.js index ab8f21369d..c47043e604 100644 --- a/src/errors.js +++ b/src/errors.js @@ -2,13 +2,15 @@ exports.messages = { NOT_STARTED_YET: 'The libp2p node is not started yet', - DHT_DISABLED: 'DHT is not available' + DHT_DISABLED: 'DHT is not available', + CONN_ENCRYPTION_REQUIRED: 'At least one connection encryption module is required' } exports.codes = { DHT_DISABLED: 'ERR_DHT_DISABLED', PUBSUB_NOT_STARTED: 'ERR_PUBSUB_NOT_STARTED', DHT_NOT_STARTED: 'ERR_DHT_NOT_STARTED', + CONN_ENCRYPTION_REQUIRED: 'ERR_CONN_ENCRYPTION_REQUIRED', ERR_CONNECTION_ENDED: 'ERR_CONNECTION_ENDED', ERR_CONNECTION_FAILED: 'ERR_CONNECTION_FAILED', ERR_NODE_NOT_STARTED: 'ERR_NODE_NOT_STARTED', diff --git a/src/index.js b/src/index.js index ad7a78281c..1c27d6184b 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ const globalThis = require('ipfs-utils/src/globalthis') const log = debug('libp2p') log.error = debug('libp2p:error') +const errCode = require('err-code') const PeerId = require('peer-id') const peerRouting = require('./peer-routing') @@ -13,7 +14,7 @@ const contentRouting = require('./content-routing') const pubsub = require('./pubsub') const getPeer = require('./get-peer') const { validate: validateConfig } = require('./config') -const { codes } = require('./errors') +const { codes, messages } = require('./errors') const AddressManager = require('./address-manager') const ConnectionManager = require('./connection-manager') @@ -115,12 +116,13 @@ class Libp2p extends EventEmitter { this.registrar.handle = this.handle // Attach crypto channels - if (this._modules.connEncryption) { - const cryptos = this._modules.connEncryption - cryptos.forEach((crypto) => { - this.upgrader.cryptos.set(crypto.protocol, crypto) - }) + if (!this._modules.connEncryption || !this._modules.connEncryption.length) { + throw errCode(new Error(messages.CONN_ENCRYPTION_REQUIRED), codes.CONN_ENCRYPTION_REQUIRED) } + const cryptos = this._modules.connEncryption + cryptos.forEach((crypto) => { + this.upgrader.cryptos.set(crypto.protocol, crypto) + }) this.dialer = new Dialer({ transportManager: this.transportManager, diff --git a/test/core/encryption.spec.js b/test/core/encryption.spec.js new file mode 100644 index 0000000000..1173828568 --- /dev/null +++ b/test/core/encryption.spec.js @@ -0,0 +1,57 @@ +'use strict' +/* eslint-env mocha */ + +const chai = require('chai') +chai.use(require('dirty-chai')) +chai.use(require('chai-as-promised')) +const { expect } = chai + +const Transport = require('libp2p-websockets') +const { NOISE: Crypto } = require('libp2p-noise') + +const Libp2p = require('../../src') +const { codes: ErrorCodes } = require('../../src/errors') +const { createPeerId } = require('../utils/creators/peer') + +describe('Connection encryption configuration', () => { + let peerId + + before(async () => { + [peerId] = await createPeerId() + }) + + it('is required', async () => { + const config = { + peerId, + modules: { + transport: [Transport] + } + } + + await expect(Libp2p.create(config)).to.eventually.be.rejected() + .and.to.have.property('code', ErrorCodes.CONN_ENCRYPTION_REQUIRED) + }) + + it('is required and needs at least one module', async () => { + const config = { + peerId, + modules: { + transport: [Transport], + connEncryption: [] + } + } + await expect(Libp2p.create(config)).to.eventually.be.rejected() + .and.to.have.property('code', ErrorCodes.CONN_ENCRYPTION_REQUIRED) + }) + + it('can be created', async () => { + const config = { + peerId, + modules: { + transport: [Transport], + connEncryption: [Crypto] + } + } + await Libp2p.create(config) + }) +}) diff --git a/test/core/listening.node.js b/test/core/listening.node.js index 14622d233a..46976733c5 100644 --- a/test/core/listening.node.js +++ b/test/core/listening.node.js @@ -6,6 +6,7 @@ chai.use(require('dirty-chai')) const { expect } = chai const Transport = require('libp2p-tcp') +const { NOISE: Crypto } = require('libp2p-noise') const { create } = require('../../src') const peerUtils = require('../utils/creators/peer') @@ -31,7 +32,8 @@ describe('Listening', () => { listen: [listenAddr] }, modules: { - transport: [Transport] + transport: [Transport], + connEncryption: [Crypto] } }) diff --git a/test/transports/transport-manager.spec.js b/test/transports/transport-manager.spec.js index 0acc4b8660..b32b280725 100644 --- a/test/transports/transport-manager.spec.js +++ b/test/transports/transport-manager.spec.js @@ -9,6 +9,7 @@ const sinon = require('sinon') const multiaddr = require('multiaddr') const Transport = require('libp2p-websockets') +const { NOISE: Crypto } = require('libp2p-noise') const AddressManager = require('../../src/address-manager') const TransportManager = require('../../src/transport-manager') const mockUpgrader = require('../utils/mockUpgrader') @@ -110,7 +111,8 @@ describe('libp2p.transportManager', () => { libp2p = new Libp2p({ peerId, modules: { - transport: [Transport] + transport: [Transport], + connEncryption: [Crypto] } }) @@ -128,7 +130,8 @@ describe('libp2p.transportManager', () => { libp2p = new Libp2p({ peerId, modules: { - transport: [spy] + transport: [spy], + connEncryption: [Crypto] }, config: { transport: { @@ -152,7 +155,8 @@ describe('libp2p.transportManager', () => { libp2p = new Libp2p({ peerId, modules: { - transport: [Transport] + transport: [Transport], + connEncryption: [Crypto] } }) @@ -188,7 +192,8 @@ describe('libp2p.transportManager (dial only)', () => { listen: [multiaddr('/ip4/127.0.0.1/tcp/0')] }, modules: { - transport: [Transport] + transport: [Transport], + connEncryption: [Crypto] } }) @@ -212,7 +217,8 @@ describe('libp2p.transportManager (dial only)', () => { faultTolerance: FaultTolerance.NO_FATAL }, modules: { - transport: [Transport] + transport: [Transport], + connEncryption: [Crypto] } })