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

Commit ca025fa

Browse files
jacobheunalanshaw
authored andcommitted
feat: add libp2p factory config option with example (#1470)
Resolves #1463 and libp2p/js-libp2p#222 This adds the ability to pass a libp2p generator function to the ipfs configuration. This makes it easier for users to add custom modules to libp2p that require some startup time properties, like peerInfo (libp2p/js-libp2p#222). I have also included an example of how to do this. I think this makes complex libp2p configuration much cleaner and easier to do. Tests have been added for the old configuration options and the new generator option. I isolated them to avoid spinning up a full ipfs node.
1 parent adaba08 commit ca025fa

File tree

4 files changed

+171
-0
lines changed

4 files changed

+171
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Let us know if you find any issue or if you want to contribute and add a new tut
2323
- [js-ipfs in electron](./run-in-electron)
2424
- [Using streams to add a directory of files to ipfs](./browser-add-readable-stream)
2525
- [Customizing the ipfs repository](./custom-ipfs-repo)
26+
- [Customizing your libp2p bundle](./custom-libp2p)
2627
- [Streaming video from ipfs to the browser using `ReadableStream`s](./browser-readablestream)
2728
- [The Mutable File System in the browser](./browser-mfs)
2829

custom-libp2p/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Customizing your libp2p bundle
2+
3+
This example shows you how to make full use of the ipfs configuration to create a libp2p bundle function. As IPFS applications become more complex, their needs for a custom libp2p bundle also grow. Instead of fighting with configuration options, you can use your own libp2p bundle function to get exactly what you need.
4+
5+
## Run this example
6+
7+
Running this example should result in metrics being logged out to the console every few seconds.
8+
9+
```
10+
> npm install
11+
> npm start
12+
```
13+
14+
## Play with the configuration!
15+
16+
With the metrics for peers and bandwidth stats being logged out, try playing around with the nodes configuration to see what kind of metrics you can get. How many peers are you getting? What does your bandwidth look like?
17+
18+
This is also a good opportunity to explore the various stats that ipfs offers! Not seeing a statistic you think would be useful? We'd love to have you [contribute](https://github.com/ipfs/js-ipfs/blob/master/CONTRIBUTING.md)!

custom-libp2p/index.js

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
'use strict'
2+
3+
const Libp2p = require('libp2p')
4+
const IPFS = require('ipfs')
5+
const TCP = require('libp2p-tcp')
6+
const MulticastDNS = require('libp2p-mdns')
7+
const WebSocketStar = require('libp2p-websocket-star')
8+
const Bootstrap = require('libp2p-railing')
9+
const SPDY = require('libp2p-spdy')
10+
const KadDHT = require('libp2p-kad-dht')
11+
const MPLEX = require('libp2p-mplex')
12+
const SECIO = require('libp2p-secio')
13+
const assert = require('assert')
14+
15+
/**
16+
* Options for the libp2p bundle
17+
* @typedef {Object} libp2pBundle~options
18+
* @property {PeerInfo} peerInfo - The PeerInfo of the IPFS node
19+
* @property {PeerBook} peerBook - The PeerBook of the IPFS node
20+
* @property {Object} config - The config of the IPFS node
21+
* @property {Object} options - The options given to the IPFS node
22+
*/
23+
24+
/**
25+
* This is the bundle we will use to create our fully customized libp2p bundle.
26+
*
27+
* @param {libp2pBundle~options} opts The options to use when generating the libp2p node
28+
* @returns {Libp2p} Our new libp2p node
29+
*/
30+
const libp2pBundle = (opts) => {
31+
// Set convenience variables to clearly showcase some of the useful things that are available
32+
const peerInfo = opts.peerInfo
33+
const peerBook = opts.peerBook
34+
const bootstrapList = opts.config.Bootstrap
35+
36+
// Create our WebSocketStar transport and give it our PeerId, straight from the ipfs node
37+
const wsstar = new WebSocketStar({
38+
id: peerInfo.id
39+
})
40+
41+
// Build and return our libp2p node
42+
return new Libp2p({
43+
peerInfo,
44+
peerBook,
45+
// Lets limit the connection managers peers and have it check peer health less frequently
46+
connectionManager: {
47+
maxPeers: 25,
48+
pollInterval: 5000
49+
},
50+
modules: {
51+
transport: [
52+
TCP,
53+
wsstar
54+
],
55+
streamMuxer: [
56+
MPLEX,
57+
SPDY
58+
],
59+
connEncryption: [
60+
SECIO
61+
],
62+
peerDiscovery: [
63+
MulticastDNS,
64+
Bootstrap,
65+
wsstar.discovery
66+
],
67+
dht: KadDHT
68+
},
69+
config: {
70+
peerDiscovery: {
71+
mdns: {
72+
interval: 10000,
73+
enabled: true
74+
},
75+
bootstrap: {
76+
interval: 10000,
77+
enabled: true,
78+
list: bootstrapList
79+
}
80+
},
81+
// Turn on relay with hop active so we can connect to more peers
82+
relay: {
83+
enabled: true,
84+
hop: {
85+
enabled: true,
86+
active: true
87+
}
88+
},
89+
dht: {
90+
kBucketSize: 20
91+
},
92+
EXPERIMENTAL: {
93+
dht: true,
94+
pubsub: true
95+
}
96+
}
97+
})
98+
}
99+
100+
// Now that we have our custom libp2p bundle, let's start up the ipfs node!
101+
const node = new IPFS({
102+
libp2p: libp2pBundle
103+
})
104+
105+
// Listen for the node to start, so we can log out some metrics
106+
node.once('start', (err) => {
107+
assert.ifError(err, 'Should startup without issue')
108+
109+
// Lets log out the number of peers we have every 2 seconds
110+
setInterval(() => {
111+
node.swarm.peers((err, peers) => {
112+
if (err) {
113+
console.log('An error occurred trying to check our peers:', err)
114+
process.exit(1)
115+
}
116+
console.log(`The node now has ${peers.length} peers.`)
117+
})
118+
}, 2000)
119+
120+
// Log out the bandwidth stats every 4 seconds so we can see how our configuration is doing
121+
setInterval(() => {
122+
node.stats.bw((err, stats) => {
123+
if (err) {
124+
console.log('An error occurred trying to check our stats:', err)
125+
}
126+
console.log(`\nBandwidth Stats: ${JSON.stringify(stats, null, 2)}\n`)
127+
})
128+
}, 4000)
129+
})

custom-libp2p/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "custom-libp2p",
3+
"version": "0.1.0",
4+
"description": "Customizing your libp2p node",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1",
8+
"start": "node index.js"
9+
},
10+
"license": "MIT",
11+
"dependencies": {
12+
"ipfs": "file:../../",
13+
"libp2p": "~0.22.0",
14+
"libp2p-kad-dht": "~0.10.1",
15+
"libp2p-mdns": "~0.12.0",
16+
"libp2p-mplex": "~0.8.0",
17+
"libp2p-railing": "~0.9.2",
18+
"libp2p-secio": "~0.10.0",
19+
"libp2p-spdy": "~0.12.1",
20+
"libp2p-tcp": "~0.12.0",
21+
"libp2p-websocket-star": "~0.8.1"
22+
}
23+
}

0 commit comments

Comments
 (0)