mirror of
https://github.com/fluencelabs/js-libp2p
synced 2025-07-24 04:51:56 +00:00
Compare commits
7 Commits
v0.30.12
...
chore/prod
Author | SHA1 | Date | |
---|---|---|---|
|
7435ebd06a | ||
|
900f8ae524 | ||
|
92b5b783f9 | ||
|
71eda21feb | ||
|
44ce1a2a3a | ||
|
fb75728682 | ||
|
fe35c3cea0 |
0
doc/production/CIRCUIT_RELAY.md
Normal file
0
doc/production/CIRCUIT_RELAY.md
Normal file
90
doc/production/DELEGATE_NODES.md
Normal file
90
doc/production/DELEGATE_NODES.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Delegate Nodes with IPFS
|
||||
|
||||
This document aims to guide the setup of a delegate node in the IPFS/libp2p network. It is recommended that you look into the [Delegated Routing with Libp2p and IPFS](../examples/deledated-routing) example first. This example describes how to use the public delegate nodes available for demos and experiments.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Delegate Nodes with IPFS](#delegate-nodes-with-ipfs)
|
||||
* [Setup a local go-ipfs node as a Delegate Node for the example](#setup-a-local-go-ipfs-node-as-a-delegate-node-for-the-example)
|
||||
* [Setup a remote go-ipfs node as a Delegate Node for the example](#setup-a-remote-go-ipfs-node-as-a-delegate-node-for-the-example)
|
||||
* [Setup a remote go-ipfs node as a Delegate Node for js-ipfs](#setup-a-remote-go-ipfs-node-as-a-delegate-node-for-js-ipfs)
|
||||
|
||||
## Setup a local go-ipfs node as a Delegate Node for the example
|
||||
|
||||
The simplest first step before going into production is to setup a delegate node locally and try it out in the [Delegated Routing with Libp2p and IPFS](../examples/deledated-routing) example.
|
||||
|
||||
Taking into account the browser policies regarding CORS, proper HTTP headers must be configured in `go-ipfs`.
|
||||
|
||||
1. Install `go-ipfs` locally, if you don't have it already. Check the [Install Guidelines](https://github.com/ipfs/go-ipfs/#install).
|
||||
2. Configure HTTP headers for access control
|
||||
|
||||
```sh
|
||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
|
||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["GET", "POST"]'
|
||||
```
|
||||
|
||||
Bear in mind that this allows access to any origin. You might want to control the allowed origins.
|
||||
|
||||
3. Start your `go-ipfs` daemon.
|
||||
|
||||
```sh
|
||||
ipfs daemon
|
||||
```
|
||||
|
||||
The daemon will output a line about its API address, like `API server listening on /ip4/127.0.0.1/tcp/5001`
|
||||
|
||||
4. Modify the example `libp2p-configuration` to use the local `go-ipfs` node API
|
||||
|
||||
```js
|
||||
const delegatedApiOptions = {
|
||||
protocol: 'http',
|
||||
port: 5001,
|
||||
host: '127.0.0.1'
|
||||
}
|
||||
```
|
||||
|
||||
5. Start the example and retry its flows. You should have your browser node leveraging the delegate `go-ipfs` node for `content-routing` and `peer-routing`.
|
||||
|
||||
## Setup a remote go-ipfs node as a Delegate Node for the example
|
||||
|
||||
1. Install `go-ipfs`. Check the [Install Guidelines](https://github.com/ipfs/go-ipfs/#install).
|
||||
2. Configure HTTP headers for access control
|
||||
|
||||
```sh
|
||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
|
||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["GET", "POST"]'
|
||||
```
|
||||
|
||||
Bear in mind that this allows access to any origin. You might want to control the allowed origins.
|
||||
|
||||
3. Start your `go-ipfs` daemon.
|
||||
|
||||
4. Expose the API to the outside world. You should setup an SSL certificate with nginx and proxy to the API. You can use a service that already offers an SSL certificate with the server and configure nginx, or you can create valid certificates with for example [Letsencrypt](https://certbot.eff.org/lets-encrypt/osx-nginx). Letsencrypt won’t give you a cert for an IP address (yet) so you need to connect via SSL to a domain name.
|
||||
|
||||
5. Modify the example `libp2p-configuration` to use the remote `go-ipfs` node host name.
|
||||
|
||||
6. Start the example and retry its flows.
|
||||
|
||||
<details>
|
||||
<summary>Troubleshooting</summary>
|
||||
|
||||
<p><b>Error: no IPFS repo found in <code>$INSTALLATION_PATH/ipfs/common</code></b></p>
|
||||
Bear in mind that in some distributions you might need to run <code>ipfs init</code> before starting the <code>go-ipfs</code> daemon. If you are running the <code>go-ipfs</code> node in a server you might prefer using the <code>server</code> profile and running <code>ipfs init --profile server</code> instead. For more detailed instructions, please refer to the canonical documentation for <a target="_blank" href="https://docs.ipfs.io/how-to/command-line-quick-start/#initialize-the-repository">initializing the repository</a>
|
||||
</details>
|
||||
|
||||
## Setup a remote go-ipfs node as a Delegate Node for js-ipfs
|
||||
|
||||
You should follow all the steps mentioned for the setup of a remote go-ipfs for the libp2p example, except for the integration with the example.
|
||||
|
||||
5. You should add your delegate multiaddr to the `js-ipfs` config file as follows:
|
||||
|
||||
```js
|
||||
Addresses: {
|
||||
Delegates: [
|
||||
'/dns4/node0.mydelegatenode.io/tcp/443/https',
|
||||
'/dns4/node1.mydelegatenode.io/tcp/443/https',
|
||||
'/dns4/node2.mydelegatenode.io/tcp/443/https',
|
||||
'/dns4/node3.mydelegatenode.io/tcp/443/https'
|
||||
]
|
||||
},
|
||||
```
|
40
doc/production/README.md
Normal file
40
doc/production/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Production
|
||||
|
||||
`js-libp2p` can be used in multiple environments, as well as for a wide range of use cases. Different environments and different use cases mean different configurations and challenges in the network.
|
||||
|
||||
Libp2p nodes in the network can vary from nodes behind an application, to infrastructure nodes that enable the network to operate and to be efficient. In this context, the Libp2p project provides public infrastructure to boost the network, enable nodes connectivity and improve constrained nodes performance. This public infrastructure should be leveraged for learning the concepts and experimenting. When an application on top of libp2p aims to move into production, its own infrastructure should be setup as the public nodes will be intensively used by others and its availability is not guaranteed.
|
||||
|
||||
This guide aims to guide you from using the public infrastructure into setting up your own.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Production](#production)
|
||||
* [Bootstrap nodes](#bootstrap-nodes)
|
||||
* [Star servers](#star-servers)
|
||||
* [Delegate nodes](#delegate-nodes)
|
||||
* [Circuit Relay](#circuit-relay)
|
||||
* [Rendezvous Server nodes](#rendezvous-server-nodes)
|
||||
|
||||
## Bootstrap nodes
|
||||
|
||||
TODO: Problem that solve...
|
||||
|
||||
## Star servers
|
||||
|
||||
TODO: Problem that solve...
|
||||
|
||||
## Delegate nodes
|
||||
|
||||
Libp2p nodes in a browser environment, in constrained devices, as well as in other scenarios, will not be an efficient node in the libp2p DHT overlay, as a consequence of their known limitations regarding connectivity and performance.
|
||||
|
||||
Aiming to support these type of nodes to find other peers and content in the network, delegate nodes can be setup. With a set of well known libp2p delegate nodes, nodes with limitations in the network can leverage them to perform peer and content routing calls.
|
||||
|
||||
You can read on how to setup your own set of delegated nodes in [DELEGATE_NODES.md](./DELEGATE_NODES.md).
|
||||
|
||||
## Circuit Relay
|
||||
|
||||
TODO: Problem that solve...
|
||||
|
||||
## Rendezvous Server nodes
|
||||
|
||||
TODO: Problem that solve...
|
3
examples/delegated-routing/.env
Normal file
3
examples/delegated-routing/.env
Normal file
@@ -0,0 +1,3 @@
|
||||
# required because react-scripts scans *up* the tree from this project and finds
|
||||
# a conflicting version of webpack in the node_modules dir for js-libp2p (aegir).
|
||||
SKIP_PREFLIGHT_CHECK=true
|
@@ -1,31 +1,21 @@
|
||||
❗❗Outdated: This example is still not refactored with the `0.27.*` release.
|
||||
WIP on [libp2p/js-libp2p#507](https://github.com/libp2p/js-libp2p/pull/507)
|
||||
======
|
||||
|
||||
# Delegated Routing with Libp2p and IPFS
|
||||
|
||||
This example shows how to use delegated peer and content routing. The [Peer and Content Routing Example](../peer-and-content-routing) focuses
|
||||
on the DHT implementation. This example takes that a step further and introduces delegated routing. Delegated routing is
|
||||
especially useful when your libp2p node will have limited resources, making running a DHT impractical. It's
|
||||
also highly useful if your node is generating content, but can't reliably be on the network. You can use delegate nodes
|
||||
to provide content on your behalf.
|
||||
This example shows how to use delegated peer and content routing. The [Peer and Content Routing Example](../peer-and-content-routing) focuses on the DHT implementation. This example takes that a step further and introduces delegated routing. Delegated routing is especially useful when your libp2p node will have limited resources, making running a DHT impractical. It's also highly useful if your node is generating content, but can't reliably be on the network. You can use delegate nodes to provide content on your behalf.
|
||||
|
||||
The starting [Libp2p Bundle](./src/libp2p-bundle.js) in this example starts by disabling the DHT and adding the Delegated Peer and Content Routers.
|
||||
Once you've completed the example, you should try enabled the DHT and see what kind of results you get! You can also enable the
|
||||
various Peer Discovery modules and see the impact it has on your Peer count.
|
||||
The starting [Libp2p Configuration](./src/libp2p-configuration.js) in this example starts by disabling the DHT and adding the Delegated Peer and Content Routers.
|
||||
Once you've completed the example, you should try enabled the DHT and see what kind of results you get! You can also enable the various Peer Discovery modules and see the impact it has on your Peer count.
|
||||
|
||||
## Prerequisite
|
||||
**NOTE**: This example is currently dependent on a clone of the [delegated routing support branch of go-ipfs](https://github.com/ipfs/go-ipfs/pull/4595).
|
||||
This example uses a publicly known delegated routing node. This aims to ease experimentation, but you should not rely on this in production.
|
||||
|
||||
## Running this example
|
||||
|
||||
1. Install IPFS locally if you dont already have it. [Install Guide](https://docs.ipfs.io/introduction/install/)
|
||||
2. Run the IPFS daemon: `ipfs daemon`
|
||||
3. The daemon will output a line about its API address, like `API server listening on /ip4/127.0.0.1/tcp/8080`
|
||||
4. In another window output the addresses of the node: `ipfs id`. Make note of the websocket address, it will contain `/ws/` in the address.
|
||||
5. In `./src/libp2p-bundle.js` check if the host and port of your node are correct, according to the previous step. If they are different, replace them.
|
||||
6. In `./src/App.js` replace `BootstrapNode` with your nodes Websocket address from step 4.
|
||||
7. Start this example:
|
||||
3. In another window output the addresses of the node: `ipfs id`. Make note of the websocket address, it will contain `/ws/` in the address.
|
||||
- If there is no websocket address, you will need to add it in the ipfs config file (`~/.ipfs/config`)
|
||||
- Add to Swarm Addresses something like: `"/ip4/127.0.0.1/tcp/4001/ws"`. Make sure to restart your IPFS node afterwards to ensure the new settings had been applied.
|
||||
4. In `./src/App.js` replace `BootstrapNode` with your nodes Websocket address from the step above.
|
||||
5. Start this example:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
@@ -34,11 +24,11 @@ npm start
|
||||
|
||||
This should open your browser to http://localhost:3000. If it does not, go ahead and do that now.
|
||||
|
||||
8. Your browser should show you connected to at least 1 peer.
|
||||
6. Your browser should show you connected to at least 1 peer.
|
||||
|
||||
### Finding Content via the Delegate
|
||||
1. Add a file to your IPFS node. From this example root you can do `ipfs add ./README.md` to add the example readme.
|
||||
2. Copy the hash from line 5, it will look something like *Qmf33vz4HJFkqgH7XPP1uA6atYKTX1BWQEQthzpKcAdeyZ*.
|
||||
2. Copy the hash from line 5, it will look something like *QmV8QZ1m4fi57fbmaYDAkaTSTjHZVLUJmsqvaP6EcUyUNb*.
|
||||
3. In the browser, paste the hash into the *Hash* field and hit `Find`. The readme contents should display.
|
||||
|
||||
This will do a few things:
|
||||
@@ -48,6 +38,10 @@ This will do a few things:
|
||||
|
||||
### Finding Peers via the Delegate
|
||||
1. Get a list of your delegate nodes peer by querying the IPFS daemon: `ipfs swarm peers`
|
||||
2. Copy one of the CIDs from the list of peer addresses, this will be the last portion of the address and will look something like `QmdoG8DpzYUZMVP5dGmgmigZwR1RE8Cf6SxMPg1SBXJAQ8`.
|
||||
2. Copy one of the CIDs from the list of peer addresses, this will be the last portion of the address and will look something like `QmSb5LGwyVTCSgi5etuBnKhkEgH68cDxfwp3rtc94Fegv4`.
|
||||
3. In your browser, paste the CID into the *Peer* field and hit `Find`.
|
||||
4. You should see information about the peer including its addresses.
|
||||
|
||||
## Going to production?
|
||||
|
||||
TODO
|
||||
|
@@ -3,19 +3,19 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"ipfs": "~0.34.4",
|
||||
"libp2p": "github:libp2p/js-libp2p#master",
|
||||
"libp2p-delegated-content-routing": "~0.2.2",
|
||||
"libp2p-delegated-peer-routing": "~0.2.2",
|
||||
"libp2p-kad-dht": "~0.14.12",
|
||||
"libp2p-mplex": "~0.8.5",
|
||||
"libp2p-secio": "~0.11.1",
|
||||
"libp2p-webrtc-star": "~0.15.8",
|
||||
"libp2p-websocket-star": "~0.10.2",
|
||||
"libp2p-websockets": "~0.12.2",
|
||||
"ipfs": "~0.47.0",
|
||||
"libp2p": "../..",
|
||||
"libp2p-delegated-content-routing": "~0.5.0",
|
||||
"libp2p-delegated-peer-routing": "~0.5.0",
|
||||
"libp2p-kad-dht": "~0.19.7",
|
||||
"libp2p-mplex": "~0.9.5",
|
||||
"libp2p-secio": "~0.12.5",
|
||||
"libp2p-webrtc-star": "~0.18.6",
|
||||
"libp2p-websockets": "~0.13.6",
|
||||
"peer-id": "^0.13.13",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-scripts": "2.1.8"
|
||||
"react-scripts": "^3.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start"
|
||||
|
@@ -3,12 +3,12 @@
|
||||
|
||||
import React from 'react'
|
||||
import Ipfs from 'ipfs'
|
||||
import libp2pBundle from './libp2p-bundle'
|
||||
const Component = React.Component
|
||||
import libp2pConfig from './libp2p-configuration'
|
||||
import PeerId from 'peer-id'
|
||||
|
||||
const BootstrapNode = '/ip4/127.0.0.1/tcp/8081/ws/p2p/QmdoG8DpzYUZMVP5dGmgmigZwR1RE8Cf6SxMPg1SBXJAQ8'
|
||||
const BootstrapNode = '/ip4/127.0.0.1/tcp/4010/ws/p2p/QmZrsjJ7v9QoJNjDJmjsQ8947wiK3UnaPPLQvrTSRDAZ2d'
|
||||
|
||||
class App extends Component {
|
||||
class App extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
@@ -16,7 +16,7 @@ class App extends Component {
|
||||
// This hash is the IPFS readme
|
||||
hash: 'QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB',
|
||||
// This peer is one of the Bootstrap nodes for IPFS
|
||||
peer: 'QmV6kA2fB8kTr6jc3pL5zbNsjKbmPUHAPKKHRBYe1kDEyc',
|
||||
peer: 'QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z',
|
||||
isLoading: 0
|
||||
}
|
||||
this.peerInterval = null
|
||||
@@ -38,39 +38,39 @@ class App extends Component {
|
||||
})
|
||||
}
|
||||
|
||||
handleHashSubmit (event) {
|
||||
async handleHashSubmit (event) {
|
||||
event.preventDefault()
|
||||
this.setState({
|
||||
isLoading: this.state.isLoading + 1
|
||||
})
|
||||
|
||||
this.ipfs.cat(this.state.hash, (err, data) => {
|
||||
if (err) console.log('Error', err)
|
||||
const chunks = []
|
||||
for await (const chunk of this.ipfs.cat(this.state.hash)) {
|
||||
chunks.push(chunk)
|
||||
}
|
||||
|
||||
this.setState({
|
||||
response: data.toString(),
|
||||
isLoading: this.state.isLoading - 1
|
||||
})
|
||||
this.setState({
|
||||
response: Buffer.concat(chunks).toString(),
|
||||
isLoading: this.state.isLoading - 1
|
||||
})
|
||||
}
|
||||
handlePeerSubmit (event) {
|
||||
async handlePeerSubmit (event) {
|
||||
event.preventDefault()
|
||||
this.setState({
|
||||
isLoading: this.state.isLoading + 1
|
||||
})
|
||||
|
||||
this.ipfs.dht.findpeer(this.state.peer, (err, results) => {
|
||||
if (err) console.log('Error', err)
|
||||
const peerId = PeerId.createFromB58String(this.state.peer)
|
||||
const results = await this.ipfs.libp2p.peerRouting.findPeer(peerId)
|
||||
|
||||
this.setState({
|
||||
response: JSON.stringify(results, null, 2),
|
||||
isLoading: this.state.isLoading - 1
|
||||
})
|
||||
this.setState({
|
||||
response: JSON.stringify(results, null, 2),
|
||||
isLoading: this.state.isLoading - 1
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
window.ipfs = this.ipfs = new Ipfs({
|
||||
async componentDidMount () {
|
||||
window.ipfs = this.ipfs = await Ipfs.create({
|
||||
config: {
|
||||
Addresses: {
|
||||
Swarm: []
|
||||
@@ -90,27 +90,17 @@ class App extends Component {
|
||||
preload: {
|
||||
enabled: false
|
||||
},
|
||||
libp2p: libp2pBundle
|
||||
libp2p: libp2pConfig
|
||||
})
|
||||
this.ipfs.on('ready', () => {
|
||||
if (this.peerInterval) {
|
||||
clearInterval(this.peerInterval)
|
||||
}
|
||||
|
||||
this.ipfs.swarm.connect(BootstrapNode, (err) => {
|
||||
if (err) {
|
||||
console.log('Error connecting to the node', err)
|
||||
}
|
||||
console.log('Connected!')
|
||||
})
|
||||
await this.ipfs.swarm.connect(BootstrapNode)
|
||||
console.log('Connected!')
|
||||
|
||||
this.peerInterval = setInterval(() => {
|
||||
this.ipfs.swarm.peers((err, peers) => {
|
||||
if (err) console.log(err)
|
||||
if (peers) this.setState({peers: peers.length})
|
||||
})
|
||||
}, 2500)
|
||||
})
|
||||
this.peerInterval = setInterval(async () => {
|
||||
const peers = await this.ipfs.swarm.peers()
|
||||
|
||||
if (peers) this.setState({ peers: peers.length })
|
||||
}, 2500)
|
||||
}
|
||||
|
||||
render () {
|
||||
|
@@ -3,7 +3,6 @@
|
||||
|
||||
const Libp2p = require('libp2p')
|
||||
const Websockets = require('libp2p-websockets')
|
||||
const WebSocketStar = require('libp2p-websocket-star')
|
||||
const WebRTCStar = require('libp2p-webrtc-star')
|
||||
const MPLEX = require('libp2p-mplex')
|
||||
const SECIO = require('libp2p-secio')
|
||||
@@ -11,18 +10,15 @@ const KadDHT = require('libp2p-kad-dht')
|
||||
const DelegatedPeerRouter = require('libp2p-delegated-peer-routing')
|
||||
const DelegatedContentRouter = require('libp2p-delegated-content-routing')
|
||||
|
||||
export default function Libp2pBundle ({peerInfo, peerBook}) {
|
||||
const wrtcstar = new WebRTCStar({id: peerInfo.id})
|
||||
const wsstar = new WebSocketStar({id: peerInfo.id})
|
||||
export default function Libp2pConfiguration ({peerId}) {
|
||||
const delegatedApiOptions = {
|
||||
host: '0.0.0.0',
|
||||
protocol: 'http',
|
||||
port: '8080'
|
||||
protocol: 'https',
|
||||
port: 443,
|
||||
host: 'node0.delegate.ipfs.io'
|
||||
}
|
||||
|
||||
return new Libp2p({
|
||||
peerInfo,
|
||||
peerBook,
|
||||
peerId,
|
||||
// Lets limit the connection managers peers and have it check peer health less frequently
|
||||
connectionManager: {
|
||||
maxPeers: 10,
|
||||
@@ -30,18 +26,13 @@ export default function Libp2pBundle ({peerInfo, peerBook}) {
|
||||
},
|
||||
modules: {
|
||||
contentRouting: [
|
||||
new DelegatedContentRouter(peerInfo.id, delegatedApiOptions)
|
||||
new DelegatedContentRouter(peerId, delegatedApiOptions)
|
||||
],
|
||||
peerRouting: [
|
||||
new DelegatedPeerRouter(delegatedApiOptions)
|
||||
],
|
||||
peerDiscovery: [
|
||||
wrtcstar.discovery,
|
||||
wsstar.discovery
|
||||
],
|
||||
transport: [
|
||||
wrtcstar,
|
||||
wsstar,
|
||||
WebRTCStar,
|
||||
Websockets
|
||||
],
|
||||
streamMuxer: [
|
Reference in New Issue
Block a user