From 30740be5df0b0e7e2bc1344e18dd9dc212b7468a Mon Sep 17 00:00:00 2001 From: Yemel Jardi Date: Tue, 9 Dec 2014 18:03:47 -0300 Subject: [PATCH] Remove old files --- lib/transport/connection.js | 576 ----------------------------------- lib/transport/peer.js | 56 ---- lib/transport/peermanager.js | 313 ------------------- 3 files changed, 945 deletions(-) delete mode 100644 lib/transport/connection.js delete mode 100644 lib/transport/peer.js delete mode 100644 lib/transport/peermanager.js diff --git a/lib/transport/connection.js b/lib/transport/connection.js deleted file mode 100644 index a7ecd32..0000000 --- a/lib/transport/connection.js +++ /dev/null @@ -1,576 +0,0 @@ -'use strict'; - -var MAX_RECEIVE_BUFFER = 10000000; -var PROTOCOL_VERSION = 70000; - -var util = require('util'); -var Put = require('bufferput'); -var Buffers = require('buffers'); -var buffertools = require('buffertools'); - -// PATCH TODO: Remove (yemel) -Buffers.prototype.skip = function (i) { - if (i == 0) { - return; - } else if (i == this.length) { - this.buffers = []; - this.length = 0; - return; - } - var pos = this.pos(i); - this.buffers = this.buffers.slice(pos.buf); - this.buffers[0] = new Buffer(this.buffers[0].slice(pos.offset)); - this.length -= i; -}; - -var networks = require('../networks'); -var Block = require('../block'); -var Transaction = require('../transaction'); -var BufferUtil = require('../util/buffer'); -var BufferReader = require('../encoding/bufferreader'); -var Hash = require('../crypto/hash'); -var Random = require('../crypto/random'); -var EventEmitter = require('events').EventEmitter; - -var nonce = Random.getPseudoRandomBuffer(8); - -var BIP0031_VERSION = 60000; - -function Connection(socket, peer, opts) { - this.config = opts || {}; - - this.network = this.config.network || networks.livenet; - this.socket = socket; - this.peer = peer; - - // check for socks5 proxy options and construct a proxied socket - if (this.config.proxy) { - var Socks5Client = require('socks5-client'); - this.socket = new Socks5Client(this.config.proxy.host, this.config.proxy.port); - } - - // A connection is considered "active" once we have received verack - this.active = false; - // The version incoming packages are interpreted as - this.recvVer = 0; - // The version outgoing packages are sent as - this.sendVer = 0; - // The (claimed) height of the remote peer's block chain - this.bestHeight = 0; - // Is this an inbound connection? - this.inbound = !!this.socket.server; - // Have we sent a getaddr on this connection? - this.getaddr = false; - - // Receive buffer - this.buffers = new Buffers(); - - // Starting 20 Feb 2012, Version 0.2 is obsolete - // This is the same behavior as the official client - if (new Date().getTime() > 1329696000000) { - this.recvVer = 209; - this.sendVer = 209; - } - - this.setupHandlers(); -} -util.inherits(Connection, EventEmitter); - -Connection.prototype.open = function(callback) { - if (typeof callback === 'function') this.once('connect', callback); - this.socket.connect(this.peer.port, this.peer.host); - return this; -}; - -Connection.prototype.setupHandlers = function() { - this.socket.addListener('connect', this.handleConnect.bind(this)); - this.socket.addListener('error', this.handleError.bind(this)); - this.socket.addListener('end', this.handleDisconnect.bind(this)); - this.socket.addListener('data', (function(data) { - var dumpLen = 35; - console.debug('[' + this.peer + '] ' + - 'Recieved ' + data.length + ' bytes of data:'); - console.debug('... ' + buffertools.toHex(data.slice(0, dumpLen > data.length ? - data.length : dumpLen)) + - (data.length > dumpLen ? '...' : '')); - }).bind(this)); - this.socket.addListener('data', this.handleData.bind(this)); -}; - -Connection.prototype.handleConnect = function() { - if (!this.inbound) { - this.sendVersion(); - } - this.emit('connect', { - conn: this, - socket: this.socket, - peer: this.peer - }); -}; - -Connection.prototype.handleError = function(err) { - if (err.errno == 110 || err.errno == 'ETIMEDOUT') { - console.info('connection timed out for ' + this.peer); - } else if (err.errno == 111 || err.errno == 'ECONNREFUSED') { - console.info('connection refused for ' + this.peer); - } else { - console.warn('connection with ' + this.peer + ' ' + err.toString()); - } - this.emit('error', { - conn: this, - socket: this.socket, - peer: this.peer, - err: err - }); -}; - -Connection.prototype.handleDisconnect = function() { - this.emit('disconnect', { - conn: this, - socket: this.socket, - peer: this.peer - }); -}; - -Connection.prototype.handleMessage = function(message) { - if (!message) { - // Parser was unable to make sense of the message, drop it - return; - } - - try { - switch (message.command) { - case 'version': - // Did we connect to ourself? - if (buffertools.compare(nonce, message.nonce) === 0) { - this.socket.end(); - return; - } - - if (this.inbound) { - this.sendVersion(); - } - - if (message.version >= 209) { - this.sendMessage('verack', new Buffer([])); - } - this.sendVer = Math.min(message.version, PROTOCOL_VERSION); - if (message.version < 209) { - this.recvVer = Math.min(message.version, PROTOCOL_VERSION); - } else { - // We won't start expecting a checksum until after we've received - // the 'verack' message. - this.once('verack', (function() { - this.recvVer = message.version; - }).bind(this)); - } - this.bestHeight = message.start_height; - break; - - case 'verack': - this.recvVer = Math.min(message.version, PROTOCOL_VERSION); - this.active = true; - break; - - case 'ping': - if ('object' === typeof message.nonce) { - this.sendPong(message.nonce); - } - break; - } - } catch (e) { - console.err('Error while handling "' + message.command + '" message from ' + - this.peer + ':\n' + - (e.stack ? e.stack : e.toString())); - return; - } - this.emit(message.command, { - conn: this, - socket: this.socket, - peer: this.peer, - message: message - }); -}; - -Connection.prototype.sendPong = function(nonce) { - this.sendMessage('pong', nonce); -}; - -Connection.prototype.sendVersion = function() { - var subversion = '/BitcoinX:0.1/'; - - var put = new Put(); - put.word32le(PROTOCOL_VERSION); // version - put.word64le(1); // services - put.word64le(Math.round(new Date().getTime() / 1000)); // timestamp - put.pad(26); // addr_me - put.pad(26); // addr_you - put.put(nonce); - put.varint(subversion.length); - put.put(new Buffer(subversion, 'ascii')); - put.word32le(0); - - this.sendMessage('version', put.buffer()); -}; - -Connection.prototype.sendGetBlocks = function(starts, stop, wantHeaders) { - // Default value for stop is 0 to get as many blocks as possible (500) - stop = stop || BufferUtil.NULL_HASH; - - var put = new Put(); - - // https://en.bitcoin.it/wiki/Protocol_specification#getblocks - put.word32le(this.sendVer); - put.varint(starts.length); - - for (var i = 0; i < starts.length; i++) { - if (starts[i].length != 32) { - throw new Error('Invalid hash length'); - } - - put.put(starts[i]); - } - - var stopBuffer = new Buffer(stop, 'binary'); - if (stopBuffer.length != 32) { - throw new Error('Invalid hash length'); - } - - put.put(stopBuffer); - - var command = 'getblocks'; - if (wantHeaders) - command = 'getheaders'; - this.sendMessage(command, put.buffer()); -}; - -Connection.prototype.sendGetHeaders = function(starts, stop) { - this.sendGetBlocks(starts, stop, true); -}; - -Connection.prototype.sendGetData = function(invs) { - var put = new Put(); - put.varint(invs.length); - for (var i = 0; i < invs.length; i++) { - put.word32le(invs[i].type); - put.put(invs[i].hash); - } - this.sendMessage('getdata', put.buffer()); -}; - -Connection.prototype.sendGetAddr = function(invs) { - var put = new Put(); - this.sendMessage('getaddr', put.buffer()); -}; - -Connection.prototype.sendInv = function(data) { - if (!Array.isArray(data)) data = [data]; - var put = new Put(); - put.varint(data.length); - data.forEach(function(value) { - if (value instanceof Block) { - // Block - put.word32le(2); // MSG_BLOCK - } else { - // Transaction - put.word32le(1); // MSG_TX - } - put.put(value.getHash()); - }); - this.sendMessage('inv', put.buffer()); -}; - -Connection.prototype.sendHeaders = function(headers) { - var put = new Put(); - put.varint(headers.length); - headers.forEach(function(header) { - put.put(header); - - // Indicate 0 transactions - put.word8(0); - }); - this.sendMessage('headers', put.buffer()); -}; - -Connection.prototype.sendTx = function(tx) { - this.sendMessage('tx', tx.serialize()); -}; - -Connection.prototype.sendBlock = function(block, txs) { - var put = new Put(); - - // Block header - put.put(block.getHeader()); - - // List of transactions - put.varint(txs.length); - txs.forEach(function(tx) { - put.put(tx.serialize()); - }); - - this.sendMessage('block', put.buffer()); -}; - -Connection.prototype.sendMessage = function(command, payload) { - try { - var magic = this.network.magic; - var commandBuf = new Buffer(command, 'ascii'); - if (commandBuf.length > 12) throw 'Command name too long'; - - var checksum; - if (this.sendVer >= 209) { - checksum = Hash.sha256sha256(payload).slice(0, 4); - } else { - checksum = new Buffer([]); - } - - var message = new Put(); // -- HEADER -- - message.put(magic); // magic bytes - message.put(commandBuf); // command name - message.pad(12 - commandBuf.length); // zero-padded - message.word32le(payload.length); // payload length - message.put(checksum); // checksum - // -- BODY -- - message.put(payload); // payload data - - var buffer = message.buffer(); - - console.debug('[' + this.peer + '] ' + - 'Sending message ' + command + ' (' + payload.length + ' bytes)'); - - this.socket.write(buffer); - } catch (err) { - // TODO: We should catch this error one level higher in order to better - // determine how to react to it. For now though, ignoring it will do. - console.err('Error while sending message to peer ' + this.peer + ': ' + - (err.stack ? err.stack : err.toString())); - } -}; - -Connection.prototype.handleData = function(data) { - this.buffers.push(data); - - if (this.buffers.length > MAX_RECEIVE_BUFFER) { - console.err('Peer ' + this.peer + ' exceeded maxreceivebuffer, disconnecting.' + - (err.stack ? err.stack : err.toString())); - this.socket.destroy(); - return; - } - - this.processData(); -}; - -Connection.prototype.processData = function() { - // If there are less than 20 bytes there can't be a message yet. - if (this.buffers.length < 20) return; - - var magic = this.network.magic; - var i = 0; - for (;;) { - if (this.buffers.get(i) === magic[0] && - this.buffers.get(i + 1) === magic[1] && - this.buffers.get(i + 2) === magic[2] && - this.buffers.get(i + 3) === magic[3]) { - if (i !== 0) { - console.debug('[' + this.peer + '] ' + - 'Received ' + i + - ' bytes of inter-message garbage: '); - console.debug('... ' + this.buffers.slice(0, i)); - - this.buffers.skip(i); - } - break; - } - - if (i > (this.buffers.length - 4)) { - this.buffers.skip(i); - return; - } - i++; - } - - var payloadLen = (this.buffers.get(16)) + - (this.buffers.get(17) << 8) + - (this.buffers.get(18) << 16) + - (this.buffers.get(19) << 24); - - var startPos = (this.recvVer >= 209) ? 24 : 20; - var endPos = startPos + payloadLen; - - if (this.buffers.length < endPos) return; - - var command = this.buffers.slice(4, 16).toString('ascii').replace(/\0+$/, ''); - var payload = this.buffers.slice(startPos, endPos); - var checksum = (this.recvVer >= 209) ? this.buffers.slice(20, 24) : null; - - console.debug('[' + this.peer + '] ' + - 'Received message ' + command + - ' (' + payloadLen + ' bytes)'); - - if (checksum !== null) { - var checksumConfirm = Hash.sha256sha256(payload).slice(0, 4); - if (buffertools.compare(checksumConfirm, checksum) !== 0) { - console.err('[' + this.peer + '] ' + - 'Checksum failed', { - cmd: command, - expected: checksumConfirm.toString('hex'), - actual: checksum.toString('hex') - }); - return; - } - } - - var message; - try { - message = this.parseMessage(command, payload); - } catch (e) { - console.err('Error while parsing message ' + command + ' from ' + - this.peer + ':\n' + - (e.stack ? e.stack : e.toString())); - } - - if (message) { - this.handleMessage(message); - } - - this.buffers.skip(endPos); - this.processData(); -}; - -Connection.prototype.parseMessage = function(command, payload) { - var parser = new BufferReader(payload); - - var data = { - command: command - }; - - var i; - - switch (command) { - case 'version': // https://en.bitcoin.it/wiki/Protocol_specification#version - data.version = parser.readUInt32LE(); - data.services = parser.readUInt64LEBN(); - data.timestamp = parser.readUInt64LEBN(); - data.addr_me = parser.read(26); - data.addr_you = parser.read(26); - data.nonce = parser.read(8); - data.subversion = parser.readVarintBuf(); - data.start_height = parser.readUInt32LE(); - break; - - case 'inv': - case 'getdata': - data.count = parser.readVarintNum(); - - data.invs = []; - for (i = 0; i < data.count; i++) { - data.invs.push({ - type: parser.readUInt32LE(), - hash: parser.read(32) - }); - } - break; - - case 'headers': - data.count = parser.readVarintNum(); - - data.headers = []; - for (i = 0; i < data.count; i++) { - var header = Block.fromBufferReader(parser); - data.headers.push(header); - } - break; - - case 'block': - var block = Block.fromBufferReader(parser); - - data.block = block; - data.version = block.version; - data.prev_hash = block.prev_hash; - data.merkle_root = block.merkle_root; - data.timestamp = block.timestamp; - data.bits = block.bits; - data.nonce = block.nonce; - - data.txs = block.txs; - - data.size = payload.length; - break; - - case 'tx': - var tx = Transaction.fromBufferReader(parser); - return { - command: command, - version: tx.version, - lock_time: tx.lock_time, - ins: tx.ins, - outs: tx.outs, - tx: tx, - }; - - case 'getblocks': - case 'getheaders': - // parse out the version - data.version = parser.readUInt32LE(); - - // TODO: Limit block locator size? - // reference implementation limits to 500 results - var startCount = parser.readVarintNum(); - - data.starts = []; - for (i = 0; i < startCount; i++) { - data.starts.push(parser.read(32)); - } - data.stop = parser.read(32); - break; - - case 'addr': - var addrCount = parser.readVarintNum(); - - // Enforce a maximum number of addresses per message - if (addrCount > 1000) { - addrCount = 1000; - } - - data.addrs = []; - for (i = 0; i < addrCount; i++) { - // TODO: Time actually depends on the version of the other peer (>=31402) - data.addrs.push({ - time: parser.readUInt32LE(), - services: parser.readUInt64LEBN(), - ip: parser.read(16), - port: parser.readUInt16BE() - }); - } - break; - - case 'alert': - data.payload = parser.readVarintBuf(); - data.signature = parser.readVarintBuf(); - break; - - case 'ping': - if (this.recvVer > BIP0031_VERSION) { - data.nonce = parser.read(8); - } - break; - - case 'getaddr': - case 'verack': - case 'reject': - // Empty message, nothing to parse - break; - - default: - console.err('Connection.parseMessage(): Command not implemented', { - cmd: command - }); - - // This tells the calling function not to issue an event - return null; - } - - return data; -}; - -module.exports = Connection; \ No newline at end of file diff --git a/lib/transport/peer.js b/lib/transport/peer.js deleted file mode 100644 index 6547c77..0000000 --- a/lib/transport/peer.js +++ /dev/null @@ -1,56 +0,0 @@ -var Net = require('net'); -var Put = require('bufferput'); -var buffertools = require('buffertools'); - -function Peer(host, port, services) { - if ("string" === typeof host) { - if (host.indexOf(':') && !port) { - var parts = host.split(':'); - host = parts[0]; - port = parts[1]; - } - this.host = host; - this.port = +port || 8333; - } else if (host instanceof Peer) { - this.host = host.host; - this.port = host.port; - } else if (Buffer.isBuffer(host)) { - if (buffertools.compare(Peer.IPV6_IPV4_PADDING, host.slice(0, 12)) != 0) { - throw new Error('IPV6 not supported yet! Cannot instantiate host.'); - } - this.host = Array.prototype.slice.apply(host.slice(12)).join('.'); - this.port = +port || 8333; - } else { - throw new Error('Could not instantiate peer, invalid parameter type: ' + - typeof host); - } - - this.services = (services) ? services : null; - this.lastSeen = 0; -}; - -Peer.IPV6_IPV4_PADDING = new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255]); - -Peer.prototype.createConnection = function() { - this.connection = Net.createConnection(this.port, this.host); - return this.connection; -}; - -Peer.prototype.getHostAsBuffer = function() { - return new Buffer(this.host.split('.')); -}; - -Peer.prototype.toString = function() { - return this.host + ":" + this.port; -}; - -Peer.prototype.toBuffer = function() { - var put = new Put(); - put.word32le(this.lastSeen); - put.word64le(this.services); - put.put(this.getHostAsBuffer()); - put.word16be(this.port); - return put.buffer(); -}; - -module.exports = Peer; \ No newline at end of file diff --git a/lib/transport/peermanager.js b/lib/transport/peermanager.js deleted file mode 100644 index fc3e403..0000000 --- a/lib/transport/peermanager.js +++ /dev/null @@ -1,313 +0,0 @@ -'use strict'; - -var dns = require('dns'); -var util = require('util'); -var async = require('async'); - -var Connection = require('./connection'); -var Peer = require('./peer'); -var networks = require('../networks'); - -var GetAdjustedTime = function() { - // TODO: Implement actual adjustment - return Math.floor(new Date().getTime() / 1000); -}; - -function PeerManager(config) { - // extend defaults with config - this.config = config || {}; - this.config.network = this.config.network || networks.livenet; - - this.active = false; - this.timer = null; - - this.peers = []; - this.pool = []; - this.connections = []; - this.isConnected = false; - this.peerDiscovery = false; - - // Move these to the Node's settings object - this.interval = 5000; - this.minConnections = 8; - this.minKnownPeers = 10; - - // keep track of tried seeds and results - this.seeds = { - resolved: [], - failed: [] - }; -} - -var EventEmitter = require('events').EventEmitter; -util.inherits(PeerManager, EventEmitter); -PeerManager.Connection = Connection; - -PeerManager.prototype.start = function() { - this.active = true; - if (!this.timer) { - this.timer = setInterval(this.checkStatus.bind(this), this.interval); - } -}; - -PeerManager.prototype.stop = function() { - this.active = false; - if (this.timer) { - clearInterval(this.timer); - this.timer = null; - } - for (var i = 0; i < this.connections.length; i++) { - this.connections[i].socket.end(); - }; -}; - -PeerManager.prototype.addPeer = function(peer, port) { - if (peer instanceof Peer) { - this.peers.push(peer); - } else if ("string" == typeof peer) { - this.addPeer(new Peer(peer, port)); - } else { - console.error('Node.addPeer(): Invalid value provided for peer', { - val: peer - }); - throw 'Node.addPeer(): Invalid value provided for peer.'; - } -}; - -PeerManager.prototype.removePeer = function(peer) { - var index = this.peers.indexOf(peer); - var exists = !!~index; - if (exists) this.peers.splice(index, 1); - return exists; -}; - -PeerManager.prototype.checkStatus = function checkStatus() { - // Make sure we are connected to all forcePeers - if (this.peers.length) { - var peerIndex = {}; - this.peers.forEach(function(peer) { - peerIndex[peer.toString()] = peer; - }); - - // Ignore the ones we're already connected to - this.connections.forEach(function(conn) { - var peerName = conn.peer.toString(); - if ("undefined" !== peerIndex[peerName]) { - delete peerIndex[peerName]; - } - }); - - // for debug purposes, print how many of our peers are actually connected - var connected = 0 - this.peers.forEach(function(p) { - if (p.connection && !p.connection._connecting) connected++ - }); - console.debug(connected + ' of ' + this.peers.length + ' peers connected'); - - Object.keys(peerIndex).forEach(function(i) { - this.connectTo(peerIndex[i]); - }.bind(this)); - } -}; - -PeerManager.prototype.connectTo = function(peer) { - console.info('connecting to ' + peer); - try { - return this.addConnection(peer.createConnection(), peer); - } catch (e) { - console.error('creating connection', e); - return null; - } -}; - -PeerManager.prototype.addConnection = function(socketConn, peer) { - var conn = new Connection(socketConn, peer, this.config); - this.connections.push(conn); - this.emit('connection', conn); - - conn.addListener('version', this.handleVersion.bind(this)); - conn.addListener('verack', this.handleReady.bind(this)); - conn.addListener('addr', this.handleAddr.bind(this)); - conn.addListener('getaddr', this.handleGetAddr.bind(this)); - conn.addListener('error', this.handleError.bind(this)); - conn.addListener('disconnect', this.handleDisconnect.bind(this)); - - return conn; -}; - -PeerManager.prototype.handleVersion = function(e) { - e.peer.version = e.message.version; - e.peer.start_height = e.message.start_height; - - if (!e.conn.inbound) { - // TODO: Advertise our address (if listening) - } - // Get recent addresses - if (this.peerDiscovery && - (e.message.version >= 31402 || this.peers.length < 1000)) { - e.conn.sendGetAddr(); - e.conn.getaddr = true; - } -}; - -PeerManager.prototype.handleReady = function(e) { - console.info('connected to ' + e.conn.peer.host + ':' + e.conn.peer.port); - this.emit('connect', { - pm: this, - conn: e.conn, - socket: e.socket, - peer: e.peer - }); - - if (this.isConnected == false) { - this.emit('netConnected', e); - this.isConnected = true; - } -}; - -PeerManager.prototype.handleAddr = function(e) { - if (!this.peerDiscovery) return; - - var now = GetAdjustedTime(); - e.message.addrs.forEach(function(addr) { - try { - // In case of an invalid time, assume "5 days ago" - if (addr.time <= 100000000 || addr.time > (now + 10 * 60)) { - addr.time = now - 5 * 24 * 60 * 60; - } - var peer = new Peer(addr.ip, addr.port, addr.services); - peer.lastSeen = addr.time; - - // TODO: Handle duplicate peers - this.peers.push(peer); - - // TODO: Handle addr relay - } catch (e) { - console.warn("Invalid addr received: " + e.message); - } - }.bind(this)); - if (e.message.addrs.length < 1000) { - e.conn.getaddr = false; - } -}; - -PeerManager.prototype.handleGetAddr = function(e) { - // TODO: Reply with addr message. -}; - -PeerManager.prototype.handleError = function(e) { - console.error('unkown error with peer ' + e.peer + ' (disconnecting): ' + e.err); - this.handleDisconnect.apply(this, [].slice.call(arguments)); -}; - -PeerManager.prototype.handleDisconnect = function(e) { - console.info('disconnected from peer ' + e.peer); - var i = this.connections.indexOf(e.conn); - if (i != -1) this.connections.splice(i, 1); - - this.removePeer(e.peer); - if (this.pool.length) { - console.info('replacing peer using the pool of ' + this.pool.length + ' seeds'); - this.addPeer(this.pool.pop()); - } - - if (!this.connections.length) { - this.emit('netDisconnected'); - this.isConnected = false; - } -}; - -PeerManager.prototype.getActiveConnection = function() { - var activeConnections = this.connections.filter(function(conn) { - return conn.active; - }); - - if (activeConnections.length) { - var randomIndex = Math.floor(Math.random() * activeConnections.length); - var candidate = activeConnections[randomIndex]; - if (candidate.socket.writable) { - return candidate; - } else { - // Socket is not writable, remove it from active connections - activeConnections.splice(randomIndex, 1); - - // Then try again - // TODO: This causes an infinite recursion when all connections are dead, - // although it shouldn't. - return this.getActiveConnection(); - } - } else { - return null; - } -}; - -PeerManager.prototype.getActiveConnections = function() { - return this.connections.slice(0); -}; - -PeerManager.prototype.discover = function(options, callback) { - var self = this; - var seeds = this.config.network.dnsSeeds; - - self.limit = options.limit || 12; - - var dnsExecutor = seeds.map(function(seed) { - return function(done) { - // have we already resolved this seed? - if (~self.seeds.resolved.indexOf(seed)) { - // if so, just pass back cached peer list - return done(null, self.seeds.results[seed]); - } - - // has this seed failed to resolve? - if (~self.seeds.failed.indexOf(seed)) { - // if so, pass back empty results - return done(null, []); - } - - console.info('resolving dns seed ' + seed); - - dns.resolve(seed, function(err, peers) { - if (err) { - console.error('failed to resolve dns seed ' + seed, err); - self.seeds.failed.push(seed); - return done(null, []); - } - - console.info('found ' + peers.length + ' peers from ' + seed); - self.seeds.resolved.push(seed); - - // transform that list into a list of Peer instances - peers = peers.map(function(ip) { - return new Peer(ip, self.config.network.port); - }); - - peers.forEach(function(p) { - if (self.peers.length < self.limit) self.addPeer(p); - else self.pool.push(p); - }); - - self.emit('peers', peers); - - return done(null, peers); - }); - - }; - }); - - // try resolving all seeds - async.parallel(dnsExecutor, function(err, results) { - var peers = []; - - // consolidate all resolved peers into one list - results.forEach(function(peerlist) { - peers = peers.concat(peerlist); - }); - - if (typeof callback === 'function') callback(null, peers); - }); - - return self; -}; - -module.exports = PeerManager; \ No newline at end of file