mirror of https://github.com/embarklabs/embark.git
move blockchain process to own module
This commit is contained in:
parent
80c617cc60
commit
68a187136d
|
@ -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) {
|
||||
|
|
|
@ -271,6 +271,11 @@ class Engine {
|
|||
}
|
||||
|
||||
web3Service(options) {
|
||||
this.registerModule('blockchain_process', {
|
||||
locale: this.locale,
|
||||
isDev: this.isDev
|
||||
});
|
||||
|
||||
const Blockchain = require('../contracts/blockchain.js');
|
||||
this.blockchain = new Blockchain({
|
||||
contractsConfig: this.config.contractsConfig,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const ProcessLauncher = require('../process/processLauncher');
|
||||
const utils = require('../utils/utils.js');
|
||||
const constants = require('../constants');
|
||||
const ProcessLauncher = require('../../process/processLauncher');
|
||||
const utils = require('../../utils/utils.js');
|
||||
const constants = require('../../constants');
|
||||
|
||||
class BlockchainProcessLauncher {
|
||||
|
||||
|
@ -21,7 +21,7 @@ class BlockchainProcessLauncher {
|
|||
this.logger.info(__('Starting Blockchain node in another process').cyan);
|
||||
|
||||
this.blockchainProcess = new ProcessLauncher({
|
||||
modulePath: utils.joinPath(__dirname, '../cmds/blockchain/blockchainProcess.js'),
|
||||
modulePath: utils.joinPath(__dirname, '../../cmds/blockchain/blockchainProcess.js'),
|
||||
logger: this.logger,
|
||||
events: this.events,
|
||||
silent: this.logger.logLevel !== 'trace',
|
|
@ -0,0 +1,126 @@
|
|||
const async = require('async');
|
||||
const utils = require('../../utils/utils.js');
|
||||
const constants = require('../../constants');
|
||||
const BlockchainProcessLauncher = require('./blockchainProcessLauncher');
|
||||
|
||||
class BlockchainModule {
|
||||
|
||||
constructor(embark, options) {
|
||||
const self = this;
|
||||
this.logger = embark.logger;
|
||||
this.events = embark.events;
|
||||
this.blockchainConfig = embark.config.blockchainConfig;
|
||||
this.contractsConfig = embark.config.contractsConfig;
|
||||
this.embark = embark;
|
||||
this.locale = options.locale;
|
||||
this.isDev = options.isDev;
|
||||
|
||||
this.registerBlockchainProcess();
|
||||
}
|
||||
|
||||
registerBlockchainProcess() {
|
||||
const self = this;
|
||||
this.events.request('processes:register', 'blockchain', (cb) => {
|
||||
console.dir("gonna check node connection");
|
||||
self.assertNodeConnection(true, (connected) => {
|
||||
if (connected === undefined) {
|
||||
console.dir("result is undefined");
|
||||
} else {
|
||||
console.dir("result is " + connected.toString());
|
||||
}
|
||||
//if (!err) return cb();
|
||||
if (connected) return cb();
|
||||
console.dir("blockchain not started, so gonna start one");
|
||||
self.startBlockchainNode(cb);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
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([
|
||||
// check if web3 is set
|
||||
//
|
||||
function checkWeb3State(next) {
|
||||
console.dir("checkWeb3State");
|
||||
self.events.request("blockchain:web3:isReady", (connected) => {
|
||||
console.dir("---> checking web3 state");
|
||||
console.dir(connected.toString());
|
||||
if (connected) {
|
||||
return next(connected);
|
||||
}
|
||||
next();
|
||||
})
|
||||
},
|
||||
//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) {
|
||||
console.dir("pingEndpoint");
|
||||
if (!self.contractsConfig || !self.contractsConfig.deployment || !self.contractsConfig.deployment.host) {
|
||||
return next();
|
||||
}
|
||||
const {host, port, type, protocol} = self.contractsConfig.deployment;
|
||||
console.dir("||||| pinging: ");
|
||||
console.dir(self.contractsConfig.deployment);
|
||||
utils.pingEndpoint(host, port, type, protocol, self.blockchainConfig.wsOrigins.split(',')[0], next);
|
||||
}
|
||||
], function (err, result) {
|
||||
console.dir("------");
|
||||
console.dir(result);
|
||||
console.dir("------");
|
||||
if (err === true || result === undefined) {
|
||||
return cb(true);
|
||||
}
|
||||
return cb(false);
|
||||
|
||||
//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);
|
||||
//}
|
||||
//cb(err);
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = BlockchainModule;
|
|
@ -16,7 +16,7 @@
|
|||
"wsRPC": true,
|
||||
"wsHost": "localhost",
|
||||
"wsPort": 8546,
|
||||
"proxy": true
|
||||
"proxy": false
|
||||
},
|
||||
"privatenet": {
|
||||
"enabled": true,
|
||||
|
|
Loading…
Reference in New Issue