Compare commits

...

11 Commits

19 changed files with 436 additions and 211 deletions

View File

@ -5,15 +5,13 @@ matrix:
- node_js: 4
env: CXX=g++-4.8
- node_js: 6
env:
- SAUCE=true
- CXX=g++-4.8
env: CXX=g++-4.8
- node_js: stable
env: CXX=g++-4.8
# Make sure we have new NPM.
before_install:
- npm install -g npm
- npm install -g npm@4
script:
- npm run lint

View File

@ -1,3 +1,13 @@
<a name="0.10.2"></a>
## [0.10.2](https://github.com/libp2p/js-libp2p/compare/v0.10.1...v0.10.2) (2017-07-21)
### Bug Fixes
* circle ci, thanks victor! ([4224c1f](https://github.com/libp2p/js-libp2p/commit/4224c1f))
<a name="0.10.1"></a>
## [0.10.1](https://github.com/libp2p/js-libp2p/compare/v0.10.0...v0.10.1) (2017-07-10)

View File

@ -1,151 +1,3 @@
# IPFS Community Code of Conduct
# Contributor Code of Conduct
We believe that our mission is best served in an environment that is friendly,
safe, and accepting; free from intimidation or harassment.
Towards this end, certain behaviors and practices will not be tolerated.
## tl;dr
- Be respectful.
- We're here to help: abuse@ipfs.io
- Abusive behavior is never tolerated.
- Violations of this code may result in swift and permanent expulsion from the IPFS community.
- "Too long, didn't read" is not a valid excuse for not knowing what is in this document.
## Table of Contents
- [Scope](#scope)
- [Friendly Harassment-Free Space](#friendly-harassment-free-space)
- [Reporting Violations of this Code of Conduct](#reporting-violations-of-this-code-of-conduct)
- [Copyright Violations](#copyright-violations)
- [Consequences](#consequences)
- [Addressing Grievances](#addressing-grievances)
- [Contact Info](#contact-info)
- [Changes](#changes)
- [Credit and License](#credit-and-license)
## Scope
We expect all members of the IPFS community to abide by this Code of Conduct
at all times in all IPFS community venues, online and in person, and in one-on-one
communications pertaining to IPFS affairs.
This policy covers the usage of IPFS public infrastructure, including the
IPFS.io HTTP gateways, as well as other IPFS websites, IPFS related events,
and any other services offered by or on behalf of the IPFS community. It also
applies to behavior in the context of the IPFS Open Source project
communities, including but not limited to public GitHub repositories, IRC
channels, social media, mailing lists, and public events.
This Code of Conduct is in addition to, and does not in any way nullify or
invalidate, any other terms or conditions related to use of IPFS services.
The definitions of various subjective terms such as "discriminatory",
"hateful", or "confusing" will be decided at the sole discretion of the IPFS
abuse team.
## Friendly Harassment-Free Space
We are committed to providing a friendly, safe and welcoming environment for
all, regardless of gender identity, sexual orientation, disability, ethnicity,
religion, age, physical appearance, body size, race, or similar personal
characteristics.
We ask that you please respect that people have differences of opinion
regarding technical choices, and that every design or implementation choice
carries a trade-off and numerous costs. There is seldom a single right answer.
A difference of technology preferences is not a license to be rude.
Any spamming, trolling, flaming, baiting, or other attention-stealing
behavior is not welcome, and will not be tolerated.
Harassing other users is never tolerated, whether via public or private media.
Avoid using offensive or harassing nicknames, or other identifiers that might
detract from a friendly, safe, and welcoming environment for all.
Harassment includes, but is not limited to: harmful or prejudicial verbal or
written comments related to gender identity, sexual orientation, disability,
ethnicity, religion, age, physical appearance, body size, race, or similar
personal characteristics; inappropriate use of nudity, sexual images, and/or
sexually explicit language in public spaces; threats of physical or non-
physical harm; deliberate intimidation, stalking or following; harassing
photography or recording; sustained disruption of talks or other events;
inappropriate physical contact; and unwelcome sexual attention.
Media shared through public infrastructure run by the IPFS team must not
contain illegal or infringing content. You should only publish content via
IPFS public infrastructure if you have the right to do so. This includes
complying with all software license agreements or other intellectual property
restrictions. You will be solely responsible for any violation of laws or
others intellectual property rights.
## Reporting Violations of this Code of Conduct
If you believe someone is harassing you or has otherwise violated this Code of
Conduct, please contact us at abuse@ipfs.io to send us an abuse report. If
this is the initial report of a problem, please include as much detail as
possible. It is easiest for us to address issues when we have more context.
## Copyright Violations
We respect the intellectual property of others and ask that you do too. If you
believe any content or other materials available through public IPFS
infrastructure violates a copyright held by you and you would like to submit a
notice pursuant to the Digital Millennium Copyright Act or other similar
international law, you can submit a notice to our agent for service of notice
to: abuse@ipfs.io
(We will add a physical mailing address here when we acquire one).
Please make sure your notice meets the Digital Millennium Copyright Act
requirements.
## Consequences
All content published to public IPFS infrastructure is hosted at the sole
discretion of the IPFS team.
Unacceptable behavior from any community member will not be tolerated.
Anyone asked to stop unacceptable behavior is expected to comply immediately.
If a community member engages in unacceptable behavior, the ipfs team
may take any action they deem appropriate, up to and including a temporary ban
or permanent expulsion from the community without warning (and without refund
in the case of a paid event or service).
## Addressing Grievances
If you feel you have been falsely or unfairly accused of violating this Code
of Conduct, you should notify the IPFS team. We will do our best to ensure
that your grievance is handled appropriately.
In general, we will choose the course of action that we judge as being most in
the interest of fostering a safe and friendly community.
On IRC, let one of the ops know if you think that someone has transgressed
against the Code of Conduct. If you would like to be an op and promise to
help maintain and abide by the code, please let us know.
## Contact Info
Please contact abuse@ipfs.io if you need to report a problem or address a
grievance related to an abuse report.
You are also encouraged to contact us if you are curious about something that
might be "on the line" between appropriate and inappropriate content. We are
happy to provide guidance to help you be a successful part of our community.
## Changes
This is a living document and may be updated from time to time. Please refer
to the git history for this document to view the changes.
## Credit and License
This Code of Conduct is based on the
[npm Code of Conduct](https://www.npmjs.com/policies/conduct).
This document may be reused under a [Creative Commons Attribution-ShareAlike
License](http://creativecommons.org/licenses/by-sa/4.0/).
The `js-libp2p` project follows the [`IPFS Community Code of Conduct`](https://github.com/ipfs/community/blob/master/code-of-conduct.md)

View File

@ -249,18 +249,6 @@ class Node extends libp2p {
- `key`: Buffer
- `nVals`: Number
---------------------
`SOON™`
#### `libp2p.findPeers`
#### `libp2p.findProviders`
#### `libp2p.record.put`
#### `libp2p.record.get`
[PeerInfo]: https://github.com/libp2p/js-peer-info
[PeerId]: https://github.com/libp2p/js-peer-id
[PeerBook]: https://github.com/libp2p/js-peer-book

View File

@ -5,8 +5,10 @@ machine:
dependencies:
pre:
- google-chrome --version
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
- sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
- curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- sudo dpkg -i google-chrome.deb || true
- sudo apt-get update
- sudo apt-get --only-upgrade install google-chrome-stable
- sudo apt-get install -f
- sudo apt-get install --only-upgrade lsb-base
- sudo dpkg -i google-chrome.deb
- google-chrome --version

View File

@ -23,4 +23,3 @@ Let us know if you find any issue or if you want to contribute and add a new tut
- Running libp2p in the Electron (future)
- [The standard echo net example with libp2p](./echo)
- [A simple chat app with](./chat)
- [See other nodes in the network using WebRTC Star discovery mechanism](./see-nodes)

View File

@ -30,12 +30,12 @@ async.parallel([
], (err, ids) => {
if (err) throw err
const peerDialer = new PeerInfo(ids[0])
peerDialer.multiaddr.add('/ip4/0.0.0.0/tcp/0')
peerDialer.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
const nodeDialer = new Node(peerDialer)
const peerListener = new PeerInfo(ids[1])
idListener = ids[1]
peerListener.multiaddr.add('/ip4/127.0.0.1/tcp/10333')
peerListener.multiaddrs.add('/ip4/127.0.0.1/tcp/10333')
nodeDialer.start((err) => {
if (err) {
throw err
@ -47,7 +47,7 @@ async.parallel([
console.log(ma.toString() + '/ipfs/' + idListener.toB58String())
})
nodeDialer.dialByPeerInfo(peerListener, '/chat/1.0.0', (err, conn) => {
nodeDialer.dial(peerListener, '/chat/1.0.0', (err, conn) => {
if (err) {
throw err
}

View File

@ -8,7 +8,7 @@ const spdy = require('libp2p-spdy')
const KadDHT = require('libp2p-kad-dht')
const multiplex = require('libp2p-multiplex')
const secio = require('libp2p-secio')
const libp2p = require('../..')
const libp2p = require('../../..')
function mapMuxers (list) {
return list.map((pref) => {

View File

@ -13,7 +13,7 @@ PeerId.createFromJSON(require('./peer-id-listener'), (err, idListener) => {
throw err
}
const peerListener = new PeerInfo(idListener)
peerListener.multiaddr.add('/ip4/0.0.0.0/tcp/10333')
peerListener.multiaddrs.add('/ip4/0.0.0.0/tcp/10333')
const nodeListener = new Node(peerListener)
nodeListener.start((err) => {

View File

@ -20,7 +20,7 @@ async.parallel([
// Dialer
const dialerId = ids[0]
const dialerPeerInfo = new PeerInfo(dialerId)
dialerPeerInfo.multiaddr.add('/ip4/0.0.0.0/tcp/0')
dialerPeerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
const dialerNode = new Node(dialerPeerInfo)
// Peer to Dial
@ -28,7 +28,7 @@ async.parallel([
const listenerId = ids[1]
const listenerMultiaddr = '/ip4/127.0.0.1/tcp/10333/ipfs/' +
listenerId.toB58String()
listenerPeerInfo.multiaddr.add(listenerMultiaddr)
listenerPeerInfo.multiaddrs.add(listenerMultiaddr)
dialerNode.start((err) => {
if (err) { throw err }
@ -38,7 +38,7 @@ async.parallel([
'/ipfs/' + dialerId.toB58String()))
console.log('Dialing to peer:', listenerMultiaddr.toString())
dialerNode.dialByPeerInfo(listenerPeerInfo, '/echo/1.0.0', (err, conn) => {
dialerNode.dial(listenerPeerInfo, '/echo/1.0.0', (err, conn) => {
if (err) { throw err }
console.log('nodeA dialed to nodeB on protocol: /echo/1.0.0')

View File

@ -24,7 +24,7 @@ series([
},
(cb) => {
const listenerPeerInfo = new PeerInfo(listenerId)
listenerPeerInfo.multiaddr.add('/ip4/0.0.0.0/tcp/10333')
listenerPeerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/10333')
listenerNode = new Node(listenerPeerInfo)
listenerNode.swarm.on('peer-mux-established', (peerInfo) => {

View File

@ -0,0 +1,67 @@
'use strict'
const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const Multiplex = require('libp2p-multiplex')
const SECIO = require('libp2p-secio')
const PeerInfo = require('peer-info')
const KadDHT = require('libp2p-kad-dht')
const waterfall = require('async/waterfall')
const parallel = require('async/parallel')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new TCP()],
connection: {
muxer: [Multiplex],
crypto: [SECIO]
},
// we add the DHT module that will enable Peer and Content Routing
DHT: KadDHT
}
super(modules, peerInfo)
}
}
function createNode (callback) {
let node
waterfall([
(cb) => PeerInfo.create(cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => callback(err, node))
}
parallel([
(cb) => createNode(cb),
(cb) => createNode(cb),
(cb) => createNode(cb)
], (err, nodes) => {
if (err) { throw err }
const node1 = nodes[0]
const node2 = nodes[1]
const node3 = nodes[2]
parallel([
(cb) => node1.dial(node2.peerInfo, cb),
(cb) => node2.dial(node3.peerInfo, cb),
// Set up of the cons might take time
(cb) => setTimeout(cb, 100)
], (err) => {
if (err) { throw err }
node1.peerRouting.findPeer(node3.peerInfo.id, (err, peer) => {
if (err) { throw err }
console.log('Found it, multiaddrs are:')
peer.multiaddrs.forEach((ma) => console.log(ma.toString()))
})
})
})

View File

@ -0,0 +1,75 @@
'use strict'
const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const Multiplex = require('libp2p-multiplex')
const SECIO = require('libp2p-secio')
const PeerInfo = require('peer-info')
const CID = require('cids')
const KadDHT = require('libp2p-kad-dht')
const waterfall = require('async/waterfall')
const parallel = require('async/parallel')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new TCP()],
connection: {
muxer: [Multiplex],
crypto: [SECIO]
},
// we add the DHT module that will enable Peer and Content Routing
DHT: KadDHT
}
super(modules, peerInfo)
}
}
function createNode (callback) {
let node
waterfall([
(cb) => PeerInfo.create(cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => callback(err, node))
}
parallel([
(cb) => createNode(cb),
(cb) => createNode(cb),
(cb) => createNode(cb)
], (err, nodes) => {
if (err) { throw err }
const node1 = nodes[0]
const node2 = nodes[1]
const node3 = nodes[2]
parallel([
(cb) => node1.dial(node2.peerInfo, cb),
(cb) => node2.dial(node3.peerInfo, cb),
// Set up of the cons might take time
(cb) => setTimeout(cb, 100)
], (err) => {
if (err) { throw err }
const cid = new CID('QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL')
node1.contentRouting.provide(cid, (err) => {
if (err) { throw err }
console.log('Node %s is providing %s', node1.peerInfo.id.toB58String(), cid.toBaseEncodedString())
node3.contentRouting.findProviders(cid, 5000, (err, providers) => {
if (err) { throw err }
console.log('Found provider:', providers[0].id.toB58String())
})
})
})
})

View File

@ -0,0 +1,106 @@
# Peer and Content Routing
DHTs (Distributed Hash Tables) are one of the most common building blocks used when creating P2P networks. However, the name doesn't make justice to all the benefits it brings and putting the whole set of features in one box has proven to be limiting when we want to integrate multiple pieces together. With this in mind, we've come up with a new definition for what a DHT offers: Peer Routing and Content Routing.
Peer Routing is the category of modules that offer a way to find other peers in the network by intentionally issuing queries, iterative or recursive, until a Peer is found or the closest Peers, given the Peer Routing algorithm strategy are found.
Content Routing is the category of modules that offer a way to find where content lives in the network, it works in two steps: 1) Peers provide (announce) to the network that they are holders of specific content (multihashes) and 2) Peers issue queries to find where that content lives. A Content Routing mechanism could be as complex as a Kademlia DHT or a simple registry somewhere in the network.
# 1. Using Peer Routing to find other peers
This example builds on top of the [Protocol and Stream Muxing](../protocol-and-stream-muxing). We need to install `libp2p-kad-dht`, go ahead and `npm install libp2p-kad-dht`. If you want to see the final version, open [1.js](./1.js).
First, let's update our bundle to support Peer Routing and Content Routing.
```JavaScript
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new TCP()],
connection: {
muxer: [Multiplex],
crypto: [SECIO]
},
// we add the DHT module that will enable Peer and Content Routing
DHT: KadDHT
}
super(modules, peerInfo)
}
}
```
Once that is done, we can use the createNode function we developed in the previous example to create 3 nodes. Connect node 1 to node 2 and node 2 to node 3. We will use node 2 as a way to find the whereabouts of node 3
```JavaScript
const node1 = nodes[0]
const node2 = nodes[1]
const node3 = nodes[2]
parallel([
(cb) => node1.dial(node2.peerInfo, cb),
(cb) => node2.dial(node3.peerInfo, cb),
// Set up of the cons might take time
(cb) => setTimeout(cb, 100)
], (err) => {
if (err) { throw err }
//
node1.peerRouting.findPeer(node3.peerInfo.id, (err, peer) => {
if (err) { throw err }
console.log('Found it, multiaddrs are:')
peer.multiaddrs.forEach((ma) => console.log(ma.toString()))
})
})
```
You should see the output being something like:
```Bash
> node 1.js
Found it, multiaddrs are:
/ip4/127.0.0.1/tcp/63617/ipfs/QmWrFXvZr9S4iDqycyoyc2zDdrT1jg9wpdenUTdd1LTar6
/ip4/192.168.86.41/tcp/63617/ipfs/QmWrFXvZr9S4iDqycyoyc2zDdrT1jg9wpdenUTdd1LTar6
```
You have successfully used Peer Routing to find a peer that you were not directly connected. Now all you have to do is to dial to the multiaddrs you discovered.
# 2. Using Content Routing to find providers of content
With Content Routing, you can create records that are stored in multiple points in the network, these records can be resolved by you or other peers and they act as memos or rendezvous points. A great usage of this feature is to support discovery of content, where one node holds a file and instead of using a centralized tracker to inform other nodes that it holds that file, it simply puts a record in the network that can be resolved by other peers. Peer Routing and Content Routing are commonly known as Distributed Hash Tables, DHT.
You can find this example completed in [2.js](./2.js), however as you will see it is very simple to update the previous example.
Instead of calling `peerRouting.findPeer`, we will use `contentRouting.provide` and `contentRouting.findProviders`.
```JavaScript
node1.contentRouting.provide(cid, (err) => {
if (err) { throw err }
console.log('Node %s is providing %s', node1.peerInfo.id.toB58String(), cid.toBaseEncodedString())
node3.contentRouting.findProviders(cid, 5000, (err, providers) => {
if (err) { throw err }
console.log('Found provider:', providers[0].id.toB58String())
})
})
```
The output of your program should look like:
```bash
> node 2.js
Node QmSsmVPoTy3WpzwiNPnsKmonBaZjK2HitFs2nWUvwK31Pz is providing QmTp9VkYvnHyrqKQuFPiuZkiX9gPcqj6x5LJ1rmWuSySnL
Found provider: QmSsmVPoTy3WpzwiNPnsKmonBaZjK2HitFs2nWUvwK31Pz
```
That's it, now you know how to find peers that have pieces of information that interest you!
# 3. Future Work
Currently, the only mechanisms for Peer and Content Routing come from the DHT, however we do have the intention to support:
- Multiple Peer Routing Mechanisms, including ones that do recursive searches (i.e [webrtc-explorer](http://daviddias.me/blog/webrtc-explorer-2-0-0-alpha-release/) like packet switching or [CJDNS](https://github.com/cjdelisle/cjdns) path finder)
- Content Routing via PubSub
- Content Routing via centralized index (i.e a tracker)

View File

@ -1,2 +0,0 @@
# WIP - This example is still in the works
![](http://1.bp.blogspot.com/-tNvSnCW0KlQ/U-KOKGVoJkI/AAAAAAAAA3Q/aiSLMeSJFtw/s1600/WIP-sign.jpg)

68
examples/pubsub/1.js Normal file
View File

@ -0,0 +1,68 @@
'use strict'
const libp2p = require('libp2p')
const TCP = require('libp2p-tcp')
const Multiplex = require('libp2p-multiplex')
const SECIO = require('libp2p-secio')
const PeerInfo = require('peer-info')
const MulticastDNS = require('libp2p-mdns')
const FloodSub = require('libp2p-floodsub')
const waterfall = require('async/waterfall')
const parallel = require('async/parallel')
const series = require('async/series')
class MyBundle extends libp2p {
constructor (peerInfo) {
const modules = {
transport: [new TCP()],
connection: {
muxer: [Multiplex],
crypto: [SECIO]
},
discovery: [new MulticastDNS(peerInfo, { interval: 2000 })]
}
super(modules, peerInfo)
}
}
function createNode (callback) {
let node
waterfall([
(cb) => PeerInfo.create(cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
node = new MyBundle(peerInfo)
node.start(cb)
}
], (err) => callback(err, node))
}
parallel([
(cb) => createNode(cb),
(cb) => createNode(cb)
], (err, nodes) => {
if (err) { throw err }
const node1 = nodes[0]
const node2 = nodes[1]
const fs1 = new FloodSub(node1)
const fs2 = new FloodSub(node2)
series([
(cb) => fs1.start(cb),
(cb) => fs2.start(cb),
(cb) => node1.once('peer:discovery', (peer) => node1.dial(peer, cb)),
(cb) => setTimeout(cb, 500)
], (err) => {
if (err) { throw err }
fs2.on('news', (msg) => console.log(msg.from, msg.data.toString()))
fs2.subscribe('news')
setInterval(() => {
fs1.publish('news', Buffer.from('Bird bird bird, bird is the word!'))
}, 1000)
})
})

View File

@ -1,2 +1,60 @@
# WIP - This example is still in the works
![](http://1.bp.blogspot.com/-tNvSnCW0KlQ/U-KOKGVoJkI/AAAAAAAAA3Q/aiSLMeSJFtw/s1600/WIP-sign.jpg)
# Publish Subscribe
Publish Subscribe is something out of scope for the modular networking stack that is libp2p, however, it is something that is enabled through the primitives that libp2p offers and so it has become one of the most interesting use cases for libp2p.
Currently, we have a PubSub implementation, [libp2p-floodsub](https://github.com/libp2p/js-libp2p-floodsub) and many more being researched at [research-pubsub](https://github.com/libp2p/research-pubsub).
We've seen many interesting use cases appear with this, here are some highlights:
- [Collaborative Text Editing](https://www.youtube.com/watch?v=-kdx8rJd8rQ)
- [IPFS PubSub (using libp2p-floodsub) for IoT](https://www.youtube.com/watch?v=qLpM5pBDGiE).
- [Real Time distributed Applications](https://www.youtube.com/watch?v=vQrbxyDPSXg)
## 1. Setting up a simple PubSub network on top of libp2p
For this example, we will use MulticastDNS for automatic Peer Discovery and libp2p-floodsub to give us the PubSub primitives we are looking for. This example is based the previous examples found in [Discovery Mechanisms](../discovery-mechanisms). You can find the complete version at [1.js](./1.js).
Getting PubSub is super simple, all you have to do is require the FloodSub module and pass it in a libp2p node, once you have done that you can start subscribing and publishing in any topic.
```JavaScript
const FloodSub = require('libp2p-floodsub')
const fs1 = new FloodSub(node1)
const fs2 = new FloodSub(node2)
series([
(cb) => fs1.start(cb),
(cb) => fs2.start(cb),
(cb) => node1.once('peer:discovery', (peer) => node1.dial(peer, cb)),
(cb) => setTimeout(cb, 500)
], (err) => {
if (err) { throw err }
fs2.on('news', (msg) => console.log(msg.from, msg.data.toString()))
fs2.subscribe('news')
setInterval(() => {
fs1.publish('news', Buffer.from('Bird bird bird, bird is the word!'))
}, 1000)
})
```
The output of the program should look like:
```
> node 1.js
QmWpvkKm6qHLhoxpWrTswY6UMNWDyn8hN265Qp9ZYvgS82 Bird bird bird, bird is the word!
QmWpvkKm6qHLhoxpWrTswY6UMNWDyn8hN265Qp9ZYvgS82 Bird bird bird, bird is the word!
QmWpvkKm6qHLhoxpWrTswY6UMNWDyn8hN265Qp9ZYvgS82 Bird bird bird, bird is the word!
QmWpvkKm6qHLhoxpWrTswY6UMNWDyn8hN265Qp9ZYvgS82 Bird bird bird, bird is the word!
QmWpvkKm6qHLhoxpWrTswY6UMNWDyn8hN265Qp9ZYvgS82 Bird bird bird, bird is the word!
```
## 2. Future work
libp2p/IPFS PubSub is enabling a whole set of Distributed Real Time applications using CRDT (Conflict-Free Replicated Data Types). It is still going through heavy research (and hacking) and we invite you to join the conversation at [research-CRDT](https://github.com/ipfs/research-CRDT). Here is a list of some of the exciting examples:
- [PubSub Room](https://github.com/ipfs-labs/ipfs-pubsub-room)
- [Live DB - A always in Sync DB using CRDT](https://github.com/ipfs-labs/ipfs-live-db)
- [IIIF Annotations over IPFS, CRDT and libp2p](https://www.youtube.com/watch?v=hmAniA6g9D0&feature=youtu.be&t=10m40s)
- [orbit.chat - p2p chat application, fully running in the browser with js-ipfs, js-libp2p and orbit-db](http://orbit.chat/)

View File

@ -1,6 +1,6 @@
{
"name": "libp2p",
"version": "0.10.1",
"version": "0.10.2",
"description": "JavaScript base class for libp2p bundles",
"main": "src/index.js",
"scripts": {
@ -36,42 +36,41 @@
"url": "https://github.com/libp2p/js-libp2p/issues"
},
"homepage": "https://github.com/libp2p/js-libp2p",
"dependencies": {
"async": "^2.5.0",
"libp2p-ping": "~0.4.0",
"libp2p-swarm": "~0.30.0",
"mafmt": "^2.1.8",
"multiaddr": "^2.3.0",
"peer-book": "~0.4.0",
"peer-id": "~0.8.8",
"peer-info": "~0.9.4"
},
"devDependencies": {
"aegir": "^11.0.2",
"chai": "^4.0.2",
"cids": "^0.5.0",
"dirty-chai": "^2.0.0",
"electron-webrtc": "^0.3.0",
"libp2p-kad-dht": "^0.2.0",
"libp2p-mdns": "^0.7.0",
"libp2p-multiplex": "^0.4.4",
"libp2p-railing": "^0.5.2",
"libp2p-secio": "^0.6.8",
"libp2p-spdy": "^0.10.6",
"libp2p-swarm": "^0.29.2",
"libp2p-tcp": "^0.10.1",
"libp2p-webrtc-star": "^0.11.0",
"libp2p-websockets": "^0.10.0",
"chai": "^4.1.0",
"dirty-chai": "^2.0.1",
"cids": "~0.5.1",
"libp2p-kad-dht": "~0.3.0",
"libp2p-mdns": "~0.7.1",
"libp2p-multiplex": "~0.4.4",
"libp2p-railing": "~0.5.2",
"libp2p-secio": "~0.6.8",
"libp2p-spdy": "~0.10.6",
"libp2p-tcp": "~0.10.1",
"libp2p-webrtc-star": "~0.11.0",
"libp2p-websockets": "~0.10.0",
"lodash.times": "^4.3.2",
"mafmt": "^2.1.8",
"pre-commit": "^1.2.2",
"pull-goodbye": "0.0.2",
"pull-serializer": "^0.3.2",
"pull-stream": "^3.6.0",
"safe-buffer": "^5.1.1",
"electron-webrtc": "^0.3.0",
"wrtc": "0.0.62"
},
"dependencies": {
"async": "^2.5.0",
"libp2p-ping": "~0.4.0",
"libp2p-swarm": "~0.29.1",
"mafmt": "^2.1.8",
"multiaddr": "^2.3.0",
"peer-book": "~0.4.0",
"peer-id": "~0.8.7",
"peer-info": "~0.9.2"
},
"contributors": [
"Chris Bratlien <chrisbratlien@gmail.com>",
"David Dias <daviddias.p@gmail.com>",
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
"Pedro Teixeira <i@pgte.me>",

View File

@ -28,6 +28,8 @@ class Node extends EventEmitter {
this.modules = _modules
this.peerInfo = _peerInfo
this.peerBook = _peerBook || new PeerBook()
_options = _options || {}
this._isStarted = false
this.swarm = new Swarm(this.peerInfo, this.peerBook)
@ -77,7 +79,10 @@ class Node extends EventEmitter {
// dht provided components (peerRouting, contentRouting, dht)
if (_modules.DHT) {
this._dht = new this.modules.DHT(this, 20, _options.DHT && _options.DHT.datastore)
this._dht = new this.modules.DHT(this.swarm, {
kBucketSize: 20,
datastoer: _options.DHT && _options.DHT.datastore
})
}
this.peerRouting = {