move blockchain process to own module

This commit is contained in:
Iuri Matias 2018-07-20 15:21:23 +03:00 committed by Pascal Precht
parent db7f3d39d3
commit 0585c5b3eb
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
1 changed files with 59 additions and 179 deletions

View File

@ -1,43 +1,40 @@
const Web3 = require('web3'); const Web3 = require('web3');
const async = require('async'); const async = require('async');
const Provider = require('./provider.js'); const Provider = require('./provider.js');
const BlockchainProcessLauncher = require('../processes/blockchainProcessLauncher');
const utils = require('../utils/utils'); const utils = require('../utils/utils');
const constants = require('../constants');
const WEB3_READY = 'web3Ready'; const WEB3_READY = 'web3Ready';
class Blockchain { class Blockchain {
constructor(options) { constructor(options) {
const self = this;
this.plugins = options.plugins; this.plugins = options.plugins;
this.logger = options.logger; this.logger = options.logger;
this.events = options.events; this.events = options.events;
this.contractsConfig = options.contractsConfig; this.contractsConfig = options.contractsConfig;
this.blockchainConfig = options.blockchainConfig; this.blockchainConfig = options.blockchainConfig;
this.web3 = options.web3; this.web3 = options.web3;
this.locale = options.locale;
this.isDev = options.isDev; this.isDev = options.isDev;
this.web3Endpoint = ''; this.web3Endpoint = '';
this.isWeb3Ready = false; this.isWeb3Ready = false;
this.web3StartedInProcess = 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) { if (!this.web3) {
this.initWeb3(); this.initWeb3();
} else { } else {
this.isWeb3Ready = true; this.isWeb3Ready = true;
} }
//this.registerServiceCheck(); this.registerServiceCheck();
this.registerRequests(); this.registerRequests();
this.registerWeb3Object(); this.registerWeb3Object();
} this.registerEvents();
registerProcessLaunch() {
const self = this;
this.events.request('processes:register', 'blockchain', (cb) => {
self.startBlockchainNode(cb);
});
} }
initWeb3() { initWeb3() {
@ -65,134 +62,48 @@ class Blockchain {
}; };
this.provider = new Provider(providerOptions); this.provider = new Provider(providerOptions);
self.assertNodeConnection(true, (err) => { self.events.request("processes:launch", "blockchain", () => {
if (!err) { console.dir("======> blockchain launched!");
self.provider.startWeb3Provider(() => { console.dir("starting web3 provider");
self.provider.fundAccounts(() => { self.provider.startWeb3Provider(() => {
self.registerWeb3Object(); 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"); //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");
});
}); });
}); });
}); });
} }
initWeb3_old() { registerEvents() {
const self = this; //const self = this;
this.web3 = new Web3(); //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") { // // once the node goes back online, we can restart the provider
const message = __("contracts config error: unknown deployment type %s", this.contractsConfig.deployment.type); // self.events.once('check:backOnline:Ethereum', () => {
this.logger.error(message); // self.logger.trace('Ethereum back online: starting web3 provider...');
//return cb(message); // self.provider.startWeb3Provider(() => {
} // self.logger.trace('web3 provider restarted after ethereum node came back online');
// });
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);
});
} }
onReady(callback) { onReady(callback) {
console.dir("======> onReady!!");
console.dir("this.isWeb3Ready: " + this.isWeb3Ready.toString());
if (this.isWeb3Ready) { if (this.isWeb3Ready) {
return callback(); return callback();
} }
this.events.once(WEB3_READY, () => { this.events.once(WEB3_READY, () => {
callback(); console.dir("got event triggered");
});
}
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();
callback(); callback();
}); });
} }
@ -204,26 +115,29 @@ class Blockchain {
this.events.request("services:register", 'Ethereum', function (cb) { this.events.request("services:register", 'Ethereum', function (cb) {
async.waterfall([ async.waterfall([
function checkNodeConnection(next) { function checkNodeConnection(next) {
self.assertNodeConnection(true, (err) => { if (!self.web3.currentProvider) {
if (err) { return next(NO_NODE, {name: "No Blockchain node found", status: 'off'});
return next(NO_NODE, {name: "No Blockchain node found", status: 'off'}); }
} next();
next();
});
}, },
function checkVersion(next) { function checkVersion(next) {
// TODO: web3_clientVersion method is currently not implemented in web3.js 1.0 // TODO: web3_clientVersion method is currently not implemented in web3.js 1.0
self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => { self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, version) => {
if (err) { if (err) {
self.isWeb3Ready = false;
return next(null, {name: "Ethereum node (version unknown)", status: 'on'}); return next(null, {name: "Ethereum node (version unknown)", status: 'on'});
} }
if (version.indexOf("/") < 0) { if (version.indexOf("/") < 0) {
self.events.emit(WEB3_READY);
self.isWeb3Ready = true;
return next(null, {name: version, status: 'on'}); return next(null, {name: version, status: 'on'});
} }
let nodeName = version.split("/")[0]; let nodeName = version.split("/")[0];
let versionNumber = version.split("/")[1].split("-")[0]; let versionNumber = version.split("/")[1].split("-")[0];
let name = nodeName + " " + versionNumber + " (Ethereum)"; let name = nodeName + " " + versionNumber + " (Ethereum)";
self.events.emit(WEB3_READY);
self.isWeb3Ready = true;
return next(null, {name: name, status: 'on'}); return next(null, {name: name, status: 'on'});
}); });
} }
@ -231,6 +145,7 @@ class Blockchain {
if (err && err !== NO_NODE) { if (err && err !== NO_NODE) {
return cb(err); return cb(err);
} }
console.dir(statusObj);
cb(statusObj); cb(statusObj);
}); });
}, 5000, 'off'); }, 5000, 'off');
@ -282,7 +197,12 @@ class Blockchain {
} }
getGasPrice(cb) { 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) { ContractObject(params) {
@ -339,56 +259,16 @@ class Blockchain {
return callback(err); return callback(err);
} }
hash = transactionHash; hash = transactionHash;
}) }).on('receipt', function (receipt) {
.on('receipt', function (receipt) { if (receipt.contractAddress !== undefined) {
if (receipt.contractAddress !== undefined) { callback(null, receipt);
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);
} }
], function (err) { }).then(function (_contract) {
if (!noLogs && err === NO_NODE_ERROR) { if (!hash) {
self.logger.error(("Couldn't connect to an Ethereum node are you sure it's on?").red); return; // Somehow we didn't get the receipt yet... Interval will catch it
self.logger.info("make sure you have an Ethereum node or simulator running. e.g 'embark blockchain'".magenta);
} }
cb(err); self.web3.eth.getTransactionReceipt(hash, callback);
}); }).catch(callback);
} }
determineDefaultAccount(cb) { determineDefaultAccount(cb) {