From 34cd17f82274a1344e171a3af97bf08e0cc4704b Mon Sep 17 00:00:00 2001 From: mkg20001 Date: Thu, 7 Sep 2017 14:05:49 +0200 Subject: [PATCH] Use new discovery and new peer class --- lib/network/ip2multi.js | 2 +- lib/peer/{peer-new.js => index.js} | 28 ++++++-- lib/peer/pool-getters.js | 110 +++++++++++++++++++++++++++++ lib/peer/{pool-new.js => pool.js} | 67 +++++++++--------- lib/tracker/manager.js | 1 + 5 files changed, 169 insertions(+), 39 deletions(-) rename lib/peer/{peer-new.js => index.js} (73%) create mode 100644 lib/peer/pool-getters.js rename lib/peer/{pool-new.js => pool.js} (71%) diff --git a/lib/network/ip2multi.js b/lib/network/ip2multi.js index 216482c..2a50b14 100644 --- a/lib/network/ip2multi.js +++ b/lib/network/ip2multi.js @@ -5,7 +5,7 @@ const assert = require("assert") function ip2multi(ip, proto) { ip = ip2multi.split(ip) - return "/ip" + ip.v + "/" + ip.ip + "/" + proto + "/" + ip.port + "/" + return "/ip" + ip.v + "/" + ip.ip + "/" + (proto || "tcp") + "/" + ip.port } ip2multi.split = ipHost => { diff --git a/lib/peer/peer-new.js b/lib/peer/index.js similarity index 73% rename from lib/peer/peer-new.js rename to lib/peer/index.js index 2b9c0bb..d5c83c6 100644 --- a/lib/peer/peer-new.js +++ b/lib/peer/index.js @@ -35,14 +35,14 @@ class Peer extends EventEmitter { this.id = id.toB58String() this._id = id } else { - this.id = id this._id = new Id(Buffer.from(id)) + this.id = this._id.toB58String() } if (PeerInfo.isPeerInfo(addrs)) { this.pi = addrs } else { this.pi = new PeerInfo(this._id) - addrs.map(addr => multiaddr.isMultiaddr(addr) ? addr : multiaddr(addr)).forEach(addr => this.pi.multiaddrs.addSafe(addr)) + addrs.map(addr => multiaddr.isMultiaddr(addr) ? addr : multiaddr(addr)).forEach(addr => this.pi.multiaddrs.add(addr)) } this.addrs = this.pi.multiaddrs.toArray().map(a => a.toString()) this.zites = {} @@ -61,6 +61,7 @@ class Peer extends EventEmitter { return { addrs: this.addrs, id: this.id, + ip: this.ip, score: this.score, zites: Object.keys(this.zites).map(zite => this.zites[zite].toJSON()) } @@ -69,7 +70,7 @@ class Peer extends EventEmitter { class ZeroPeer extends Peer { constructor(addr) { - super([addr], sha5(sha5(addr))) + super([addr], sha5(sha5(addr)).substr(0, 20)) this.ip = multi2ip(addr) } } @@ -80,7 +81,26 @@ class Lp2pPeer extends Peer { } } +function fromJSON(data) { + if (!data.id) return + let peer + if (data.ip) { + peer = new ZeroPeer(data.addrs[0]) + } else { + const id = Id.createFromB58String(data.id) + const pi = new PeerInfo(id) + data.addrs.forEach(a => pi.multiaddrs.addSafe(a)) + peer = new Lp2pPeer(pi) + } + data.zites.forEach(zite_ => { + let zite = new ZiteInfo(zite_.addr) + //TODO: hashfield + peer.zites[zite_] = zite + }) +} + module.exports = { ZeroPeer, - Lp2pPeer + Lp2pPeer, + fromJSON } diff --git a/lib/peer/pool-getters.js b/lib/peer/pool-getters.js new file mode 100644 index 0000000..0754f05 --- /dev/null +++ b/lib/peer/pool-getters.js @@ -0,0 +1,110 @@ +"use strict" + +const EventEmitter = require("events").EventEmitter + +class Getter extends EventEmitter { + constructor(pool) { + super() + this.peers = [] + this.pool = pool + this.register = () => { + pool.registerGetter(this) + delete this.register + } + } + _push(peer) { + this.peers.push(peer) + this.emit("peer", peer) + } + get(cb) { + if (this.peers.length) { + return cb(null, this.peers.shift()) + } else { + this.pool.discover() + this.once("peer", () => cb(null, this.peers.shift())) + } + } + registerGetter(get) { + this.peers.forEach(p => get.push(p)) + this.on("peer", p => get.push(p)) + } +} + +class OnlineGetter extends Getter { + constructor(pool) { + super(pool) + this.tag = "online" + this.register() + } + push(peer) { + if (peer.isOnline) { + this._push(peer) + } + } +} + +class OfflineGetter extends Getter { + constructor(pool) { + super(pool) + this.tag = "offline" + this.register() + } + push(peer) { + if (peer.isOnline) { + this._push(peer) + } + } +} + +class DiscoveryCandidateGetter extends Getter { + constructor(pool, addr) { + super(pool) + this.tag = "discovery" + this.zite = addr + this.register() + } + push(peer) { + if (!peer.ip && !peer.isSeeding(this.zite) && peer.isOnline) this._push(peer) + } +} + +class MetaGetter extends EventEmitter { + constructor(getters) { + super() + this.glist = getters + this.gobj = {} + getters.forEach(g => { + g.id = g.tag || g.constructor.name + this.gobj[g.id] = g + g.on("peer", peer => this.emit("peer", g.id, peer)) + }) + } + get(cb) { + const f = this.glist.filter(g => g.peers.length)[0] + if (f) { + cb(null, f.id, f.peers.shift()) + } else { + this.once("peer", id => + cb(null, id, this.gobj[id].peers.shift())) + } + } + getSync() { + const f = this.glist.filter(g => g.peers.length)[0] + if (f) { + return [f.id, f.peers.shift()] + } else { + return false + } + } + get peers() { + return this.glist.filter(g => g.peers.length).length + } +} + +module.exports = { + Getter, + OnlineGetter, + OfflineGetter, + DiscoveryCandidateGetter, + MetaGetter +} diff --git a/lib/peer/pool-new.js b/lib/peer/pool.js similarity index 71% rename from lib/peer/pool-new.js rename to lib/peer/pool.js index dbc1b20..a2cf326 100644 --- a/lib/peer/pool-new.js +++ b/lib/peer/pool.js @@ -2,7 +2,7 @@ const EventEmitter = require("events").EventEmitter const hypercache = require("hypercache") -const Peer = require("./peer-new.js") +const Peer = require("./") const PeerInfo = require("peer-info") const Id = require("peer-id") const multiaddr = require("multiaddr") @@ -30,27 +30,6 @@ function isInPool(cache, pi) { throw new Error("Invalid type supplied to isInPool. Please report!") } -class Getter extends EventEmitter { - constructor(pool) { - super() - this.peers = [] - this.pool = pool - pool.registerGetter(this) - } - push(peer) { - this.peers.push(peer) - this.emit("peer", peer) - } - get(cb) { - if (this.peers.length) { - return cb(null, this.peers.shift()) - } else { - this.pool.discover() - this.once("peer", () => cb(null, this.peers.shift())) - } - } -} - class Pool extends EventEmitter { constructor() { super() @@ -66,6 +45,10 @@ class Pool extends EventEmitter { toJSON() { return this.peers.map(p => p.toJSON()) } + fromJSON(data, cb) { + data.map(d => Peer.fromJSON(d)).filter(e => !!e).forEach(peer => this.push(peer)) + cb() + } registerGetter(get) { this.peers.forEach(p => get.push(p)) this.on("peer", p => get.push(p)) @@ -92,55 +75,71 @@ class MainPool extends Pool { this.cache = new hypercache(null, { manual: true, keys: ["id", "ip"], - sets: ["addrs"] + sets: ["addrs"], + name: "peers" }) + this.cache.update([]) } - push(peer) { + push(peer, lazy) { this._push(peer) peer.on("seed", zite => this.emit("seed." + zite, peer)) - this.cache.update(this.peers) + if (!lazy) this.cache.update(this.peers) return peer } - add(pi) { + add(pi, lazy) { let p = isInPool(this.cache, pi) if (p.length > 1) throw new Error("Multiple peers found!") if (p.length) return p.pop() if (PeerInfo.isPeerInfo(pi)) - return this.push(new Peer.Lp2pPeer(pi)) + return this.push(new Peer.Lp2pPeer(pi), lazy) if (ip2multi.isIp(pi)) - return this.push(new Peer.ZeroPeer(ip2multi(pi))) + return this.push(new Peer.ZeroPeer(ip2multi(pi)), lazy) if (multiaddr.isMultiaddr(pi)) { if (pi.toString().indexOf("ipfs") != -1) { const id = Id.createFromB58String(pi.toString().split("ipfs/").pop()) const _pi = new PeerInfo(id) _pi.multiaddrs.addSafe(pi) - return this.push(new Peer.Lp2pPeer(_pi)) + return this.push(new Peer.Lp2pPeer(_pi), lazy) } else { - return this.push(new Peer.ZeroPeer(pi.toString())) + return this.push(new Peer.ZeroPeer(pi.toString()), lazy) } } if (typeof pi == "string") { if (pi.match(/\/.+\/.+\/.+\/.+\//) || pi.match(/\/.+\/.+\/.+\/.+/)) - return this.push(new Peer.ZeroPeer(pi)) + return this.push(new Peer.ZeroPeer(pi), lazy) if (pi.match(/\/.+\/.+\/.+\/.+\/.+\/.+\//) || pi.match(/\/.+\/.+\/.+\/.+\/.+\/.+/)) { const id = Id.createFromB58String(pi.split("ipfs/").pop()) const _pi = new PeerInfo(id) _pi.multiaddrs.addSafe(pi) - return this.push(new Peer.Lp2pPeer(_pi)) + return this.push(new Peer.Lp2pPeer(_pi), lazy) } } return false } + addMany(list, zite) { + if (zite && zite.address) zite = zite.address + let u = {} + list.filter(d => u[d] ? false : (u[d] = true)).forEach(p => { + const peer = this.add(p, true) + if (zite) + if (!peer.isSeeding(zite)) peer.seed(zite) + }) + if (list.length) this.cache.update(this.peers) + } + fromJSON(data, cb) { + data.map(d => Peer.fromJSON(d)).filter(e => !!e).forEach(peer => this.push(peer, true)) + this.cache.update(this.peers) + cb() + } } module.exports = { MainPool, - ZitePool, - Getter + ZitePool } diff --git a/lib/tracker/manager.js b/lib/tracker/manager.js index 1d76d7f..4e5280c 100644 --- a/lib/tracker/manager.js +++ b/lib/tracker/manager.js @@ -43,6 +43,7 @@ module.exports = function TrackerManager(tracker_server, zeronet) { plist = null }) } + if (addr.endsWith(":0")) return plist.push(addr) })