2018-05-18 21:15:49 +00:00
|
|
|
const async = require('async');
|
|
|
|
|
2018-05-23 13:33:32 +00:00
|
|
|
const utils = require('../utils/utils');
|
2018-06-04 19:36:43 +00:00
|
|
|
const IPC = require('./ipc');
|
2018-05-22 19:46:02 +00:00
|
|
|
|
2017-03-30 11:12:39 +00:00
|
|
|
class Engine {
|
|
|
|
constructor(options) {
|
|
|
|
this.env = options.env;
|
2018-05-18 19:48:28 +00:00
|
|
|
this.client = options.client;
|
|
|
|
this.locale = options.locale;
|
2017-03-30 11:12:39 +00:00
|
|
|
this.embarkConfig = options.embarkConfig;
|
|
|
|
this.interceptLogs = options.interceptLogs;
|
2017-03-31 11:34:43 +00:00
|
|
|
this.version = options.version;
|
2018-04-19 04:25:43 +00:00
|
|
|
this.logFile = options.logFile;
|
2018-04-17 06:17:59 +00:00
|
|
|
this.logLevel = options.logLevel;
|
2018-04-19 04:25:43 +00:00
|
|
|
this.events = options.events;
|
2018-04-25 14:34:17 +00:00
|
|
|
this.context = options.context;
|
2018-06-14 23:37:52 +00:00
|
|
|
this.useDashboard = options.useDashboard;
|
2018-07-16 04:49:24 +00:00
|
|
|
this.webServerConfig = options.webServerConfig;
|
2018-08-16 20:51:34 +00:00
|
|
|
this.webpackConfigName = options.webpackConfigName;
|
2018-09-12 09:16:27 +00:00
|
|
|
this.ipcRole = options.ipcRole || 'client';
|
2017-03-30 11:12:39 +00:00
|
|
|
}
|
2017-03-03 06:22:12 +00:00
|
|
|
|
2018-09-05 09:39:09 +00:00
|
|
|
init(_options, callback) {
|
|
|
|
callback = callback || function() {};
|
2018-06-02 13:54:32 +00:00
|
|
|
const Events = require('./events.js');
|
|
|
|
const Logger = require('./logger.js');
|
|
|
|
const Config = require('./config.js');
|
|
|
|
|
2017-03-30 11:38:14 +00:00
|
|
|
let options = _options || {};
|
2018-04-19 04:25:43 +00:00
|
|
|
this.events = options.events || this.events || new Events();
|
2018-10-04 12:22:41 +00:00
|
|
|
this.logger = options.logger || new Logger({context: this.context, logLevel: options.logLevel || this.logLevel || 'debug', events: this.events, logFile: this.logFile});
|
2018-07-16 04:49:24 +00:00
|
|
|
this.config = new Config({env: this.env, logger: this.logger, events: this.events, context: this.context, webServerConfig: this.webServerConfig});
|
2017-03-30 11:38:14 +00:00
|
|
|
this.config.loadConfigFiles({embarkConfig: this.embarkConfig, interceptLogs: this.interceptLogs});
|
|
|
|
this.plugins = this.config.plugins;
|
2018-07-10 12:49:08 +00:00
|
|
|
this.isDev = this.config && this.config.blockchainConfig && (this.config.blockchainConfig.isDev || this.config.blockchainConfig.default);
|
2017-03-30 11:38:14 +00:00
|
|
|
|
2018-04-30 05:56:43 +00:00
|
|
|
if (this.interceptLogs || this.interceptLogs === undefined) {
|
2018-08-22 22:04:52 +00:00
|
|
|
utils.interceptLogs(console, this.logger);
|
2018-04-30 05:56:43 +00:00
|
|
|
}
|
2018-08-08 12:42:45 +00:00
|
|
|
|
2018-09-12 09:16:27 +00:00
|
|
|
this.ipc = new IPC({logger: this.logger, ipcRole: this.ipcRole});
|
|
|
|
if (this.ipc.isClient()) {
|
|
|
|
return this.ipc.connect((_err) => {
|
|
|
|
callback();
|
|
|
|
});
|
|
|
|
} else if (this.ipc.isServer()) {
|
|
|
|
this.ipc.serve();
|
|
|
|
return callback();
|
|
|
|
}
|
2018-07-19 20:31:28 +00:00
|
|
|
callback();
|
2018-04-30 05:56:43 +00:00
|
|
|
}
|
|
|
|
|
2017-12-16 20:39:30 +00:00
|
|
|
registerModule(moduleName, options) {
|
2018-05-30 16:26:49 +00:00
|
|
|
this.plugins.loadInternalPlugin(moduleName, options || {});
|
2017-12-16 20:39:30 +00:00
|
|
|
}
|
|
|
|
|
2017-03-30 11:38:14 +00:00
|
|
|
startService(serviceName, _options) {
|
|
|
|
let options = _options || {};
|
|
|
|
|
|
|
|
let services = {
|
2018-06-01 16:27:12 +00:00
|
|
|
"serviceMonitor": this.serviceMonitor,
|
2017-03-30 11:38:14 +00:00
|
|
|
"pipeline": this.pipelineService,
|
2018-05-23 15:16:56 +00:00
|
|
|
"codeRunner": this.codeRunnerService,
|
2017-08-03 23:29:09 +00:00
|
|
|
"codeGenerator": this.codeGeneratorService,
|
2018-10-09 13:12:33 +00:00
|
|
|
"compiler": this.setupCompilerAndContractsManagerService,
|
2017-03-30 11:38:14 +00:00
|
|
|
"deployment": this.deploymentService,
|
|
|
|
"fileWatcher": this.fileWatchService,
|
|
|
|
"webServer": this.webServerService,
|
2018-08-31 08:24:45 +00:00
|
|
|
"console": this.console,
|
2017-12-30 20:52:51 +00:00
|
|
|
"web3": this.web3Service,
|
2018-04-24 00:27:11 +00:00
|
|
|
"libraryManager": this.libraryManagerService,
|
2018-07-19 20:31:28 +00:00
|
|
|
"processManager": this.processManagerService,
|
2018-07-20 17:03:55 +00:00
|
|
|
"storage": this.storageService,
|
2018-10-23 09:26:15 +00:00
|
|
|
"pluginCommand": this.pluginCommandService,
|
2018-08-01 16:08:47 +00:00
|
|
|
"graph": this.graphService,
|
2018-10-05 23:13:00 +00:00
|
|
|
"testRunner": this.testRunnerService,
|
2018-09-09 17:37:55 +00:00
|
|
|
"codeCoverage": this.codeCoverageService,
|
2018-10-04 05:01:02 +00:00
|
|
|
"scaffolding": this.scaffoldingService,
|
2018-10-09 23:15:39 +00:00
|
|
|
"coreProcess": this.coreProcessService,
|
Process logs API refactor
There are three separate instances of process log APIs: embark logs, blockchain logs (when in standalone mode), and child process logs (storage, communication, blockchain, etc). Each one was repeating the implementation of creating a process log API endpoint. This commit centralises the API declaration by using the class `ProcessLogsApi`.
`ProcessLogsApi` is started for all three components mentioned above: blockchain (in standalone) in the `BlockchainListener` module, embark in the `EmbarkListener` module, and for all child processes in the `ProcessLauncher`.
These listeners have two functions:
1. Create the process logs API endpoints for `get` and `ws`, and
2. Ensure that all logs are logged through the `LogHandler`, which normalises the output of the log and ensures each log has a timestamp and id (used in the cockpit for log ordering).
Also, this commit moved the pipeline in to a module, so that the `embark` object could be passed to the `ProcessLogsApi` (to be used for registering API endpoints).
2018-10-24 05:54:09 +00:00
|
|
|
"processApi": this.processApiService,
|
|
|
|
"blockchainListener": this.blockchainListenerService,
|
|
|
|
"embarkListener": this.embarkListenerService
|
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]);
|
|
|
|
}
|
|
|
|
|
Process logs API refactor
There are three separate instances of process log APIs: embark logs, blockchain logs (when in standalone mode), and child process logs (storage, communication, blockchain, etc). Each one was repeating the implementation of creating a process log API endpoint. This commit centralises the API declaration by using the class `ProcessLogsApi`.
`ProcessLogsApi` is started for all three components mentioned above: blockchain (in standalone) in the `BlockchainListener` module, embark in the `EmbarkListener` module, and for all child processes in the `ProcessLauncher`.
These listeners have two functions:
1. Create the process logs API endpoints for `get` and `ws`, and
2. Ensure that all logs are logged through the `LogHandler`, which normalises the output of the log and ensures each log has a timestamp and id (used in the cockpit for log ordering).
Also, this commit moved the pipeline in to a module, so that the `embark` object could be passed to the `ProcessLogsApi` (to be used for registering API endpoints).
2018-10-24 05:54:09 +00:00
|
|
|
embarkListenerService(_options){
|
|
|
|
this.registerModule('embark_listener');
|
|
|
|
}
|
|
|
|
|
2018-10-22 12:56:14 +00:00
|
|
|
blockchainListenerService(_options){
|
|
|
|
this.registerModule('blockchain_listener', {
|
|
|
|
ipc: this.ipc
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-10-09 23:15:39 +00:00
|
|
|
coreProcessService(_options){
|
|
|
|
this.registerModule('core_process', {
|
|
|
|
events: this.events
|
|
|
|
});
|
|
|
|
}
|
2018-10-17 22:36:46 +00:00
|
|
|
|
Process logs API refactor
There are three separate instances of process log APIs: embark logs, blockchain logs (when in standalone mode), and child process logs (storage, communication, blockchain, etc). Each one was repeating the implementation of creating a process log API endpoint. This commit centralises the API declaration by using the class `ProcessLogsApi`.
`ProcessLogsApi` is started for all three components mentioned above: blockchain (in standalone) in the `BlockchainListener` module, embark in the `EmbarkListener` module, and for all child processes in the `ProcessLauncher`.
These listeners have two functions:
1. Create the process logs API endpoints for `get` and `ws`, and
2. Ensure that all logs are logged through the `LogHandler`, which normalises the output of the log and ensures each log has a timestamp and id (used in the cockpit for log ordering).
Also, this commit moved the pipeline in to a module, so that the `embark` object could be passed to the `ProcessLogsApi` (to be used for registering API endpoints).
2018-10-24 05:54:09 +00:00
|
|
|
processApiService(_options){
|
|
|
|
this.registerModule('process_api', {
|
2018-10-04 05:01:02 +00:00
|
|
|
logger: this.logger
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-07-19 20:31:28 +00:00
|
|
|
processManagerService(_options) {
|
2018-08-22 22:16:03 +00:00
|
|
|
const ProcessManager = require('./processes/processManager.js');
|
2018-08-22 22:04:52 +00:00
|
|
|
this.processManager = new ProcessManager({
|
2018-07-19 20:31:28 +00:00
|
|
|
events: this.events,
|
|
|
|
logger: this.logger,
|
|
|
|
plugins: this.plugins
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-08-22 22:16:03 +00:00
|
|
|
graphService(_options) {
|
|
|
|
this.registerModule('graph');
|
|
|
|
}
|
|
|
|
|
2018-10-05 23:13:00 +00:00
|
|
|
scaffoldingService(_options) {
|
|
|
|
this.registerModule('scaffolding', {plugins: this.plugins});
|
|
|
|
}
|
|
|
|
|
2017-10-14 14:13:30 +00:00
|
|
|
pipelineService(_options) {
|
2018-10-25 05:21:08 +00:00
|
|
|
const self = this;
|
|
|
|
this.registerModule('pipeline', {
|
|
|
|
webpackConfigName: this.webpackConfigName
|
|
|
|
});
|
|
|
|
this.events.on('code-generator-ready', function (modifiedAssets) {
|
|
|
|
self.events.request('code', function (abi, contractsJSON) {
|
|
|
|
self.events.request('pipeline:build', {abi, contractsJSON, modifiedAssets}, () => {
|
|
|
|
self.events.emit('outputDone');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2017-03-16 11:31:52 +00:00
|
|
|
}
|
2017-03-30 11:38:14 +00:00
|
|
|
|
2018-06-01 16:27:12 +00:00
|
|
|
serviceMonitor() {
|
|
|
|
const self = this;
|
2018-06-02 13:54:32 +00:00
|
|
|
const ServicesMonitor = require('./services_monitor.js');
|
2018-06-01 16:27:12 +00:00
|
|
|
this.servicesMonitor = new ServicesMonitor({events: this.events, logger: this.logger, plugins: this.plugins});
|
2018-10-17 22:36:46 +00:00
|
|
|
this.servicesMonitor.addCheck('Embark', function (cb) {
|
2018-06-01 16:27:12 +00:00
|
|
|
return cb({name: 'Embark ' + self.version, status: 'on'});
|
|
|
|
}, 0);
|
|
|
|
this.servicesMonitor.startMonitor();
|
|
|
|
}
|
|
|
|
|
2018-09-09 17:37:55 +00:00
|
|
|
pluginCommandService() {
|
2018-09-10 17:08:17 +00:00
|
|
|
this.registerModule('plugin_cmd', {embarkConfigFile: this.embarkConfig, embarkConfig: this.config.embarkConfig, packageFile: 'package.json'});
|
2018-09-09 17:37:55 +00:00
|
|
|
}
|
|
|
|
|
2018-08-31 08:24:45 +00:00
|
|
|
console(_options) {
|
|
|
|
this.registerModule('console', {
|
|
|
|
events: this.events,
|
|
|
|
plugins: this.plugins,
|
|
|
|
version: this.version,
|
|
|
|
ipc: this.ipc,
|
|
|
|
logger: this.logger,
|
|
|
|
config: this.config
|
|
|
|
});
|
2018-10-02 03:59:24 +00:00
|
|
|
this.registerModule('authenticator');
|
2018-08-31 08:24:45 +00:00
|
|
|
}
|
|
|
|
|
2018-05-23 15:16:56 +00:00
|
|
|
codeRunnerService(_options) {
|
2018-08-22 22:04:52 +00:00
|
|
|
const CodeRunner = require('./modules/coderunner/codeRunner.js');
|
2018-05-21 21:22:19 +00:00
|
|
|
this.codeRunner = new CodeRunner({
|
2018-08-28 13:43:52 +00:00
|
|
|
config: this.config,
|
2018-05-23 15:16:56 +00:00
|
|
|
plugins: this.plugins,
|
|
|
|
events: this.events,
|
2018-08-22 22:04:52 +00:00
|
|
|
logger: this.logger,
|
|
|
|
ipc: this.ipc
|
2018-05-21 21:22:19 +00:00
|
|
|
});
|
2018-05-23 15:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
codeGeneratorService(_options) {
|
|
|
|
let self = this;
|
2018-05-21 21:22:19 +00:00
|
|
|
|
2018-08-22 22:04:52 +00:00
|
|
|
this.registerModule('code_generator', {plugins: self.plugins, env: self.env});
|
2018-05-23 15:16:13 +00:00
|
|
|
|
2018-10-16 23:29:53 +00:00
|
|
|
const generateCode = function (modifiedAssets) {
|
2018-07-27 18:54:25 +00:00
|
|
|
self.events.request("code-generator:embarkjs:build", () => {
|
2018-10-16 23:29:53 +00:00
|
|
|
self.events.emit('code-generator-ready', modifiedAssets);
|
2018-01-10 15:43:25 +00:00
|
|
|
});
|
2017-03-30 11:38:14 +00:00
|
|
|
};
|
2018-10-16 23:29:53 +00:00
|
|
|
const cargo = async.cargo((tasks, callback) => {
|
2018-10-22 18:25:18 +00:00
|
|
|
const modifiedAssets = tasks.map(task => task.modifiedAsset).filter(asset => asset); // filter null elements
|
2018-10-16 23:29:53 +00:00
|
|
|
generateCode(modifiedAssets);
|
2018-05-15 18:42:06 +00:00
|
|
|
self.events.once('outputDone', callback);
|
2018-10-16 23:29:53 +00:00
|
|
|
});
|
2018-10-11 11:19:27 +00:00
|
|
|
const addToCargo = function (modifiedAsset) {
|
|
|
|
cargo.push({modifiedAsset});
|
2018-05-15 18:42:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
this.events.on('contractsDeployed', addToCargo);
|
|
|
|
this.events.on('blockchainDisabled', addToCargo);
|
|
|
|
this.events.on('asset-changed', addToCargo);
|
2017-03-03 06:22:12 +00:00
|
|
|
}
|
2017-03-04 02:48:32 +00:00
|
|
|
|
2018-10-09 13:12:33 +00:00
|
|
|
setupCompilerAndContractsManagerService(options) {
|
|
|
|
this.registerModule('compiler', {plugins: this.plugins, disableOptimizations: options.disableOptimizations});
|
|
|
|
this.registerModule('solidity', {ipc: this.ipc, useDashboard: this.useDashboard});
|
|
|
|
this.registerModule('vyper');
|
|
|
|
this.registerModule('contracts_manager', {compileOnceOnly: options.compileOnceOnly});
|
|
|
|
}
|
|
|
|
|
2017-03-30 11:38:14 +00:00
|
|
|
deploymentService(options) {
|
|
|
|
let self = this;
|
2017-12-16 20:39:30 +00:00
|
|
|
|
2018-10-09 13:12:33 +00:00
|
|
|
this.setupCompilerAndContractsManagerService(options);
|
2018-08-01 17:27:50 +00:00
|
|
|
this.registerModule('compiler', {plugins: self.plugins, disableOptimizations: options.disableOptimizations});
|
|
|
|
this.registerModule('solidity', {ipc: self.ipc, useDashboard: this.useDashboard});
|
|
|
|
this.registerModule('vyper');
|
|
|
|
this.registerModule('profiler', {plugins: this.plugins});
|
2018-08-24 13:25:47 +00:00
|
|
|
this.registerModule('deploytracker', {trackContracts: options.trackContracts});
|
2018-05-30 16:26:49 +00:00
|
|
|
this.registerModule('specialconfigs');
|
2018-10-05 09:19:10 +00:00
|
|
|
this.registerModule('ens');
|
2018-08-08 12:42:45 +00:00
|
|
|
this.registerModule('console_listener', {ipc: self.ipc});
|
2018-07-27 20:03:15 +00:00
|
|
|
this.registerModule('deployment', {plugins: this.plugins, onlyCompile: options.onlyCompile});
|
2018-08-29 19:46:17 +00:00
|
|
|
this.registerModule('transactionTracker');
|
2018-10-12 22:22:17 +00:00
|
|
|
this.registerModule('debugger');
|
2017-03-30 11:38:14 +00:00
|
|
|
|
2018-10-11 11:19:27 +00:00
|
|
|
this.events.on('file-event', function ({fileType, path}) {
|
2018-05-15 19:41:24 +00:00
|
|
|
clearTimeout(self.fileTimeout);
|
|
|
|
self.fileTimeout = setTimeout(() => {
|
|
|
|
// TODO: still need to redeploy contracts because the original contracts
|
|
|
|
// config is being corrupted
|
2018-08-22 22:04:52 +00:00
|
|
|
self.config.reloadConfig();
|
|
|
|
|
2018-05-15 19:41:24 +00:00
|
|
|
if (fileType === 'asset') {
|
|
|
|
// Throttle file changes so we re-write only once for all files
|
2018-10-11 11:19:27 +00:00
|
|
|
self.events.emit('asset-changed', path);
|
2018-05-15 19:41:24 +00:00
|
|
|
}
|
|
|
|
// TODO: for now need to deploy on asset changes as well
|
|
|
|
// because the contractsManager config is corrupted after a deploy
|
|
|
|
if (fileType === 'contract' || fileType === 'config') {
|
2018-05-29 21:23:29 +00:00
|
|
|
self.events.request('deploy:contracts', () => {});
|
2018-05-15 19:41:24 +00:00
|
|
|
}
|
|
|
|
}, 50);
|
2017-03-30 11:12:39 +00:00
|
|
|
});
|
|
|
|
}
|
2017-03-11 03:00:30 +00:00
|
|
|
|
2018-10-03 15:15:16 +00:00
|
|
|
fileWatchService() {
|
|
|
|
this.registerModule('watcher');
|
|
|
|
this.events.request('watcher:start');
|
2017-03-30 11:38:14 +00:00
|
|
|
}
|
|
|
|
|
2018-09-17 22:51:46 +00:00
|
|
|
webServerService() {
|
2018-07-12 13:02:16 +00:00
|
|
|
this.registerModule('webserver', {plugins: this.plugins});
|
2017-03-30 11:38:14 +00:00
|
|
|
}
|
|
|
|
|
2018-05-25 07:13:57 +00:00
|
|
|
storageService(_options) {
|
2018-07-08 20:41:37 +00:00
|
|
|
this.registerModule('storage', {plugins: this.plugins});
|
2018-07-08 17:40:06 +00:00
|
|
|
this.registerModule('ipfs');
|
|
|
|
this.registerModule('swarm');
|
2018-04-24 00:27:11 +00:00
|
|
|
}
|
|
|
|
|
2017-03-30 11:38:14 +00:00
|
|
|
web3Service(options) {
|
2018-07-20 12:21:23 +00:00
|
|
|
this.registerModule('blockchain_process', {
|
2018-10-06 16:05:37 +00:00
|
|
|
client: this.client,
|
2018-07-20 12:21:23 +00:00
|
|
|
locale: this.locale,
|
2018-08-23 16:54:43 +00:00
|
|
|
isDev: this.isDev,
|
|
|
|
ipc: this.ipc
|
2018-07-20 12:21:23 +00:00
|
|
|
});
|
|
|
|
|
2018-07-27 20:54:33 +00:00
|
|
|
this.registerModule('blockchain_connector', {
|
2018-05-18 18:58:05 +00:00
|
|
|
isDev: this.isDev,
|
2018-07-19 20:31:28 +00:00
|
|
|
locale: this.locale,
|
2018-07-31 14:46:19 +00:00
|
|
|
plugins: this.plugins,
|
2018-10-09 20:43:38 +00:00
|
|
|
web3: options.web3,
|
|
|
|
wait: options.wait
|
2018-07-27 20:54:33 +00:00
|
|
|
});
|
2018-04-10 19:14:00 +00:00
|
|
|
|
2018-08-22 22:04:52 +00:00
|
|
|
this.registerModule('whisper');
|
2017-03-30 11:38:14 +00:00
|
|
|
}
|
2017-12-30 20:52:51 +00:00
|
|
|
|
2017-12-30 22:07:13 +00:00
|
|
|
libraryManagerService(_options) {
|
2018-08-22 22:04:52 +00:00
|
|
|
this.registerModule('library_manager');
|
|
|
|
}
|
|
|
|
|
|
|
|
codeCoverageService(_options) {
|
|
|
|
this.registerModule('coverage');
|
2018-08-22 22:04:52 +00:00
|
|
|
}
|
|
|
|
|
2018-10-18 12:36:34 +00:00
|
|
|
testRunnerService(options) {
|
2018-10-18 12:38:29 +00:00
|
|
|
this.registerModule('tests', Object.assign(options, {ipc: this.ipc}));
|
2018-10-18 12:36:34 +00:00
|
|
|
}
|
|
|
|
|
2018-08-01 16:08:47 +00:00
|
|
|
codeCoverageService(_options) {
|
|
|
|
this.registerModule('coverage');
|
|
|
|
}
|
2017-03-30 11:38:14 +00:00
|
|
|
}
|
2017-03-11 15:29:45 +00:00
|
|
|
|
2017-03-03 06:22:12 +00:00
|
|
|
module.exports = Engine;
|