diff --git a/lib/contracts/blockchain.js b/lib/contracts/blockchain.js index 36da1e96..be76c2e7 100644 --- a/lib/contracts/blockchain.js +++ b/lib/contracts/blockchain.js @@ -1,5 +1,6 @@ const Web3 = require('web3'); const Provider = require('./provider.js'); +const request = require('request'); class Blockchain { constructor(options) { @@ -21,25 +22,26 @@ class Blockchain { this.registerWeb3Object(); } - initWeb3() { + initWeb3(cb) { const self = this; this.web3 = new Web3(); if (this.contractsConfig.deployment.type === "rpc") { - this.web3.setProvider(new this.web3.providers.HttpProvider(web3Endpoint)); - let provider; - let web3Endpoint = 'http://' + this.contractsConfig.deployment.host + ':' + this.contractsConfig.deployment.port; + self.web3Endpoint = 'http://' + this.contractsConfig.deployment.host + ':' + this.contractsConfig.deployment.port; const providerOptions = { web3: this.web3, accountsConfig: this.contractsConfig.deployment.accounts, logger: this.logger, isDev: this.isDev, - web3Endpoint + web3Endpoint: self.web3Endpoint }; provider = new Provider(providerOptions); provider.startWeb3Provider(() => { self.isWeb3Started = true; + if (cb) { + cb(); + } }); } else { throw new Error("contracts config error: unknown deployment type " + this.contractsConfig.deployment.type); @@ -152,7 +154,7 @@ class Blockchain { } // TODO: refactor this - request.get(web3Endpoint, function (err, _response, _body) { + request.get(this.web3Endpoint, function (err, _response, _body) { if (err) { self.logger.error(("Couldn't connect to an Ethereum node are you sure it's on?").red); self.logger.info("make sure you have an Ethereum node or simulator running. e.g 'embark blockchain'".magenta); diff --git a/lib/contracts/deploy_manager.js b/lib/contracts/deploy_manager.js index 5c6e4bff..b43825d8 100644 --- a/lib/contracts/deploy_manager.js +++ b/lib/contracts/deploy_manager.js @@ -47,8 +47,10 @@ class DeployManager { // TODO: could be implemented as an event (beforeDeployAll) function checkIsConnectedToBlockchain(callback) { - self.blockchain.assertNodeConnection((err) => { - callback(err); + self.blockchain.initWeb3(() => { + self.blockchain.assertNodeConnection((err) => { + callback(err); + }); }); }, diff --git a/lib/core/engine.js b/lib/core/engine.js index b752bdc3..0f4956b1 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -13,13 +13,8 @@ const Pipeline = require('../pipeline/pipeline.js'); const Watch = require('../pipeline/watch.js'); const LibraryManager = require('../versions/library_manager.js'); const CodeRunner = require('../coderunner/codeRunner.js'); -const request = require('request'); -const ProcessLauncher = require('../process/processLauncher'); -const utils = require('../utils/utils'); -const constants = require('../constants'); - -const STARTING_BLOCKCHAIN = 'startBlockchain'; +const BlockchainProcess = require('../processes/blockchain.js'); class Engine { constructor(options) { @@ -126,6 +121,7 @@ class Engine { "codeRunner": this.codeRunnerService, "codeGenerator": this.codeGeneratorService, "deployment": this.deploymentService, + "processes": this.processesService, "fileWatcher": this.fileWatchService, "webServer": this.webServerService, "ipfs": this.ipfsService, @@ -170,6 +166,18 @@ class Engine { }); } + processesService(_options) { + let blockchainProcess = new BlockchainProcess({ + events: this.events, + logger: this.logger, + normalizeInput: this.normalizeInput, + blockchainConfig: this.config.blockchainConfig, + locale: this.locale + }); + + blockchainProcess.startBlockchainNode(); + } + codeRunnerService(_options) { this.codeRunner = new CodeRunner({ plugins: this.plugins, @@ -254,13 +262,6 @@ class Engine { contractsManager: this.contractsManager, onlyCompile: options.onlyCompile }); - if (!options.web3) { - // Web3 object might have been modified - self.onReady(() => { - self.deployManager.web3 = self.web3; - }); - } - this.events.on('file-event', function (fileType) { clearTimeout(self.fileTimeout); @@ -314,74 +315,14 @@ class Engine { } onReady(callback) { - if (this.isReady) { - return callback(); - } - this.events.once(constants.blockchain.engineReady, () => { - callback(); - }); - } + //if (this.isReady) { + // return callback(); + //} + //this.events.once(constants.blockchain.engineReady, () => { + // callback(); + //}); - checkWeb3Status(web3Endpoint, callback) { - const self = this; - const NO_NODE = 'noNode'; - const noNodeObj = {name: __("No Blockchain node found"), status: 'off'}; - async.waterfall([ - function checkCurrentProvider(next) { - if (self.web3.currentProvider === undefined) { - return next(NO_NODE); - } - next(); - }, - function pingWeb3Endpoint(next) { - // FIXME: this is needed currently because the provider (MetaMask/provider-engine) doesn't callback when there is no node - request.get(web3Endpoint, function (err, _response, _body) { - if (err) { - return next(NO_NODE); - } - next(); - }); - }, - function checkAccount(next) { - self.web3.eth.getAccounts(function(err, _accounts) { - if (err) { - return next(NO_NODE); - } - next(); - }); - }, - function getWeb3ClientVersion(next) { - // TODO: web3_clientVersion method is currently not implemented in web3.js 1.0 - self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => { - if (err) { - return next({name: __("Ethereum node (version unknown)"), status: 'on'}); - } - if (version.indexOf("/") < 0) { - return next({name: version, status: 'on'}); - } - let nodeName = version.split("/")[0]; - let versionNumber = version.split("/")[1].split("-")[0]; - let name = nodeName + " " + versionNumber + " (Ethereum)"; - - return next({name: name, status: 'on'}); - }); - } - ], (msg) => { - if (msg === NO_NODE) { - if (self.isRunningBlockchain) { - return callback(noNodeObj); - } - // Start blockchain node ourselves - self.stopWeb3Service(); - self.startBlockchainNode(); - return callback(STARTING_BLOCKCHAIN); - } - if (!self.isReady) { - self.isReady = true; - self.events.emit(constants.blockchain.engineReady); - } - callback(msg); - }); + setTimeout(function() { callback(); }, 2000); } web3Service(options) { @@ -404,41 +345,6 @@ class Engine { }); } - stopWeb3Service() { - this.servicesMonitor.stopCheck('Ethereum'); - if (this.provider) { - this.provider.stop(); - } - this.web3 = null; - } - - startBlockchainNode() { - this.logger.info(__('Starting Blockchain node in another process').cyan); - this.isRunningBlockchain = true; - - this.blockchainProcess = new ProcessLauncher({ - modulePath: utils.joinPath(__dirname, '../cmds/blockchain/blockchainProcess.js'), - logger: this.logger, - events: this.events, - normalizeInput: this.normalizeInput, - silent: true - }); - this.blockchainProcess.send({ - action: constants.blockchain.init, options: { - blockchainConfig: this.config.blockchainConfig, - client: this.client, - env: this.env, - isDev: this.isDev, - locale: this.locale - } - }); - - this.blockchainProcess.once('result', constants.blockchain.blockchainReady, () => { - this.logger.info(__('Blockchain node is ready').cyan); - this.startService('web3'); - }); - } - libraryManagerService(_options) { this.libraryManager = new LibraryManager({ plugins: this.plugins, diff --git a/lib/i18n/locales/en.json b/lib/i18n/locales/en.json index 26275642..234b4cea 100644 --- a/lib/i18n/locales/en.json +++ b/lib/i18n/locales/en.json @@ -120,8 +120,7 @@ "adding %s to ipfs": "adding %s to ipfs", "DApp available at": "DApp available at", "successfully uploaded to ipfs": "successfully uploaded to ipfs", - "finished building DApp and deploying to": "finished building DApp and deploying to", - "instantiated js-ipfs object configured to the current environment (available if ipfs is enabled)": "instantiated js-ipfs object configured to the current environment (available if ipfs is enabled)", "Starting Blockchain node in another process": "Starting Blockchain node in another process", - "Blockchain node is ready": "Blockchain node is ready" + "Blockchain node is ready": "Blockchain node is ready", + "terminating due to error": "terminating due to error" } \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index 3b03d9a4..47e75bd3 100644 --- a/lib/index.js +++ b/lib/index.js @@ -129,6 +129,7 @@ class Embark { } engine.startMonitor(); + engine.startService("processes"); engine.startService("libraryManager"); engine.startService("codeRunner"); engine.startService("web3"); diff --git a/lib/processes/blockchain.js b/lib/processes/blockchain.js new file mode 100644 index 00000000..3630a6b1 --- /dev/null +++ b/lib/processes/blockchain.js @@ -0,0 +1,48 @@ +const ProcessLauncher = require('../process/processLauncher'); +const utils = require('../utils/utils.js'); +const constants = require('../constants'); + +class Blockchain { + + constructor (options) { + this.events = options.events; + this.logger = options.logger; + this.normalizeInput = options.normalizeInput; + this.blockchainConfig = options.blockchainConfig; + this.locale = options.locale; + } + + startBlockchainNode() { + this.logger.info('Starting Blockchain node in another process'.cyan); + this.isRunningBlockchain = true; + + this.blockchainProcess = new ProcessLauncher({ + modulePath: utils.joinPath(__dirname, '../cmds/blockchain/blockchainProcess.js'), + logger: this.logger, + events: this.events, + normalizeInput: this.normalizeInput, + //silent: true + silent: false + }); + this.blockchainProcess.send({ + action: constants.blockchain.init, options: { + blockchainConfig: this.blockchainConfig, + //client: this.client, + // TODO: assume for now it's geth + client: 'geth', + env: this.env, + //isDev: this.isDev, + // TODO: assume for now it's true + isDev: true, + locale: this.locale + } + }); + + this.blockchainProcess.once('result', constants.blockchain.blockchainReady, () => { + this.logger.info('Blockchain node is ready'.cyan); + }); + } + +} + +module.exports = Blockchain; diff --git a/test_apps/test_app/package-lock.json b/test_apps/test_app/package-lock.json index 6a0c2c66..3dba6607 100644 --- a/test_apps/test_app/package-lock.json +++ b/test_apps/test_app/package-lock.json @@ -89,7 +89,7 @@ "dom-helpers": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz", - "integrity": "sha1-/BpOFf/fYN3eA6SAqcD+zoId1KY=" + "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg==" }, "dotenv": { "version": "4.0.0", @@ -229,7 +229,7 @@ "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha1-mA9vcthSEaU0fGsrwYxbhMPrR+8=", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { "encoding": "0.1.12", "is-stream": "1.1.0" @@ -252,7 +252,7 @@ "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "requires": { "asap": "2.0.6" } @@ -289,7 +289,7 @@ "react-bootstrap": { "version": "0.32.1", "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-0.32.1.tgz", - "integrity": "sha1-YGJMG0ijnXc+9szmQhpPM+zBZrs=", + "integrity": "sha512-RbfzKUbsukWsToWqGHfCCyMFq9QQI0TznutdyxyJw6dih2NvIne25Mrssg8LZsprqtPpyQi8bN0L0Fx3fUsL8Q==", "requires": { "babel-runtime": "6.26.0", "classnames": "2.2.5", @@ -319,7 +319,7 @@ "react-overlays": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-0.8.3.tgz", - "integrity": "sha1-+tZe6lskMBzKGSoWn13dsLINOsU=", + "integrity": "sha512-h6GT3jgy90PgctleP39Yu3eK1v9vaJAW73GOA/UbN9dJ7aAN4BTZD6793eI1D5U+ukMk17qiqN/wl3diK1Z5LA==", "requires": { "classnames": "2.2.5", "dom-helpers": "3.3.1", @@ -353,7 +353,7 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk=" + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "setimmediate": { "version": "1.0.5", @@ -412,7 +412,7 @@ "zeppelin-solidity": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/zeppelin-solidity/-/zeppelin-solidity-1.8.0.tgz", - "integrity": "sha1-BJ/N59rqn8hSEPjG25+M0auKhTo=", + "integrity": "sha512-7Mxq6Y7EES0PSLrRF6v0EVYqBVRRo8hFrr7m3jEs69VbbQ5kpANzizeEdbP1/PWKSOmBOg208qP2vSA0FlzFLA==", "requires": { "dotenv": "4.0.0", "ethjs-abi": "0.2.1"