Skip to content

Commit

Permalink
Merge pull request #1 from diasdavid/revamp
Browse files Browse the repository at this point in the history
node-ipfs is getting form :)
  • Loading branch information
daviddias committed Jul 6, 2015
2 parents 2bcc8b7 + 0c34ad5 commit 3d319e7
Show file tree
Hide file tree
Showing 94 changed files with 424 additions and 5 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules/
**/node_modules/
**/*.log
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
21 changes: 17 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"name": "ipfs",
"version": "0.1.1",
"version": "0.0.0",
"description": "ipfs implementation in node",
"main": "index.js",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"start": "IPFS_LOG=* node src/index.js | ./node_modules/.bin/bunyan -o short"
},
"repository": {
"type": "git",
Expand All @@ -18,5 +19,17 @@
"bugs": {
"url": "https://github.com/jbenet/node-ipfs/issues"
},
"homepage": "https://github.com/jbenet/node-ipfs"
"homepage": "https://github.com/jbenet/node-ipfs",
"devDependencies": {
"standard": "^4.5.1"
},
"dependencies": {
"bs58": "^2.0.1",
"bunyan": "^1.4.0",
"k-bucket": "^0.5.0",
"multiaddr": "^0.1.2",
"multicast-dns": "^2.2.0",
"multihashing": "^0.1.2",
"network": "^0.1.3"
}
}
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var Routing = require('./routing')

var r = new Routing()

r.start()
107 changes: 107 additions & 0 deletions src/routing/discovery/mdns/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
var mdns = require('multicast-dns')()
var Id = require('./../../routers/dht/peer/id')
var Peer = require('./../../routers/dht/peer')
var Multiaddr = require('multiaddr')
var log = require('ipfs-logger').group('discovery')

exports = module.exports = sonar

function sonar (cb) {
var serviceTag = 'discovery.ipfs.io.local'

mdns.on('warning', function (err) {
cb(err)
})

mdns.on('response', function (response) {
if (!response.answers) {
return
}

var answers = {
ptr: {},
srv: {},
txt: {},
a: []
}

response.answers.forEach(function (answer) {
switch (answer.type) {
case 'PTR': answers.ptr = answer; break
case 'SRV': answers.srv = answer; break
case 'TXT': answers.txt = answer; break
case 'A': answers.a.push(answer); break
default: break
}
})

if (answers.ptr.name !== serviceTag) {
return
}

var b58Id = answers.txt.data
var port = answers.srv.data.port
var multiaddrs = []

answers.a.forEach(function (a) {
multiaddrs.push(new Multiaddr('/ip4/' + a.data + '/tcp/' + port))
})

log.info('peer found -', b58Id)
var peerId = Id.createFromB58String(b58Id)
cb(null, new Peer(peerId, multiaddrs))
})

mdns.on('query', function (query) {
// answer with PTR, SRV and A for several IP addr
})

setInterval(function () {
mdns.query({
questions: [{
name: serviceTag,
type: 'PTR'
}]
})
}, 1e3 * 5)
}

/* for reference
[ { name: 'discovery.ipfs.io.local',
type: 'PTR',
class: 1,
ttl: 120,
data: 'QmbBHw1Xx9pUpAbrVZUKTPL5Rsph5Q9GQhRvcWVBPFgGtC.discovery.ipfs.io.local' },
{ name: 'QmbBHw1Xx9pUpAbrVZUKTPL5Rsph5Q9GQhRvcWVBPFgGtC.discovery.ipfs.io.local',
type: 'SRV',
class: 1,
ttl: 120,
data: { priority: 10, weight: 1, port: 4001, target: 'lorien.local' } },
{ name: 'lorien.local',
type: 'A',
class: 1,
ttl: 120,
data: '127.0.0.1' },
{ name: 'lorien.local',
type: 'A',
class: 1,
ttl: 120,
data: '127.94.0.1' },
{ name: 'lorien.local',
type: 'A',
class: 1,
ttl: 120,
data: '172.16.38.224' },
{ name: 'QmbBHw1Xx9pUpAbrVZUKTPL5Rsph5Q9GQhRvcWVBPFgGtC.discovery.ipfs.io.local',
type: 'TXT',
class: 1,
ttl: 120,
data: 'QmbBHw1Xx9pUpAbrVZUKTPL5Rsph5Q9GQhRvcWVBPFgGtC' } ],
*/
76 changes: 76 additions & 0 deletions src/routing/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* routing/index.js Routing is the front door for everything that happens on the routing layer.
* Other modules present in the remaining layers should not require to interact with modules
* behind this level
*/

var mDNSDiscovery = require('./discovery/mdns')
var Peer = require('./routers/dht/peer')
var Id = require('./routers/dht/peer/id')
var network = require('network')
var Multiaddr = require('multiaddr')
var DHT = require('./routers/dht')

exports = module.exports = Routing

