From 83969c6b735eb3729964bbe40696bc9888e4c92c Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Wed, 3 Aug 2016 17:06:38 +0200 Subject: [PATCH 01/16] refactor --- modules/ethereumNode.js | 12 ++-- modules/getNodePath.js | 139 ++++++++++++++++++++++++++++++++-------- 2 files changed, 118 insertions(+), 33 deletions(-) diff --git a/modules/ethereumNode.js b/modules/ethereumNode.js index d565fd5ae..3a08e8464 100644 --- a/modules/ethereumNode.js +++ b/modules/ethereumNode.js @@ -34,13 +34,15 @@ class EthereumNode extends EventEmitter { super(); this.STATES = STATES; - + this._loadDefaults(); this._node = null; this._type = null; this._network = null; + getNodePath(); + this._socket = Sockets.get('node-ipc', Settings.rpcMode); this.on('data', _.bind(this._logNodeData, this)); @@ -331,10 +333,10 @@ class EthereumNode extends EventEmitter { log.debug(`Start node using ${binPath}`); - return new Q((resolve, reject) => { - this.__startProcess(nodeType, network, binPath) - .then(resolve, reject); - }); + return new Q((resolve, reject) => { + this.__startProcess(nodeType, network, binPath) + .then(resolve, reject); + }); } diff --git a/modules/getNodePath.js b/modules/getNodePath.js index c0f58ac68..cfb4ebeb9 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -7,52 +7,135 @@ Gets the right Node path */ const path = require('path'); +const fs = require('fs'); +const exec = require('child_process').exec; +const cmpVer = require('semver-compare'); const binaryPath = path.resolve(__dirname + '/../nodes'); const log = require('./utils/logger').create('getNodePath'); const Settings = require('./settings'); // cache -const resolvedPaths = {}; +var paths = {}, // all versions (system + bundled): { type: { path: version } } + resolvedPaths = {}; // latest version: { type: path } + +const resolvedPathsOld = {}; // latest version: { type: path } -module.exports = function(type) { - if (resolvedPaths[type]) { - return resolvedPaths[type]; - } - let ret = ''; +/** + * Get path of system node + * + * @param {String} type the type of node (i.e. 'geth', 'eth') + */ +function getSystemPath(type) { + var proc = exec('type ' + type, (e, stdout, stderr) => { + if (!e) + // create new entry for path without version + paths[type][stdout.match(/(\/\w+)+/)[0]] = null; + }); +} - // global override? - let globallySetType = Settings[`${type}Path`]; - - if (globallySetType) { - resolvedPaths[type] = globallySetType; - } else { - var binPath = (Settings.inProductionMode) - ? binaryPath.replace('nodes','node') + '/'+ type +'/'+ type - : binaryPath + '/'+ type +'/'+ process.platform +'-'+ process.arch + '/'+ type; - - if(Settings.inProductionMode) { - binPath = binPath.replace('app.asar/','').replace('app.asar\\',''); - - if(process.platform === 'darwin') { - binPath = path.resolve(binPath.replace('/node/', '/../Frameworks/node/')); + +/** + * Get versions of node (system and bundled) + * + * @param {String} type the type of node (i.e. 'geth', 'eth') + */ +function getVersion(type) { + setTimeout(() => { + for (var path in paths[type]) { + switch (type) { + case 'geth': + var command = 'echo ' + path + ' && ' + path + ' version'; // stupid, use echo to pass path variable) + break; + case 'eth': + case 'parity': + var command = 'echo ' + path + ' && ' + path + ' --version'; + break; } + var proc = exec(command, (e, stdout, stderr) => { + if (!e) { + // add version to path entry + var path = stdout.match(/(\/.+)+/)[0]; + var version = stdout.match(/[\d.]{3,}/)[0]; + paths[type][path] = version; + } + }); } + }, 50); // 3ms are sufficient on a SSD macbookpro for getSystemPath(type) +} + + +/** + * Scans for bundled nodes + */ + function getBundledNodes() { + fs.readdirSync('nodes/').forEach((type) => { + if (fs.statSync('nodes/' + type).isDirectory()) // .DS_Store files... ?? + fs.readdirSync('nodes/' + type).forEach((platform) => { + if (platform.indexOf(process.platform) !== -1) { + // this structure triggers the inculsion of a node type + var nodePath = path.resolve('nodes/' + type + '/' + platform + '/' + type); + paths[type] = {}; + paths[type][nodePath] = null; + } + }); + }); +} - if(process.platform === 'win32') { - binPath = binPath.replace(/\/+/,'\\'); - binPath += '.exe'; +/** + * Get paths of all nodes, returns system or bundled path depending on the latest version + */ +/* +function getNodePaths() { + getBundledNodes(); + log.warn(paths); + + for (var type in paths) { + getVersion(type, getSystemPath(type)); + } + + setTimeout(() => { + // console.log(paths); // diplays all nodes, paths + versions + for (type in paths) { + var path = Object.keys(paths[type])[0]; + if (Object.keys(paths[type]).length > 1) { + path = (cmpVer(Object.keys(paths[type])[0], Object.keys(paths[type])[1])) ? Object.keys(paths[type])[0] : Object.keys(paths[type])[1] + } + resolvedPaths[type] = path; } + log.info(resolvedPaths); + return resolvedPaths; + }, 1500); // 100ms (geth) / 900ms (eth) are sufficient on a SSD macbookpro (for two calls) +}*/ + + +module.exports = function(type) { + if (resolvedPaths[type]) { + return resolvedPaths[type]; + } + + getBundledNodes(); - resolvedPaths[type] = binPath; + for (var type in paths) { + getVersion(type, getSystemPath(type)); } - log.debug(`Resolved path for ${type}: ${resolvedPaths[type]}`); + setTimeout(() => { + // console.log(paths); // diplays all nodes, paths + versions + for (type in paths) { + var path = Object.keys(paths[type])[0]; + if (Object.keys(paths[type]).length > 1) { + path = (cmpVer(Object.keys(paths[type])[0], Object.keys(paths[type])[1])) ? Object.keys(paths[type])[0] : Object.keys(paths[type])[1] + } + resolvedPaths[type] = path; + } - return resolvedPaths[type]; -}; + log.info('Available backends: %j', resolvedPaths); + return resolvedPaths[type]; + }, 1500); // 100ms (geth) / 900ms (eth) are sufficient on a SSD macbookpro (for two calls) +} From 0ed955471893c04ee6ab801f073b360ce953f94d Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Wed, 3 Aug 2016 17:34:18 +0200 Subject: [PATCH 02/16] cleanup --- modules/ethereumNode.js | 10 +++++----- modules/getNodePath.js | 43 ++++++----------------------------------- 2 files changed, 11 insertions(+), 42 deletions(-) diff --git a/modules/ethereumNode.js b/modules/ethereumNode.js index 3a08e8464..b59fae8e1 100644 --- a/modules/ethereumNode.js +++ b/modules/ethereumNode.js @@ -34,7 +34,7 @@ class EthereumNode extends EventEmitter { super(); this.STATES = STATES; - + this._loadDefaults(); this._node = null; @@ -333,10 +333,10 @@ class EthereumNode extends EventEmitter { log.debug(`Start node using ${binPath}`); - return new Q((resolve, reject) => { - this.__startProcess(nodeType, network, binPath) - .then(resolve, reject); - }); + return new Q((resolve, reject) => { + this.__startProcess(nodeType, network, binPath) + .then(resolve, reject); + }); } diff --git a/modules/getNodePath.js b/modules/getNodePath.js index cfb4ebeb9..17e94a84a 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -18,9 +18,6 @@ const Settings = require('./settings'); // cache var paths = {}, // all versions (system + bundled): { type: { path: version } } resolvedPaths = {}; // latest version: { type: path } - -const resolvedPathsOld = {}; // latest version: { type: path } - /** @@ -31,7 +28,6 @@ const resolvedPathsOld = {}; // latest version: { type: path function getSystemPath(type) { var proc = exec('type ' + type, (e, stdout, stderr) => { if (!e) - // create new entry for path without version paths[type][stdout.match(/(\/\w+)+/)[0]] = null; }); } @@ -88,54 +84,27 @@ function getVersion(type) { /** * Get paths of all nodes, returns system or bundled path depending on the latest version */ -/* -function getNodePaths() { - getBundledNodes(); - log.warn(paths); - - for (var type in paths) { - getVersion(type, getSystemPath(type)); - } - - setTimeout(() => { - // console.log(paths); // diplays all nodes, paths + versions - for (type in paths) { - var path = Object.keys(paths[type])[0]; - if (Object.keys(paths[type]).length > 1) { - path = (cmpVer(Object.keys(paths[type])[0], Object.keys(paths[type])[1])) ? Object.keys(paths[type])[0] : Object.keys(paths[type])[1] - } - resolvedPaths[type] = path; - } - log.info(resolvedPaths); - return resolvedPaths; - }, 1500); // 100ms (geth) / 900ms (eth) are sufficient on a SSD macbookpro (for two calls) -}*/ - - module.exports = function(type) { - if (resolvedPaths[type]) { + if (resolvedPaths[type]) return resolvedPaths[type]; - } getBundledNodes(); - for (var type in paths) { - getVersion(type, getSystemPath(type)); - } + if (process.platform === 'linux' || process.platform === 'darwin') + for (var type in paths) + getVersion(type, getSystemPath(type)); setTimeout(() => { - // console.log(paths); // diplays all nodes, paths + versions for (type in paths) { var path = Object.keys(paths[type])[0]; - if (Object.keys(paths[type]).length > 1) { + if (Object.keys(paths[type]).length > 1) path = (cmpVer(Object.keys(paths[type])[0], Object.keys(paths[type])[1])) ? Object.keys(paths[type])[0] : Object.keys(paths[type])[1] - } resolvedPaths[type] = path; } log.info('Available backends: %j', resolvedPaths); return resolvedPaths[type]; - }, 1500); // 100ms (geth) / 900ms (eth) are sufficient on a SSD macbookpro (for two calls) + }, 1500); // 100ms (geth) / 900ms (eth) are sufficient on a SSD macbookpro for two calls (bundled and system) } From df4bd005e3171bd0d59498f12fa575967102d2c2 Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Wed, 3 Aug 2016 17:56:09 +0200 Subject: [PATCH 03/16] update package.json --- modules/getNodePath.js | 78 ++++++++++++++++++++++++++---------------- package.json | 1 + 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index 17e94a84a..38c5d30f3 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -16,7 +16,7 @@ const Settings = require('./settings'); // cache -var paths = {}, // all versions (system + bundled): { type: { path: version } } +const paths = {}, // all versions (system + bundled): { type: { path: version } } resolvedPaths = {}; // latest version: { type: path } @@ -40,22 +40,19 @@ function getSystemPath(type) { */ function getVersion(type) { setTimeout(() => { - for (var path in paths[type]) { + for (let path in paths[type]) { switch (type) { case 'geth': - var command = 'echo ' + path + ' && ' + path + ' version'; // stupid, use echo to pass path variable) + var command = path + ' version'; break; case 'eth': case 'parity': - var command = 'echo ' + path + ' && ' + path + ' --version'; + var command = path + ' --version'; break; } var proc = exec(command, (e, stdout, stderr) => { if (!e) { - // add version to path entry - var path = stdout.match(/(\/.+)+/)[0]; - var version = stdout.match(/[\d.]{3,}/)[0]; - paths[type][path] = version; + paths[type][path] = stdout.match(/[\d.]+/)[0]; } }); } @@ -64,32 +61,52 @@ function getVersion(type) { /** - * Scans for bundled nodes + * Get paths of all nodes, returns system or bundled path depending on the latest version + * + * @param {String} type the type of node (i.e. 'geth', 'eth') */ - function getBundledNodes() { - fs.readdirSync('nodes/').forEach((type) => { - if (fs.statSync('nodes/' + type).isDirectory()) // .DS_Store files... ?? - fs.readdirSync('nodes/' + type).forEach((platform) => { - if (platform.indexOf(process.platform) !== -1) { - // this structure triggers the inculsion of a node type - var nodePath = path.resolve('nodes/' + type + '/' + platform + '/' + type); +module.exports = function(type) { + // return path if already resolved + if (resolvedPaths[type]) { + return resolvedPaths[type]; + } + + // resolve base path of bundled nodes + var binPath = (Settings.inProductionMode) + ? binaryPath.replace('nodes','node') + : binaryPath + + if(Settings.inProductionMode) { + binPath = binPath.replace('app.asar/','').replace('app.asar\\',''); + + if(process.platform === 'darwin') { + binPath = path.resolve(binPath.replace('/node', '/../Frameworks/node')); + } + + if(process.platform === 'win32') { + binPath = binPath.replace(/\/+/,'\\'); + binPath += '.exe'; + } + } + + // resolve node binary paths + if (Settings.inProductionMode) { + fs.readdirSync(binPath).forEach((type) => { + var nodePath = binPath + '/' + type + '/' + type; + paths[type] = {}; + paths[type][nodePath] = null; + }); + } else { + fs.readdirSync('nodes/').forEach((type) => { + if (fs.statSync('nodes/' + type).isDirectory()) { + var nodePath = path.resolve('nodes/' + type + '/' + process.platform +'-'+ process.arch + '/' + type); paths[type] = {}; paths[type][nodePath] = null; } }); - }); -} - - -/** - * Get paths of all nodes, returns system or bundled path depending on the latest version - */ -module.exports = function(type) { - if (resolvedPaths[type]) - return resolvedPaths[type]; - - getBundledNodes(); + } + // compare versions to system-wide installed nodes (only linux and mac) if (process.platform === 'linux' || process.platform === 'darwin') for (var type in paths) getVersion(type, getSystemPath(type)); @@ -97,14 +114,15 @@ module.exports = function(type) { setTimeout(() => { for (type in paths) { var path = Object.keys(paths[type])[0]; + if (Object.keys(paths[type]).length > 1) path = (cmpVer(Object.keys(paths[type])[0], Object.keys(paths[type])[1])) ? Object.keys(paths[type])[0] : Object.keys(paths[type])[1] + resolvedPaths[type] = path; } - log.info('Available backends: %j', resolvedPaths); + log.info('Prefered backends: %j', resolvedPaths); return resolvedPaths[type]; }, 1500); // 100ms (geth) / 900ms (eth) are sufficient on a SSD macbookpro for two calls (bundled and system) } - diff --git a/package.json b/package.json index fc7a10c44..6d9d3de27 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "numeral": "^1.5.3", "os-timesync": "^1.0.6", "semver": "^5.1.0", + "semver-compare": "^1.0.0", "solc": "^0.3.1-1", "underscore": "^1.8.3", "uuid": "^2.0.2", From 4fdbe9edc411c45586c7b06642a246733a4ab11f Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Wed, 3 Aug 2016 22:22:35 +0200 Subject: [PATCH 04/16] add debug log messages --- modules/getNodePath.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index 38c5d30f3..a26b611f2 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -56,7 +56,7 @@ function getVersion(type) { } }); } - }, 50); // 3ms are sufficient on a SSD macbookpro for getSystemPath(type) + }, 200); } @@ -121,8 +121,8 @@ module.exports = function(type) { resolvedPaths[type] = path; } - log.info('Prefered backends: %j', resolvedPaths); + log.debug('Available backends: %j', paths); return resolvedPaths[type]; - }, 1500); // 100ms (geth) / 900ms (eth) are sufficient on a SSD macbookpro for two calls (bundled and system) + }, 3000); } From b342175e2ef10d2de84df7a43d7932c5006d0b1a Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Wed, 3 Aug 2016 22:31:10 +0200 Subject: [PATCH 05/16] fix win builds --- modules/getNodePath.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index a26b611f2..cfe465017 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -84,8 +84,8 @@ module.exports = function(type) { } if(process.platform === 'win32') { + binPath += '/' + type + '/' + type + '.exe'; binPath = binPath.replace(/\/+/,'\\'); - binPath += '.exe'; } } From 1557f8dd931f04adf4204d891078b55fa6e1c733 Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Wed, 3 Aug 2016 22:54:47 +0200 Subject: [PATCH 06/16] cleanup --- modules/getNodePath.js | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index cfe465017..03ecc21b4 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -66,33 +66,25 @@ function getVersion(type) { * @param {String} type the type of node (i.e. 'geth', 'eth') */ module.exports = function(type) { - // return path if already resolved if (resolvedPaths[type]) { return resolvedPaths[type]; } - // resolve base path of bundled nodes - var binPath = (Settings.inProductionMode) - ? binaryPath.replace('nodes','node') - : binaryPath - if(Settings.inProductionMode) { - binPath = binPath.replace('app.asar/','').replace('app.asar\\',''); + binPath = binPath.replace('nodes','node').replace('app.asar/','').replace('app.asar\\',''); if(process.platform === 'darwin') { binPath = path.resolve(binPath.replace('/node', '/../Frameworks/node')); } - if(process.platform === 'win32') { - binPath += '/' + type + '/' + type + '.exe'; - binPath = binPath.replace(/\/+/,'\\'); - } - } - - // resolve node binary paths - if (Settings.inProductionMode) { fs.readdirSync(binPath).forEach((type) => { var nodePath = binPath + '/' + type + '/' + type; + + if(process.platform === 'win32') { + binPath += '.exe'; + binPath = binPath.replace(/\/+/,'\\'); + } + paths[type] = {}; paths[type][nodePath] = null; }); @@ -106,10 +98,10 @@ module.exports = function(type) { }); } - // compare versions to system-wide installed nodes (only linux and mac) - if (process.platform === 'linux' || process.platform === 'darwin') + if (process.platform === 'linux' || process.platform === 'darwin') { for (var type in paths) getVersion(type, getSystemPath(type)); + } setTimeout(() => { for (type in paths) { From e79fe1cb844011e5c36915e65bd262523c5e766c Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Sun, 7 Aug 2016 14:35:44 +0200 Subject: [PATCH 07/16] fix weird win build bug --- modules/getNodePath.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index 03ecc21b4..a7d2d0c5b 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -71,7 +71,7 @@ module.exports = function(type) { } if(Settings.inProductionMode) { - binPath = binPath.replace('nodes','node').replace('app.asar/','').replace('app.asar\\',''); + var binPath = binaryPath.replace('nodes','node').replace('app.asar/','').replace('app.asar\\',''); if(process.platform === 'darwin') { binPath = path.resolve(binPath.replace('/node', '/../Frameworks/node')); @@ -81,8 +81,8 @@ module.exports = function(type) { var nodePath = binPath + '/' + type + '/' + type; if(process.platform === 'win32') { - binPath += '.exe'; - binPath = binPath.replace(/\/+/,'\\'); + nodePath = nodePath.replace(/\/+/,'\\'); + nodePath += '.exe'; } paths[type] = {}; @@ -114,7 +114,5 @@ module.exports = function(type) { } log.debug('Available backends: %j', paths); - - return resolvedPaths[type]; }, 3000); } From dd131d7502870d99f53ca056e3195b0c8d9fa2f3 Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Mon, 8 Aug 2016 17:29:08 +0200 Subject: [PATCH 08/16] use promises --- modules/getNodePath.js | 145 ++++++++++++++++++++++++----------------- 1 file changed, 85 insertions(+), 60 deletions(-) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index a7d2d0c5b..e8d422294 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -9,6 +9,7 @@ Gets the right Node path const path = require('path'); const fs = require('fs'); const exec = require('child_process').exec; +const Q = require('bluebird'); const cmpVer = require('semver-compare'); const binaryPath = path.resolve(__dirname + '/../nodes'); const log = require('./utils/logger').create('getNodePath'); @@ -26,9 +27,9 @@ const paths = {}, // all versions (system + bundled): { type: { path: ve * @param {String} type the type of node (i.e. 'geth', 'eth') */ function getSystemPath(type) { - var proc = exec('type ' + type, (e, stdout, stderr) => { - if (!e) - paths[type][stdout.match(/(\/\w+)+/)[0]] = null; + return new Q((resolve, reject) => { + var proc = exec('type ' + type); + proc.stdout.on('data', resolve); }); } @@ -37,26 +38,38 @@ function getSystemPath(type) { * Get versions of node (system and bundled) * * @param {String} type the type of node (i.e. 'geth', 'eth') + * @param {String} path the path of the node instance */ -function getVersion(type) { - setTimeout(() => { - for (let path in paths[type]) { - switch (type) { - case 'geth': - var command = path + ' version'; - break; - case 'eth': - case 'parity': - var command = path + ' --version'; - break; +function getVersion(type, path) { + return new Q((resolve, reject) => { + switch (type) { + case 'geth': + var command = path + ' version'; + break; + case 'eth': + case 'parity': + var command = path + ' --version'; + break; + } + var proc = exec(command); + proc.stdout.on('data', resolve); + }); +} + + +/** + * Compare versions of system and bundled nodes + */ +function compareNodes() { + return new Q((resolve, reject) => { + for (let type in paths) { + var path = Object.keys(paths[type])[0]; + if (Object.keys(paths[type]).length > 1) { + path = (cmpVer(Object.keys(paths[type])[0], Object.keys(paths[type])[1])) ? Object.keys(paths[type])[0] : Object.keys(paths[type])[1] } - var proc = exec(command, (e, stdout, stderr) => { - if (!e) { - paths[type][path] = stdout.match(/[\d.]+/)[0]; - } - }); + resolvedPaths[type] = path; } - }, 200); + }); } @@ -66,53 +79,65 @@ function getVersion(type) { * @param {String} type the type of node (i.e. 'geth', 'eth') */ module.exports = function(type) { - if (resolvedPaths[type]) { + if (resolvedPaths[type]) return resolvedPaths[type]; - } - - if(Settings.inProductionMode) { - var binPath = binaryPath.replace('nodes','node').replace('app.asar/','').replace('app.asar\\',''); - - if(process.platform === 'darwin') { - binPath = path.resolve(binPath.replace('/node', '/../Frameworks/node')); - } + + return new Q((resolve, reject) => { + if(Settings.inProductionMode) { + var binPath = binaryPath.replace('nodes','node').replace('app.asar/','').replace('app.asar\\',''); + + if(process.platform === 'darwin') { + binPath = path.resolve(binPath.replace('/node', '/../Frameworks/node')); + } - fs.readdirSync(binPath).forEach((type) => { - var nodePath = binPath + '/' + type + '/' + type; + fs.readdirSync(binPath).forEach((type) => { + var nodePath = binPath + '/' + type + '/' + type; - if(process.platform === 'win32') { - nodePath = nodePath.replace(/\/+/,'\\'); - nodePath += '.exe'; - } + if(process.platform === 'win32') { + nodePath = nodePath.replace(/\/+/,'\\'); + nodePath += '.exe'; + } - paths[type] = {}; - paths[type][nodePath] = null; - }); - } else { - fs.readdirSync('nodes/').forEach((type) => { - if (fs.statSync('nodes/' + type).isDirectory()) { - var nodePath = path.resolve('nodes/' + type + '/' + process.platform +'-'+ process.arch + '/' + type); paths[type] = {}; paths[type][nodePath] = null; + }); + } else { + fs.readdirSync('nodes/').forEach((type) => { + if (fs.statSync('nodes/' + type).isDirectory()) { + var nodePath = path.resolve('nodes/' + type + '/' + process.platform +'-'+ process.arch + '/' + type); + paths[type] = {}; + paths[type][nodePath] = null; + } + }); + } + + if (process.platform === 'linux' || process.platform === 'darwin') { + var getPathProms = [], + getVersionProms = []; + + for (let type in paths) { + getPathProms.push(getSystemPath(type) + .then((data) => { + paths[type][data.match(/(\/\w+)+/)[0]] = null; + })); } - }); - } - if (process.platform === 'linux' || process.platform === 'darwin') { - for (var type in paths) - getVersion(type, getSystemPath(type)); - } - - setTimeout(() => { - for (type in paths) { - var path = Object.keys(paths[type])[0]; - - if (Object.keys(paths[type]).length > 1) - path = (cmpVer(Object.keys(paths[type])[0], Object.keys(paths[type])[1])) ? Object.keys(paths[type])[0] : Object.keys(paths[type])[1] - - resolvedPaths[type] = path; + Q.all(getPathProms).then(() => { + for (let type in paths) { + for (let path in paths[type]) { + getVersionProms.push(getVersion(type, path) + .then((data)=>{ + var version = data.match(/[\d.]+/)[0]; + paths[type][path] = version; + })); + } + } + }).then(() => { + Q.all(getVersionProms).then(() => { + compareNodes(); + log.debug('Available backends: %j', paths); + }) + }); } - - log.debug('Available backends: %j', paths); - }, 3000); + }); } From 0e5dad8ac5e2ffd4d04aa7984a1a2b7459228216 Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Mon, 8 Aug 2016 20:18:08 +0200 Subject: [PATCH 09/16] integration into ethereumNode.js --- modules/ethereumNode.js | 16 ++--- modules/getNodePath.js | 131 ++++++++++++++++++++++------------------ 2 files changed, 80 insertions(+), 67 deletions(-) diff --git a/modules/ethereumNode.js b/modules/ethereumNode.js index b59fae8e1..196d7421b 100644 --- a/modules/ethereumNode.js +++ b/modules/ethereumNode.js @@ -41,8 +41,6 @@ class EthereumNode extends EventEmitter { this._type = null; this._network = null; - getNodePath(); - this._socket = Sockets.get('node-ipc', Settings.rpcMode); this.on('data', _.bind(this._logNodeData, this)); @@ -329,13 +327,15 @@ class EthereumNode extends EventEmitter { this._network = network; this._type = nodeType; - const binPath = getNodePath(nodeType); - - log.debug(`Start node using ${binPath}`); - return new Q((resolve, reject) => { - this.__startProcess(nodeType, network, binPath) - .then(resolve, reject); + getNodePath.probe() + .then(() => { + const binPath = getNodePath.query(nodeType); + log.debug(`Start node using ${binPath}`); + + this.__startProcess(nodeType, network, binPath) + .then(resolve, reject); + }); }); } diff --git a/modules/getNodePath.js b/modules/getNodePath.js index e8d422294..f89909354 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -6,10 +6,10 @@ Gets the right Node path @module getNodePath */ -const path = require('path'); const fs = require('fs'); -const exec = require('child_process').exec; +const path = require('path'); const Q = require('bluebird'); +const exec = require('child_process').exec; const cmpVer = require('semver-compare'); const binaryPath = path.resolve(__dirname + '/../nodes'); const log = require('./utils/logger').create('getNodePath'); @@ -73,71 +73,84 @@ function compareNodes() { } -/** - * Get paths of all nodes, returns system or bundled path depending on the latest version - * - * @param {String} type the type of node (i.e. 'geth', 'eth') - */ -module.exports = function(type) { - if (resolvedPaths[type]) - return resolvedPaths[type]; - - return new Q((resolve, reject) => { - if(Settings.inProductionMode) { - var binPath = binaryPath.replace('nodes','node').replace('app.asar/','').replace('app.asar\\',''); - - if(process.platform === 'darwin') { - binPath = path.resolve(binPath.replace('/node', '/../Frameworks/node')); - } +module.exports = { + /** + * Returns path of node + * linux and mac only: returns system or bundled path depending on the latest version + * + * @param {String} type the type of node (i.e. 'geth', 'eth') + */ + query: (type) => { + return resolvedPaths[type]; + }, + /** + * Evaluates node paths + * - Enumerates bundled nodes + * linux and mac only: + * - probes for system installation of nodes + * - compares the versions of bundled and system nodes (preferes latest version) + */ + probe: () => { + return new Q((resolve, reject) => { + if(Settings.inProductionMode) { + var binPath = binaryPath.replace('nodes','node').replace('app.asar/','').replace('app.asar\\',''); + + if(process.platform === 'darwin') { + binPath = path.resolve(binPath.replace('/node', '/../Frameworks/node')); + } - fs.readdirSync(binPath).forEach((type) => { - var nodePath = binPath + '/' + type + '/' + type; + fs.readdirSync(binPath).forEach((type) => { + var nodePath = binPath + '/' + type + '/' + type; - if(process.platform === 'win32') { - nodePath = nodePath.replace(/\/+/,'\\'); - nodePath += '.exe'; - } + if(process.platform === 'win32') { + nodePath = nodePath.replace(/\/+/,'\\'); + nodePath += '.exe'; + } - paths[type] = {}; - paths[type][nodePath] = null; - }); - } else { - fs.readdirSync('nodes/').forEach((type) => { - if (fs.statSync('nodes/' + type).isDirectory()) { - var nodePath = path.resolve('nodes/' + type + '/' + process.platform +'-'+ process.arch + '/' + type); paths[type] = {}; paths[type][nodePath] = null; - } - }); - } - - if (process.platform === 'linux' || process.platform === 'darwin') { - var getPathProms = [], - getVersionProms = []; - - for (let type in paths) { - getPathProms.push(getSystemPath(type) - .then((data) => { - paths[type][data.match(/(\/\w+)+/)[0]] = null; - })); + }); + } else { + fs.readdirSync('nodes/').forEach((type) => { + if (fs.statSync('nodes/' + type).isDirectory()) { + var nodePath = path.resolve('nodes/' + type + '/' + process.platform +'-'+ process.arch + '/' + type); + paths[type] = {}; + paths[type][nodePath] = null; + } + }); } + + if (process.platform === 'linux' || process.platform === 'darwin') { + var getPathProms = [], + getVersionProms = []; - Q.all(getPathProms).then(() => { for (let type in paths) { - for (let path in paths[type]) { - getVersionProms.push(getVersion(type, path) - .then((data)=>{ - var version = data.match(/[\d.]+/)[0]; - paths[type][path] = version; - })); - } + getPathProms.push(getSystemPath(type) + .then((data) => { + paths[type][data.match(/(\/\w+)+/)[0]] = null; + })); } - }).then(() => { - Q.all(getVersionProms).then(() => { - compareNodes(); - log.debug('Available backends: %j', paths); + + Q.all(getPathProms).then(() => { + for (let type in paths) { + for (let path in paths[type]) { + getVersionProms.push(getVersion(type, path) + .then((data)=>{ + var version = data.match(/[\d.]+/)[0]; + paths[type][path] = version; + })); + } + } + }).then(() => { + Q.all(getVersionProms).then(() => { + compareNodes(); + log.debug('Available backends: %j', paths); + }) + .then(resolve, reject); }) - }); - } - }); + } else { + resolve(); + } + }); + } } From 2a2a748ef2d0b7d07c7f93f2db80ef81c8df4712 Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Mon, 8 Aug 2016 21:15:06 +0200 Subject: [PATCH 10/16] fix windows build --- modules/getNodePath.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index f89909354..9f337a7c9 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -81,7 +81,7 @@ module.exports = { * @param {String} type the type of node (i.e. 'geth', 'eth') */ query: (type) => { - return resolvedPaths[type]; + return resolvedPaths[type]; }, /** * Evaluates node paths @@ -149,6 +149,12 @@ module.exports = { .then(resolve, reject); }) } else { + for (let type in paths) { + for (let path in paths[type]) { + resolvedPaths[type] = path; + } + } + log.debug('Available backends: %j', paths); resolve(); } }); From cbb482a84871b62d9adf17d08d2ed1c1926937dc Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Tue, 9 Aug 2016 00:50:09 +0200 Subject: [PATCH 11/16] dynamically populate node menu --- modules/ethereumNode.js | 4 +++- modules/getNodePath.js | 8 ++++---- modules/menuItems.js | 35 ++++++++++++----------------------- 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/modules/ethereumNode.js b/modules/ethereumNode.js index 196d7421b..72e341185 100644 --- a/modules/ethereumNode.js +++ b/modules/ethereumNode.js @@ -41,6 +41,8 @@ class EthereumNode extends EventEmitter { this._type = null; this._network = null; + getNodePath.probe(); + this._socket = Sockets.get('node-ipc', Settings.rpcMode); this.on('data', _.bind(this._logNodeData, this)); @@ -330,7 +332,7 @@ class EthereumNode extends EventEmitter { return new Q((resolve, reject) => { getNodePath.probe() .then(() => { - const binPath = getNodePath.query(nodeType); + const binPath = getNodePath.query()[nodeType]; log.debug(`Start node using ${binPath}`); this.__startProcess(nodeType, network, binPath) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index 9f337a7c9..db9fabfac 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -80,18 +80,18 @@ module.exports = { * * @param {String} type the type of node (i.e. 'geth', 'eth') */ - query: (type) => { - return resolvedPaths[type]; + query: () => { + return resolvedPaths; }, /** * Evaluates node paths * - Enumerates bundled nodes * linux and mac only: * - probes for system installation of nodes - * - compares the versions of bundled and system nodes (preferes latest version) + * - compares the versions of bundled and system nodes (preferres latest version) */ probe: () => { - return new Q((resolve, reject) => { + return new Q((resolve, reject) => { if(Settings.inProductionMode) { var binPath = binaryPath.replace('nodes','node').replace('app.asar/','').replace('app.asar\\',''); diff --git a/modules/menuItems.js b/modules/menuItems.js index c455506f2..c8dbcf373 100644 --- a/modules/menuItems.js +++ b/modules/menuItems.js @@ -7,6 +7,7 @@ const shell = electron.shell; const log = require('./utils/logger').create('menuItems'); const ipc = electron.ipcMain; const ethereumNode = require('./ethereumNode.js'); +const getNodePath = require('./getNodePath.js'); const Windows = require('./windows'); const updateChecker = require('./updateChecker'); const Settings = require('./settings'); @@ -342,39 +343,27 @@ var menuTempl = function(webviews) { } ]; - - - - // add node switching menu devToolsMenu.push({ type: 'separator' }); // add node switch if(process.platform === 'darwin' || process.platform === 'win32') { - devToolsMenu.push({ - label: i18n.t('mist.applicationMenu.develop.ethereumNode'), - submenu: [ - { - label: 'Geth 1.4.10 (Go)', - checked: ethereumNode.isOwnNode && ethereumNode.isGeth, + var nodesMenu = []; + for (let type in getNodePath.query()) + nodesMenu.push({ + label: type.charAt(0).toUpperCase() + type.slice(1), + checked: ethereumNode.isOwnNode && ethereumNode.type === type, enabled: ethereumNode.isOwnNode, type: 'checkbox', click: function(){ - restartNode('geth'); + restartNode(type); } - }, - { - label: 'Eth 1.2.9 (C++) [no hardfork support!]', - /*checked: ethereumNode.isOwnNode && ethereumNode.isEth, - enabled: ethereumNode.isOwnNode,*/ - enabled: false, - type: 'checkbox', - click: function(){ - restartNode('eth'); - } - } - ]}); + }); + devToolsMenu.push({ + label: i18n.t('mist.applicationMenu.develop.ethereumNode'), + submenu: nodesMenu + }); } // add network switch From 65b5c2f5ca66bc2bbecff3f3303f90935a4f0d3b Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Tue, 9 Aug 2016 01:45:37 +0200 Subject: [PATCH 12/16] menu: check and hint if external node --- interface/i18n/mist.en.i18n.json | 2 ++ modules/ethereumNode.js | 2 -- modules/menuItems.js | 41 +++++++++++++++++++++----------- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/interface/i18n/mist.en.i18n.json b/interface/i18n/mist.en.i18n.json index c09ea0ff4..faddbab36 100644 --- a/interface/i18n/mist.en.i18n.json +++ b/interface/i18n/mist.en.i18n.json @@ -59,6 +59,8 @@ "runTests": "Run tests", "logFiles": "Show log file", "ethereumNode": "Ethereum Node", + "starting": "starting", + "externalNode": "using external node", "network": "Network", "mainNetwork": "Main Network", "startMining": "⛏ Start Mining (Testnet only)", diff --git a/modules/ethereumNode.js b/modules/ethereumNode.js index 72e341185..fc272ba8d 100644 --- a/modules/ethereumNode.js +++ b/modules/ethereumNode.js @@ -41,8 +41,6 @@ class EthereumNode extends EventEmitter { this._type = null; this._network = null; - getNodePath.probe(); - this._socket = Sockets.get('node-ipc', Settings.rpcMode); this.on('data', _.bind(this._logNodeData, this)); diff --git a/modules/menuItems.js b/modules/menuItems.js index c8dbcf373..c245d27c3 100644 --- a/modules/menuItems.js +++ b/modules/menuItems.js @@ -349,9 +349,9 @@ var menuTempl = function(webviews) { }); // add node switch if(process.platform === 'darwin' || process.platform === 'win32') { - var nodesMenu = []; + var nodes = []; for (let type in getNodePath.query()) - nodesMenu.push({ + nodes.push({ label: type.charAt(0).toUpperCase() + type.slice(1), checked: ethereumNode.isOwnNode && ethereumNode.type === type, enabled: ethereumNode.isOwnNode, @@ -360,17 +360,29 @@ var menuTempl = function(webviews) { restartNode(type); } }); - devToolsMenu.push({ - label: i18n.t('mist.applicationMenu.develop.ethereumNode'), - submenu: nodesMenu - }); + var submenu = { 'label': i18n.t('mist.applicationMenu.develop.ethereumNode') }; + if (ethereumNode.state === undefined) { + submenu.label += ' (' + i18n.t('mist.applicationMenu.develop.starting') + ')'; + submenu.enabled = false; + } else if (ethereumNode.isExternalNode) { + submenu.label += ' (' + i18n.t('mist.applicationMenu.develop.externalNode') + ')'; + submenu.enabled = false; + } else if (nodes.length > 0) { + submenu.submenu = nodes; + } + devToolsMenu.push(submenu); } // add network switch - devToolsMenu.push({ - label: i18n.t('mist.applicationMenu.develop.network'), - submenu: [ - { + var submenu = { label: i18n.t('mist.applicationMenu.develop.network') }; + if (ethereumNode.state === undefined) { + submenu.label += ' (' + i18n.t('mist.applicationMenu.develop.starting') + ')'; + submenu.enabled = false; + } else if (ethereumNode.isExternalNode) { + submenu.label += ' (' + i18n.t('mist.applicationMenu.develop.externalNode') + ')'; + submenu.enabled = false; + } else { + submenu.submenu = [{ label: i18n.t('mist.applicationMenu.develop.mainNetwork'), accelerator: 'CommandOrControl+Shift+1', checked: ethereumNode.isOwnNode && ethereumNode.isMainNetwork, @@ -379,8 +391,8 @@ var menuTempl = function(webviews) { click: function(){ restartNode(ethereumNode.type, 'main'); } - }, - { + }, + { label: 'Testnet (Morden)', accelerator: 'CommandOrControl+Shift+2', checked: ethereumNode.isOwnNode && ethereumNode.isTestNetwork, @@ -389,8 +401,9 @@ var menuTempl = function(webviews) { click: function(){ restartNode(ethereumNode.type, 'test'); } - } - ]}); + }]; + } + devToolsMenu.push(submenu); // add fork support devToolsMenu.push({ From 9aecb640aa7541d668ffb705706f99cf927d44ab Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Thu, 11 Aug 2016 15:09:47 +0200 Subject: [PATCH 13/16] error handling; version string in menu --- modules/ethereumNode.js | 2 +- modules/getNodePath.js | 22 +++++++++++++++------- modules/menuItems.js | 8 +++++--- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/modules/ethereumNode.js b/modules/ethereumNode.js index fc272ba8d..3876ee8fa 100644 --- a/modules/ethereumNode.js +++ b/modules/ethereumNode.js @@ -330,7 +330,7 @@ class EthereumNode extends EventEmitter { return new Q((resolve, reject) => { getNodePath.probe() .then(() => { - const binPath = getNodePath.query()[nodeType]; + const binPath = Object.keys(getNodePath.query()[nodeType])[0]; log.debug(`Start node using ${binPath}`); this.__startProcess(nodeType, network, binPath) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index db9fabfac..9b8a09bc7 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -18,7 +18,7 @@ const Settings = require('./settings'); // cache const paths = {}, // all versions (system + bundled): { type: { path: version } } - resolvedPaths = {}; // latest version: { type: path } + resolvedPaths = {}; // only latest version per type /** @@ -30,6 +30,7 @@ function getSystemPath(type) { return new Q((resolve, reject) => { var proc = exec('type ' + type); proc.stdout.on('data', resolve); + proc.stderr.on('data', reject); }); } @@ -63,11 +64,14 @@ function getVersion(type, path) { function compareNodes() { return new Q((resolve, reject) => { for (let type in paths) { - var path = Object.keys(paths[type])[0]; - if (Object.keys(paths[type]).length > 1) { - path = (cmpVer(Object.keys(paths[type])[0], Object.keys(paths[type])[1])) ? Object.keys(paths[type])[0] : Object.keys(paths[type])[1] - } - resolvedPaths[type] = path; + var entries = Object.keys(paths[type]); + var preferredPath = entries[0]; + if (Object.keys(paths[type]).length > 1) + var preferredPath = (cmpVer(paths[type][entries[0]], paths[type][entries[1]])) + ? entries[1] : entries[0] + var version = paths[type][preferredPath]; + resolvedPaths[type] = {}; + resolvedPaths[type][preferredPath] = version; } }); } @@ -128,7 +132,11 @@ module.exports = { getPathProms.push(getSystemPath(type) .then((data) => { paths[type][data.match(/(\/\w+)+/)[0]] = null; - })); + }) + .catch((data) => { + log.trace(data); + }) + ); } Q.all(getPathProms).then(() => { diff --git a/modules/menuItems.js b/modules/menuItems.js index c245d27c3..536300de0 100644 --- a/modules/menuItems.js +++ b/modules/menuItems.js @@ -348,11 +348,13 @@ var menuTempl = function(webviews) { type: 'separator' }); // add node switch - if(process.platform === 'darwin' || process.platform === 'win32') { + var resolvedPaths = getNodePath.query(); + if (Object.keys(resolvedPaths).length > 1) { var nodes = []; - for (let type in getNodePath.query()) + for (let type in resolvedPaths) nodes.push({ - label: type.charAt(0).toUpperCase() + type.slice(1), + label: type.charAt(0).toUpperCase() + type.slice(1) + + ' (' + resolvedPaths[type][Object.keys(resolvedPaths[type])[0]] + ')', checked: ethereumNode.isOwnNode && ethereumNode.type === type, enabled: ethereumNode.isOwnNode, type: 'checkbox', From 36a982a49edcf910bcfba958d68264aa147237d6 Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Wed, 24 Aug 2016 20:54:23 +0800 Subject: [PATCH 14/16] format debug log strings --- modules/getNodePath.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/getNodePath.js b/modules/getNodePath.js index 9b8a09bc7..3907ff36d 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -152,7 +152,14 @@ module.exports = { }).then(() => { Q.all(getVersionProms).then(() => { compareNodes(); - log.debug('Available backends: %j', paths); + log.debug('Available backends:'); + Object.keys(paths).forEach((type) => { + let i = 0; + for (let path in paths[type]) { + var name = (0 === i++) ? type + ' -' : type.replace(/./g, ' ') + ' ' + log.debug(name, paths[type][path], '=>', path); + } + }); }) .then(resolve, reject); }) From 518771cba6dc45b673cc123c3c6d4a4859b5c6c3 Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Sun, 28 Aug 2016 12:51:30 +0700 Subject: [PATCH 15/16] start probe() after first connection timeout --- modules/sockets/base.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/sockets/base.js b/modules/sockets/base.js index 8a112ba23..ab6c8b00a 100644 --- a/modules/sockets/base.js +++ b/modules/sockets/base.js @@ -5,6 +5,7 @@ const EventEmitter = require('events').EventEmitter; const _ = global._; const log = require('../utils/logger').create('Sockets'); +const getNodePath = require('../getNodePath.js'); @@ -83,6 +84,9 @@ class Socket extends EventEmitter { if (STATE.CONNECTING === this._state) { this._log.warn(`Connection failed, retrying after ${CONNECT_INTERVAL_MS}ms...`); + if (Object.keys(getNodePath.query()).length == 0) + getNodePath.probe(); + connectTimerId = setTimeout(() => { this._socket.connect(connectConfig); }, CONNECT_INTERVAL_MS); From ad688ec5a0bbe7d3f4faac0db1e82e0fa5508e8b Mon Sep 17 00:00:00 2001 From: Luca Zeug Date: Tue, 30 Aug 2016 03:09:07 +0700 Subject: [PATCH 16/16] promisify probe() after first timeout --- modules/ethereumNode.js | 3 ++- modules/getNodePath.js | 2 +- modules/sockets/base.js | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/ethereumNode.js b/modules/ethereumNode.js index 3876ee8fa..28e48833e 100644 --- a/modules/ethereumNode.js +++ b/modules/ethereumNode.js @@ -14,6 +14,7 @@ const Q = require('bluebird'); const getNodePath = require('./getNodePath.js'); const EventEmitter = require('events').EventEmitter; const Sockets = require('./sockets'); +const SocketsBase = require('./sockets/base.js'); const Settings = require('./settings'); const DEFAULT_NODE_TYPE = 'geth'; @@ -328,7 +329,7 @@ class EthereumNode extends EventEmitter { this._type = nodeType; return new Q((resolve, reject) => { - getNodePath.probe() + Q.all(SocketsBase.getNodePathProm) .then(() => { const binPath = Object.keys(getNodePath.query()[nodeType])[0]; log.debug(`Start node using ${binPath}`); diff --git a/modules/getNodePath.js b/modules/getNodePath.js index 3907ff36d..13cb47abd 100644 --- a/modules/getNodePath.js +++ b/modules/getNodePath.js @@ -143,7 +143,7 @@ module.exports = { for (let type in paths) { for (let path in paths[type]) { getVersionProms.push(getVersion(type, path) - .then((data)=>{ + .then((data) => { var version = data.match(/[\d.]+/)[0]; paths[type][path] = version; })); diff --git a/modules/sockets/base.js b/modules/sockets/base.js index ab6c8b00a..64718ae28 100644 --- a/modules/sockets/base.js +++ b/modules/sockets/base.js @@ -12,6 +12,7 @@ const getNodePath = require('../getNodePath.js'); const CONNECT_INTERVAL_MS = 1000; const CONNECT_TIMEOUT_MS = 3000; +var getNodePathProm = []; /** * Socket connecting to Ethereum Node. @@ -85,7 +86,7 @@ class Socket extends EventEmitter { this._log.warn(`Connection failed, retrying after ${CONNECT_INTERVAL_MS}ms...`); if (Object.keys(getNodePath.query()).length == 0) - getNodePath.probe(); + getNodePathProm.push(getNodePath.probe()); connectTimerId = setTimeout(() => { this._socket.connect(connectConfig); @@ -200,6 +201,7 @@ class Socket extends EventEmitter { exports.Socket = Socket; +exports.getNodePathProm = getNodePathProm; const STATE = exports.STATE = Socket.STATE = {