diff --git a/PeerManager.js b/PeerManager.js index 4ee071e4a..47bdbe99f 100644 --- a/PeerManager.js +++ b/PeerManager.js @@ -213,4 +213,61 @@ PeerManager.prototype.getActiveConnections = function () { return this.connections.slice(0); }; +PeerManager.prototype.discoverPeers = function(callback) { + var self = this; + var async = imports.async || require('async'); + var dns = imports.dns || require('dns'); + var networks = imports.networks || require('./networks')[this.config.network]; + var seeds = networks.dnsSeeds; + + // keep track of tried seeds and results + self.seeds = { + resolved: [], + failed: [], + results: {} + }; + + 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.resolved.indexOf(seed)) { + // if so, pass back empty results + return done(null, []); + } + // otherwise resolve the dns seed to get some peers + dns.resolve(seed, function(err, peers) { + if (err) { + self.seeds.failed.push(seed); + return done(null, []); + } + self.seeds.resolved.push(seed); + self.seeds.results[seed] = 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); + }); + + // transform that list into a list of Peer instances + peers = peers.map(function(ip) { + return new Peer(ip, networks.defaultClientPort); + }); + + callback(null, peers); + }); +}; + module.exports = require('soop')(PeerManager); diff --git a/examples/PeerDiscovery.js b/examples/PeerDiscovery.js new file mode 100644 index 000000000..b12cb3ced --- /dev/null +++ b/examples/PeerDiscovery.js @@ -0,0 +1,15 @@ +var PeerManager = require('../PeerManager'); +var peerman = new PeerManager(); + +peerman.discoverPeers(function(err, peers) { + // we get an array of peer instances + console.log(peers); + // the peer manager caches the tried seeds and any results + console.log(peerman.seeds); + // we can use this array of peers to add to the manager + peers.forEach(function(p) { + peerman.addPeer(p); + }); + // then we can start the manager + peerman.start(); +}); diff --git a/networks.js b/networks.js index 27f60c4df..787f71958 100644 --- a/networks.js +++ b/networks.js @@ -19,7 +19,16 @@ exports.livenet = { prev_hash: buffertools.fill(new Buffer(32), 0), timestamp: 1231006505, bits: 486604799, - } + }, + dnsSeeds: [ + 'seed.bitcoin.sipa.be', + 'dnsseed.bluematt.me', + 'dnsseed.bitcoin.dashjr.org', + 'seed.bitcoinstats.com', + 'seed.bitnodes.io', + 'bitseed.xf2.org' + ], + defaultClientPort: 8333 }; exports.testnet = { @@ -39,5 +48,10 @@ exports.testnet = { prev_hash: buffertools.fill(new Buffer(32), 0), timestamp: 1296688602, bits: 486604799, - } + }, + dnsSeeds: [ + 'testnet-seed.bitcoin.petertodd.org', + 'testnet-seed.bluematt.me' + ], + defaultClientPort: 18333 };