function Routing () {
var self = this

if (!(self instanceof Routing)) {
throw new Error('Routing should be called with new')
}

self.router
self.peer

// instantiate this peer

self.start = function (cb) {
network.get_private_ip(function (err, ip) {
if (err) {
cb(err)
}
var multiaddrs = []
multiaddrs.push(new Multiaddr('/ip4/' + ip + '/tcp/' + 4001))
self.peer = new Peer(Id.create(), multiaddrs)
self.useRouterDHT()
self.useDiscoveryMDNS()
if (cb) {
cb()
}
})
}

// routing interface

self.putValue = function (key, buf) {}
self.getValue = function (key) {}
self.provide = function (key) {}
self.findPeer = function (key) {}
self.ping = function (key) {}

// select strategies (plugins) used

self.useRouterDHT = function () {
self.router = new DHT(self.peer)
}

self.useRouterMDNS = function () {}

self.useDiscoveryBootstrapList = function () {}

self.useDiscoveryMDNS = function () {
mDNSDiscovery(function (err, peer) {
if (err) {
return console.log('mDNS Discovery err: ', err)
}
self.router.addPeer(peer)
})
}

self.useDiscoveryRandomWalk = function () {
// use router to find a random peer
}

}

46 changes: 46 additions & 0 deletions src/routing/routers/dht/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* DHT routing plugin for router
*/

var KBucket = require('k-bucket')
var log = require('ipfs-logger').group('router')

exports = module.exports = DHT

function DHT (peerSelf) {
var self = this

if (!(self instanceof DHT)) {
throw new Error('DHT must be called with new')
}

var kBucket = new KBucket({
localNodeId: peerSelf.id.toBytes(),
numberOfNodesPerKBucket: 20 // same as go-ipfs
})

kBucket.on('ping', function (oldContacts, newContact) {
log.info('kbucket ping')
log.info('old', oldContacts)
log.info('new', newContact)
// 1. ping each oldContact
// 2. those who respond should be readded (kBucket.add)
// 3. those who didn't respond should be removed (kBucket.remove)
// 4. if at least one is removed, then newContact can be added (kBucket.add)
})

self.addPeer = function (peer) {
log.info('New DHT candidate -', peer.id.toB58String())
kBucket.add({
id: peer.id.toBytes(),
peer: peer
})
}

self.candidatesToId = function (id) {
return kBucket.closest({
id: id.toBytes(),
n: 3
})
}
}
79 changes: 79 additions & 0 deletions src/routing/routers/dht/peer/id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Id is an object representation of a peer Id. a peer Id is a multihash
*/

var multihashing = require('multihashing')
var base58 = require('bs58')
var crypto = require('crypto')

exports = module.exports = Id

function Id (id, pubKey, privKey) {
var self = this

if (!(self instanceof Id)) {
throw new Error('Id must be called with new')
}

self.privKey = privKey
self.pubKey = pubKey
self.id = id // multihash - sha256 - buffer

// pretty print

self.toPrint = function () {
return {
id: id.toHexString(),
privKey: privKey.toString('hex'),
pubKey: pubKey.toString('hex')
}
}

// encode/decode functions

self.toHexString = function () {
return self.id.toString('hex')
}

self.toBytes = function () {
return self.id
}

self.toB58String = function () {
return base58.encode(self.id)
}

}

// generation

exports.create = function () {
var ecdh = crypto.createECDH('secp256k1')
ecdh.generateKeys()

var mhId = multihashing(ecdh.getPublicKey(), 'sha2-256')

return new Id(mhId, ecdh.getPrivateKey(), ecdh.getPublicKey())
}

exports.createFromHexString = function (str) {
return new Id(new Buffer(str), 'hex')
}

exports.createFromBytes = function (buf) {
return new Id(buf)
}

exports.createFromB58String = function (str) {
return new Id(new Buffer(base58.decode(str)))
}

exports.createFromPubKey = function (pubKey) {
var mhId = multihashing(pubKey, 'sha2-256')

return new Id(mhId, null, pubKey)
}

exports.createFromPrivKey = function () {
// TODO(daviddias) derive PubKey from priv
}
22 changes: 22 additions & 0 deletions src/routing/routers/dht/peer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Peer represents a peer on the IPFS network
*/

var Id = require('./id.js')

exports = module.exports = Peer

function Peer (peerId, multiaddrs) {
var self = this

if (!(self instanceof Peer)) {
throw new Error('Peer must be called with new')
}

if (!(peerId instanceof Id)) {
throw new Error('Peer must be created with an instance of Id')
}

self.id = peerId
self.multiaddrs = multiaddrs
}
20 changes: 20 additions & 0 deletions src/utils/ipfs-logger/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "ipfs-logger",
"version": "0.0.0",
"description": "IPFS logging module (wrapper of bunyan) for the Node.js implementation of IPFS",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"IPFS"
],
"author": "David Dias <[email protected]>",
"license": "MIT",
"dependencies": {
"bunyan": "^1.4.0"
},
"devDependencies": {
"standard": "^4.5.2"
}
}
Loading

0 comments on commit 3d319e7

Please sign in to comment.