From f2d092f23c57cb9a743c8cdccda2d56589067e04 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 16 Jan 2017 04:28:46 -0800 Subject: [PATCH] net: add priority nodes. --- etc/sample.conf | 1 + lib/net/bip150.js | 2 + lib/net/hostlist.js | 99 ++++++++++++++++++++++++++++++++++++++------ lib/net/pool.js | 17 ++++++-- lib/node/config.js | 19 +++++++-- lib/node/fullnode.js | 3 +- lib/node/spvnode.js | 3 +- 7 files changed, 123 insertions(+), 21 deletions(-) diff --git a/etc/sample.conf b/etc/sample.conf index 2d8293f6..42c42d7b 100644 --- a/etc/sample.conf +++ b/etc/sample.conf @@ -49,6 +49,7 @@ bip150: false identity-key: 74b4147957813b62cc8987f2b711ddb31f8cb46dcbf71502033da66053c8780a auth-peers: ./authorized-peers known-peers: ./known-peers +# nodes: 127.0.0.1,127.0.0.2 # Miner # payout-address: 1111111111111111111114oLvT2 diff --git a/lib/net/bip150.js b/lib/net/bip150.js index 177accbf..220cae82 100644 --- a/lib/net/bip150.js +++ b/lib/net/bip150.js @@ -634,6 +634,8 @@ AuthDB.prototype.populate = co(function* populate(addr, key) { try { hosts = yield this.resolve(addr.host, this.proxyServer); } catch (e) { + if (this.logger) + this.logger.error(e); return; } diff --git a/lib/net/hostlist.js b/lib/net/hostlist.js index f26973b7..5ecd7723 100644 --- a/lib/net/hostlist.js +++ b/lib/net/hostlist.js @@ -36,8 +36,10 @@ function HostList(options) { this.resolve = dns.resolve; this.banTime = common.BAN_TIME; this.rawSeeds = this.network.seeds; + this.rawNodes = []; this.seeds = []; + this.nodes = []; this.banned = {}; this.map = {}; @@ -103,6 +105,11 @@ HostList.prototype._initOptions = function initOptions(options) { assert(Array.isArray(options.seeds)); this.rawSeeds = options.seeds; } + + if (options.nodes) { + assert(Array.isArray(options.nodes)); + this.setNodes(options.nodes); + } }; /** @@ -665,12 +672,40 @@ HostList.prototype.setSeeds = function setSeeds(seeds) { /** * Add a preferred seed. - * @param {String} hostname + * @param {String} host */ HostList.prototype.addSeed = function addSeed(host) { var addr = IP.parseHost(host, this.network.port); - return this.seeds.push(addr); + this.seeds.push(addr); + return addr; +}; + +/** + * Set priority nodes. + * @param {String[]} nodes + */ + +HostList.prototype.setNodes = function setNodes(nodes) { + var i, node; + + this.rawNodes.length = 0; + + for (i = 0; i < nodes.length; i++) { + node = nodes[i]; + this.addNode(node); + } +}; + +/** + * Add a priority node. + * @param {String} host + */ + +HostList.prototype.addNode = function addNode(host) { + var addr = IP.parseHost(host, this.network.port); + this.rawNodes.push(addr); + return addr; }; /** @@ -680,7 +715,12 @@ HostList.prototype.addSeed = function addSeed(host) { HostList.prototype.discover = co(function* discover() { var jobs = []; - var i, seed; + var i, node, seed; + + for (i = 0; i < this.rawNodes.length; i++) { + node = this.rawNodes[i]; + jobs.push(this.lookupNode(node)); + } for (i = 0; i < this.seeds.length; i++) { seed = this.seeds[i]; @@ -690,6 +730,22 @@ HostList.prototype.discover = co(function* discover() { yield Promise.all(jobs); }); +/** + * Lookup node's domain. + * @param {Object} addr + * @returns {Promise} + */ + +HostList.prototype.lookupNode = co(function* lookupNode(addr) { + var addrs = yield this.lookup(addr); + + if (addrs.length === 0) + return; + + this.nodes.push(addrs[0]); + this.add(addrs[0]); +}); + /** * Populate from seed. * @param {Object} seed @@ -697,30 +753,49 @@ HostList.prototype.discover = co(function* discover() { */ HostList.prototype.populate = co(function* populate(seed) { + var addrs = yield this.lookup(seed); + var i, addr; + + for (i = 0; i < addrs.length; i++) { + addr = addrs[i]; + this.add(addr); + } +}); + +/** + * Lookup hosts from dns host. + * @param {Object} target + * @returns {Promise} + */ + +HostList.prototype.lookup = co(function* lookup(target) { + var addrs = []; var i, addr, hosts, host; - if (seed.version !== -1) { - addr = NetAddress.fromHost(seed.host, seed.port, this.network); - this.add(addr); - return; + if (target.version !== -1) { + addr = NetAddress.fromHost(target.host, target.port, this.network); + addrs.push(addr); + return addrs; } if (this.logger) - this.logger.info('Resolving hosts from seed: %s.', seed.host); + this.logger.info('Resolving host: %s.', target.host); try { - hosts = yield this.resolve(seed.host, this.proxyServer); + hosts = yield this.resolve(target.host, this.proxyServer); } catch (e) { if (this.logger) this.logger.error(e); - return; + return addrs; } for (i = 0; i < hosts.length; i++) { host = hosts[i]; - addr = NetAddress.fromHost(host, seed.port, this.network); - this.add(addr); + addr = NetAddress.fromHost(host, target.port, this.network); + addrs.push(addr); } + + return addrs; }); /** diff --git a/lib/net/pool.js b/lib/net/pool.js index 3f93e05c..078f5bac 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -1295,6 +1295,15 @@ Pool.prototype.getHost = function getHost(unique) { var now = this.network.now(); var i, entry, addr; + for (i = 0; i < this.hosts.nodes.length; i++) { + addr = this.hosts.nodes[i]; + + if (this.peers.has(addr.hostname)) + continue; + + return addr; + } + for (i = 0; i < 100; i++) { entry = this.hosts.getHost(); @@ -1929,7 +1938,7 @@ function PoolOptions(options) { this.feeRate = -1; this.noDiscovery = false; this.seeds = this.network.seeds; - this.preferredSeed = null; + this.nodes = []; this.invTimeout = 60000; this.services = common.LOCAL_SERVICES; this.requiredServices = common.REQUIRED_SERVICES; @@ -2116,9 +2125,9 @@ PoolOptions.prototype.fromOptions = function fromOptions(options) { this.seeds = options.seeds; } - if (options.preferredSeed) { - assert(typeof options.preferredSeed === 'string'); - this.seeds = [options.preferredSeed]; + if (options.nodes) { + assert(Array.isArray(options.nodes)); + this.nodes = options.nodes; } if (options.invTimeout != null) { diff --git a/lib/node/config.js b/lib/node/config.js index 0bc245e0..609b5feb 100644 --- a/lib/node/config.js +++ b/lib/node/config.js @@ -28,10 +28,12 @@ function config(options) { config.alias = { conf: {}, env: { - 'seed': 'preferredseed' + 'seed': 'seeds', + 'node': 'nodes' }, arg: { - 'seed': 'preferredseed', + 'seed': 'seeds', + 'node': 'nodes', 'n': 'network' } }; @@ -192,7 +194,8 @@ config.parseData = function parseData(data, prefix, dirname) { options.bip150 = bool(data.bip150); options.identityKey = key(data.identitykey); options.proxyServer = str(data.proxyserver); - options.preferredSeed = str(data.preferredseed); + options.seeds = list(data.seeds); + options.nodes = list(data.nodes); options.maxOutbound = num(data.maxoutbound); options.maxInbound = num(data.maxinbound); options.noDiscovery = bool(data.nodiscovery); @@ -635,6 +638,16 @@ function str(value) { return value; } +function list(value) { + if (!value) + return null; + + if (typeof value !== 'string') + return null; + + return value.trim().split(/\s*,\s*/); +} + function key(value) { var key; diff --git a/lib/node/fullnode.js b/lib/node/fullnode.js index 252ddf23..596cb737 100644 --- a/lib/node/fullnode.js +++ b/lib/node/fullnode.js @@ -113,7 +113,8 @@ function FullNode(options) { maxOutbound: this.options.maxOutbound, maxInbound: this.options.maxInbound, proxyServer: this.options.proxyServer, - preferredSeed: this.options.preferredSeed, + seeds: this.options.seeds, + nodes: this.options.nodes, noDiscovery: this.options.noDiscovery, port: this.options.port, listen: this.options.listen diff --git a/lib/node/spvnode.js b/lib/node/spvnode.js index d4254a30..498e5328 100644 --- a/lib/node/spvnode.js +++ b/lib/node/spvnode.js @@ -64,7 +64,8 @@ function SPVNode(options) { chain: this.chain, witness: this.options.witness, proxyServer: this.options.proxyServer, - preferredSeed: this.options.preferredSeed, + seeds: this.options.seeds, + nodes: this.options.nodes, bip151: this.options.bip151, bip150: this.options.bip150, authPeers: this.options.authPeers,