From c5d9a759afd15d5aba329fa655d820d9dadd2cbb Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 20 Jul 2018 15:21:23 +0300 Subject: [PATCH] move blockchain process to own module --- lib/contracts/blockchain.js | 238 +++++++++--------------------------- 1 file changed, 59 insertions(+), 179 deletions(-) diff --git a/lib/contracts/blockchain.js b/lib/contracts/blockchain.js index 04e32a59..57835675 100644 --- a/lib/contracts/blockchain.js +++ b/lib/contracts/blockchain.js @@ -1,43 +1,40 @@ const Web3 = require('web3'); const async = require('async'); const Provider = require('./provider.js'); -const BlockchainProcessLauncher = require('../processes/blockchainProcessLauncher'); const utils = require('../utils/utils'); -const constants = require('../constants'); const WEB3_READY = 'web3Ready'; class Blockchain { constructor(options) { + const self = this; this.plugins = options.plugins; this.logger = options.logger; this.events = options.events; this.contractsConfig = options.contractsConfig; this.blockchainConfig = options.blockchainConfig; this.web3 = options.web3; - this.locale = options.locale; this.isDev = options.isDev; this.web3Endpoint = ''; this.isWeb3Ready = false; this.web3StartedInProcess = false; - this.registerProcessLaunch(); + self.events.setCommandHandler("blockchain:web3:isReady", (cb) => { + console.dir("geting state of web3"); + console.dir(self.isWeb3Ready.toString()); + cb(self.isWeb3Ready); + }); if (!this.web3) { this.initWeb3(); } else { this.isWeb3Ready = true; } - //this.registerServiceCheck(); + this.registerServiceCheck(); this.registerRequests(); this.registerWeb3Object(); - } + this.registerEvents(); - registerProcessLaunch() { - const self = this; - this.events.request('processes:register', 'blockchain', (cb) => { - self.startBlockchainNode(cb); - }); } initWeb3() { @@ -65,134 +62,48 @@ class Blockchain { }; this.provider = new Provider(providerOptions); - self.assertNodeConnection(true, (err) => { - if (!err) { - self.provider.startWeb3Provider(() => { - self.provider.fundAccounts(() => { - self.registerWeb3Object(); + self.events.request("processes:launch", "blockchain", () => { + console.dir("======> blockchain launched!"); + console.dir("starting web3 provider"); + self.provider.startWeb3Provider(() => { + console.dir("funding accounts"); + self.provider.fundAccounts(() => { + console.dir("registering web3 object"); + self.isWeb3Ready = true; + self.events.emit(WEB3_READY); + self.registerWeb3Object(); - self.events.emit("check:backOnline:Ethereum"); - }); - }); - return; - } - - self.events.request("processes:launch", "blockchain", () => { - console.dir("======> blockchain launched!"); - self.provider.startWeb3Provider(() => { - self.provider.fundAccounts(() => { - self.registerWeb3Object(); - - self.events.emit("check:backOnline:Ethereum"); - }); + //self.events.emit("check:backOnline:Ethereum"); }); }); }); } - initWeb3_old() { - const self = this; - this.web3 = new Web3(); + registerEvents() { + //const self = this; + //self.events.on('check:wentOffline:Ethereum', () => { + // self.logger.trace('Ethereum went offline: stopping web3 provider...'); + // self.provider.stop(); - if (this.contractsConfig.deployment.type !== "rpc" && this.contractsConfig.deployment.type !== "ws") { - const message = __("contracts config error: unknown deployment type %s", this.contractsConfig.deployment.type); - this.logger.error(message); - //return cb(message); - } - - const protocol = (this.contractsConfig.deployment.type === "rpc") ? this.contractsConfig.deployment.protocol : 'ws'; - - this.web3Endpoint = utils.buildUrl(protocol, this.contractsConfig.deployment.host, this.contractsConfig.deployment.port);//`${protocol}://${this.contractsConfig.deployment.host}:${this.contractsConfig.deployment.port}`; - - const providerOptions = { - web3: this.web3, - accountsConfig: this.contractsConfig.deployment.accounts, - blockchainConfig: this.blockchainConfig, - logger: this.logger, - isDev: this.isDev, - type: this.contractsConfig.deployment.type, - web3Endpoint: self.web3Endpoint - }; - this.provider = new Provider(providerOptions); - - async.waterfall([ - function checkNode(next) { - self.assertNodeConnection(true, (err) => { - if (err && self.web3StartedInProcess) { - // Already started blockchain in another node, we really have a node problem - self.logger.error(__('Unable to start the blockchain process. Is Geth installed?').red); - return next(err); - } - if (!err) { - self.isWeb3Ready = true; - self.events.emit(WEB3_READY); - // if the ethereum node goes offline, we need a check to ensure - // the provider is also stopped - self.events.on('check:wentOffline:Ethereum', () => { - self.logger.trace('Ethereum went offline: stopping web3 provider...'); - self.provider.stop(); - - // once the node goes back online, we can restart the provider - self.events.once('check:backOnline:Ethereum', () => { - self.logger.trace('Ethereum back online: starting web3 provider...'); - self.provider.startWeb3Provider(() => { - self.logger.trace('web3 provider restarted after ethereum node came back online'); - }); - }); - }); - return next(); - } - self.web3StartedInProcess = true; - //self.startBlockchainNode(() => { - self.events.request("processes:launch", "blockchain", () => { - // Need to re-initialize web3 to connect to the new blockchain node - self.provider.stop(); - //self.initWeb3(cb); - }); - }); - }, - function startProvider(next) { - self.provider.startWeb3Provider(next); - }, - function fundAccountsIfNeeded(next) { - self.provider.fundAccounts(next); - } - ], (err) => { - self.registerWeb3Object(); - cb(err); - }); + // // once the node goes back online, we can restart the provider + // self.events.once('check:backOnline:Ethereum', () => { + // self.logger.trace('Ethereum back online: starting web3 provider...'); + // self.provider.startWeb3Provider(() => { + // self.logger.trace('web3 provider restarted after ethereum node came back online'); + // }); + // }); + //}); } onReady(callback) { + console.dir("======> onReady!!"); + console.dir("this.isWeb3Ready: " + this.isWeb3Ready.toString()); if (this.isWeb3Ready) { return callback(); } this.events.once(WEB3_READY, () => { - callback(); - }); - } - - startBlockchainNode(callback) { - console.dir("==> startBlockchainNode"); - const self = this; - let blockchainProcess = new BlockchainProcessLauncher({ - events: self.events, - logger: self.logger, - normalizeInput: utils.normalizeInput, - blockchainConfig: self.blockchainConfig, - locale: self.locale, - isDev: self.isDev - }); - - blockchainProcess.startBlockchainNode(); - self.events.once(constants.blockchain.blockchainReady, () => { - console.dir("==> blockchainReady"); - callback(); - }); - self.events.once(constants.blockchain.blockchainExit, () => { - console.dir("==> blockchainExit"); - self.provider.stop(); + console.dir("got event triggered"); callback(); }); } @@ -204,26 +115,29 @@ class Blockchain { this.events.request("services:register", 'Ethereum', function (cb) { async.waterfall([ function checkNodeConnection(next) { - self.assertNodeConnection(true, (err) => { - if (err) { - return next(NO_NODE, {name: "No Blockchain node found", status: 'off'}); - } - next(); - }); + if (!self.web3.currentProvider) { + return next(NO_NODE, {name: "No Blockchain node found", status: 'off'}); + } + next(); }, function checkVersion(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) { + self.isWeb3Ready = false; return next(null, {name: "Ethereum node (version unknown)", status: 'on'}); } if (version.indexOf("/") < 0) { + self.events.emit(WEB3_READY); + self.isWeb3Ready = true; return next(null, {name: version, status: 'on'}); } let nodeName = version.split("/")[0]; let versionNumber = version.split("/")[1].split("-")[0]; let name = nodeName + " " + versionNumber + " (Ethereum)"; + self.events.emit(WEB3_READY); + self.isWeb3Ready = true; return next(null, {name: name, status: 'on'}); }); } @@ -231,6 +145,7 @@ class Blockchain { if (err && err !== NO_NODE) { return cb(err); } + console.dir(statusObj); cb(statusObj); }); }, 5000, 'off'); @@ -282,7 +197,12 @@ class Blockchain { } getGasPrice(cb) { - this.web3.eth.getGasPrice(cb); + console.dir("geting gas price"); + const self = this; + this.onReady(() => { + console.dir("it's ready, getting gas price"); + self.web3.eth.getGasPrice(cb); + }); } ContractObject(params) { @@ -339,56 +259,16 @@ class Blockchain { return callback(err); } hash = transactionHash; - }) - .on('receipt', function (receipt) { - if (receipt.contractAddress !== undefined) { - callback(null, receipt); - } - }) - .then(function (_contract) { - if (!hash) { - return; // Somehow we didn't get the receipt yet... Interval will catch it - } - self.web3.eth.getTransactionReceipt(hash, callback); - }) - .catch(callback); - } - - assertNodeConnection(noLogs, cb) { - if (typeof noLogs === 'function') { - cb = noLogs; - noLogs = false; - } - const NO_NODE_ERROR = Error("error connecting to blockchain node"); - const self = this; - - async.waterfall([ - function checkInstance(next) { - if (!self.web3) { - return next(Error("no web3 instance found")); - } - next(); - }, - function checkProvider(next) { - if (self.web3.currentProvider === undefined) { - return next(NO_NODE_ERROR); - } - next(); - }, - function pingEndpoint(next) { - if (!self.contractsConfig || !self.contractsConfig.deployment || !self.contractsConfig.deployment.host) { - return next(); - } - const {host, port, type, protocol} = self.contractsConfig.deployment; - utils.pingEndpoint(host, port, type, protocol, self.blockchainConfig.wsOrigins.split(',')[0], next); + }).on('receipt', function (receipt) { + if (receipt.contractAddress !== undefined) { + callback(null, receipt); } - ], function (err) { - if (!noLogs && err === NO_NODE_ERROR) { - 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); + }).then(function (_contract) { + if (!hash) { + return; // Somehow we didn't get the receipt yet... Interval will catch it } - cb(err); - }); + self.web3.eth.getTransactionReceipt(hash, callback); + }).catch(callback); } determineDefaultAccount(cb) {