embark/lib/core/engine.js

249 lines
8.2 KiB
JavaScript
Raw Normal View History

2017-03-29 17:50:05 +00:00
let Web3 = require('web3');
let Events = require('./events.js');
let Logger = require('./logger.js');
let Config = require('./config.js');
let ContractsManager = require('../contracts/contracts.js');
2017-03-29 17:50:05 +00:00
let DeployManager = require('../contracts/deploy_manager.js');
let CodeGenerator = require('../contracts/code_generator.js');
2017-03-29 17:50:05 +00:00
let ServicesMonitor = require('./services_monitor.js');
let Pipeline = require('../pipeline/pipeline.js');
let Watch = require('../pipeline/watch.js');
let LibraryManager = require('../versions/library_manager.js');
2017-03-30 11:12:39 +00:00
class Engine {
constructor(options) {
this.env = options.env;
this.embarkConfig = options.embarkConfig;
this.interceptLogs = options.interceptLogs;
2017-03-31 11:34:43 +00:00
this.version = options.version;
this.logfile = options.logfile;
2017-03-30 11:12:39 +00:00
}
2017-03-30 11:38:14 +00:00
init(_options) {
let self = this;
let options = _options || {};
this.events = new Events();
2018-03-15 20:44:05 +00:00
this.logger = options.logger || new Logger({logLevel: options.logLevel || 'debug', events: this.events, logfile: this.logfile});
2017-03-30 11:38:14 +00:00
this.config = new Config({env: this.env, logger: this.logger, events: this.events});
this.config.loadConfigFiles({embarkConfig: this.embarkConfig, interceptLogs: this.interceptLogs});
this.plugins = this.config.plugins;
this.servicesMonitor = new ServicesMonitor({events: this.events, logger: this.logger});
this.servicesMonitor.addCheck('embarkVersion', function (cb) {
return cb({name: 'Embark ' + self.version, status: 'on'});
2017-03-30 11:38:14 +00:00
}, 0);
}
startMonitor() {
let self = this;
if (this.plugins) {
2017-12-18 14:37:16 +00:00
// --------
// TODO: this only works for services done on startup
// --------
2017-03-30 11:38:14 +00:00
let servicePlugins = this.plugins.getPluginsFor('serviceChecks');
servicePlugins.forEach(function (plugin) {
plugin.serviceChecks.forEach(function (pluginCheck) {
self.servicesMonitor.addCheck(pluginCheck.checkName, pluginCheck.checkFn, pluginCheck.time);
});
});
2017-03-30 11:38:14 +00:00
}
this.servicesMonitor.startMonitor();
}
2017-12-16 20:39:30 +00:00
registerModule(moduleName, options) {
this.plugins.loadInternalPlugin(moduleName, options);
}
2017-03-30 11:38:14 +00:00
startService(serviceName, _options) {
let options = _options || {};
let services = {
"pipeline": this.pipelineService,
"codeGenerator": this.codeGeneratorService,
2017-03-30 11:38:14 +00:00
"deployment": this.deploymentService,
"fileWatcher": this.fileWatchService,
"webServer": this.webServerService,
"ipfs": this.ipfsService,
"web3": this.web3Service,
"libraryManager": this.libraryManagerService
2017-03-30 11:38:14 +00:00
};
let service = services[serviceName];
if (!service) {
throw new Error("unknown service: " + serviceName);
}
// need to be careful with circular references due to passing the web3 object
//this.logger.trace("calling: " + serviceName + "(" + JSON.stringify(options) + ")");
return service.apply(this, [options]);
}
2017-10-14 14:13:30 +00:00
pipelineService(_options) {
2017-03-30 11:38:14 +00:00
let self = this;
this.events.emit("status", "Building Assets");
2017-03-30 11:38:14 +00:00
let pipeline = new Pipeline({
buildDir: this.config.buildDir,
contractsFiles: this.config.contractsFiles,
assetFiles: this.config.assetFiles,
2017-12-12 17:20:57 +00:00
events: this.events,
2017-03-30 11:38:14 +00:00
logger: this.logger,
plugins: this.plugins
});
this.events.on('code-generator-ready', function () {
2017-10-17 11:03:13 +00:00
self.events.request('code', function (abi, contractsJSON) {
self.currentAbi = abi;
self.contractsJSON = contractsJSON;
pipeline.build(abi, contractsJSON, null, function() {
self.events.emit('outputDone');
});
});
2017-03-30 11:38:14 +00:00
});
// TODO: still need to redeploy contracts because the original contracts
// config is being corrupted
this.events.on('file-event', function(fileType, _path) {
if (fileType === 'asset') {
self.events.emit('asset-changed', self.contractsManager);
}
});
}
2017-03-30 11:38:14 +00:00
2017-10-14 14:13:30 +00:00
codeGeneratorService(_options) {
2017-03-30 11:38:14 +00:00
let self = this;
let generateCode = function (contractsManager) {
let codeGenerator = new CodeGenerator({
2017-03-30 11:38:14 +00:00
blockchainConfig: self.config.blockchainConfig,
contractsConfig: self.config.contractsConfig,
2017-03-30 11:38:14 +00:00
contractsManager: contractsManager,
plugins: self.plugins,
storageConfig: self.config.storageConfig,
communicationConfig: self.config.communicationConfig,
events: self.events
2017-03-30 11:38:14 +00:00
});
codeGenerator.listenToCommands();
2018-01-10 15:43:25 +00:00
codeGenerator.buildEmbarkJS(function() {
self.events.emit('code-generator-ready');
});
2017-03-30 11:38:14 +00:00
};
this.events.on('contractsDeployed', generateCode);
this.events.on('blockchainDisabled', generateCode);
this.events.on('asset-changed', generateCode);
}
2017-03-04 02:48:32 +00:00
2017-03-30 11:38:14 +00:00
deploymentService(options) {
let self = this;
2017-12-16 20:39:30 +00:00
this.registerModule('solidity', {
contractDirectories: self.config.contractDirectories
});
2018-04-12 17:24:54 +00:00
this.registerModule('vyper', {
contractDirectories: self.config.contractDirectories
});
2017-12-16 20:39:30 +00:00
this.contractsManager = new ContractsManager({
contractFiles: this.config.contractsFiles,
contractsConfig: this.config.contractsConfig,
logger: this.logger,
plugins: this.plugins,
gasLimit: false
});
2017-03-30 11:38:14 +00:00
this.deployManager = new DeployManager({
web3: options.web3 || self.web3,
trackContracts: options.trackContracts,
config: this.config,
logger: this.logger,
plugins: this.plugins,
events: this.events,
contractsManager: this.contractsManager,
onlyCompile: options.onlyCompile
2017-03-04 02:48:32 +00:00
});
2017-03-30 11:38:14 +00:00
this.events.on('file-event', function (fileType, _path) {
2017-03-30 11:38:14 +00:00
// TODO: for now need to deploy on asset chanes as well
// because the contractsManager config is corrupted after a deploy
if (fileType === 'contract' || fileType === 'config') {
self.config.reloadConfig();
self.deployManager.deployContracts(function () {
});
}
2017-03-30 11:12:39 +00:00
});
}
2017-10-14 14:13:30 +00:00
fileWatchService(_options) {
this.events.emit("status", "Watching for changes");
2017-03-30 11:38:14 +00:00
let watch = new Watch({logger: this.logger, events: this.events});
watch.start();
}
2017-12-19 14:50:29 +00:00
webServerService() {
2017-12-18 14:37:16 +00:00
this.registerModule('webserver', {
addCheck: this.servicesMonitor.addCheck.bind(this.servicesMonitor)
2017-03-30 11:38:14 +00:00
});
}
2017-10-14 14:13:30 +00:00
ipfsService(_options) {
2017-12-27 01:32:51 +00:00
this.registerModule('ipfs', {
addCheck: this.servicesMonitor.addCheck.bind(this.servicesMonitor),
storageConfig: this.config.storageConfig,
host: _options.host,
port: _options.port
});
}
2017-03-30 11:38:14 +00:00
web3Service(options) {
let self = this;
this.web3 = options.web3;
if (this.web3 === undefined) {
this.web3 = new Web3();
if (this.config.contractsConfig.deployment.type === "rpc") {
let web3Endpoint = 'http://' + this.config.contractsConfig.deployment.host + ':' + this.config.contractsConfig.deployment.port;
this.web3.setProvider(new this.web3.providers.HttpProvider(web3Endpoint));
} else {
throw new Error("contracts config error: unknown deployment type " + this.config.contractsConfig.deployment.type);
}
}
2017-03-30 11:38:14 +00:00
self.servicesMonitor.addCheck('Ethereum', function (cb) {
2018-01-05 20:30:52 +00:00
if (self.web3.currentProvider === undefined) {
return cb({name: "No Blockchain node found", status: 'off'});
}
self.web3.eth.getAccounts(function(err, _accounts) {
if (err) {
return cb({name: "No Blockchain node found", status: 'off'});
}
2018-04-10 19:08:08 +00:00
// 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 cb({name: "Ethereum node (version unknown)", status: 'on'});
}
let nodeName = version.split("/")[0];
let versionNumber = version.split("/")[1].split("-")[0];
let name = nodeName + " " + versionNumber + " (Ethereum)";
return cb({name: name, status: 'on'});
2017-03-30 11:38:14 +00:00
});
2018-01-05 20:30:52 +00:00
});
});
2018-01-05 20:30:52 +00:00
this.registerModule('whisper', {
addCheck: this.servicesMonitor.addCheck.bind(this.servicesMonitor),
communicationConfig: this.config.communicationConfig,
web3: this.web3
});
2017-03-30 11:38:14 +00:00
}
2017-12-30 22:07:13 +00:00
libraryManagerService(_options) {
this.libraryManager = new LibraryManager({
plugins: this.plugins,
config: this.config
});
}
2017-03-30 11:38:14 +00:00
}
module.exports = Engine;