From a2a27bb0c2d8f539c3e9c58a8904038424df13f2 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 24 Feb 2017 08:20:03 -0500 Subject: [PATCH 1/9] start refactoring deployment steps --- lib/contracts/abi.js | 6 +- lib/contracts/contracts.js | 8 +-- lib/contracts/deploy_manager.js | 83 ++++++++++++++++++++++++ lib/index.js | 110 ++++++-------------------------- 4 files changed, 112 insertions(+), 95 deletions(-) create mode 100644 lib/contracts/deploy_manager.js diff --git a/lib/contracts/abi.js b/lib/contracts/abi.js index 86480995..7246de69 100644 --- a/lib/contracts/abi.js +++ b/lib/contracts/abi.js @@ -108,8 +108,10 @@ ABIGenerator.prototype.generateABI = function(options) { result += this.generateProvider(); result += this.generateContracts(options.useEmbarkJS); - result += this.generateStorageInitialization(options.useEmbarkJS); - result += this.generateCommunicationInitialization(options.useEmbarkJS); + + // TODO: disable this for now until refactor is over + //result += this.generateStorageInitialization(options.useEmbarkJS); + //result += this.generateCommunicationInitialization(options.useEmbarkJS); return result; }; diff --git a/lib/contracts/contracts.js b/lib/contracts/contracts.js index 9bd20e05..ef7df60e 100644 --- a/lib/contracts/contracts.js +++ b/lib/contracts/contracts.js @@ -41,14 +41,14 @@ ContractsManager.prototype.build = function(done) { function compileContracts(callback) { var compiler = new Compiler({plugins: self.plugins}); // TODO: check if try is still needed - try { + //try { compiler.compile_contracts(self.contractFiles, function(compiledObject) { self.compiledContracts = compiledObject; callback(); }); - } catch(err) { - return callback(new Error(err.message)); - } + //} catch(err) { + // return callback(new Error(err.message)); + //} }, function prepareContractsFromConfig(callback) { var className, contract; diff --git a/lib/contracts/deploy_manager.js b/lib/contracts/deploy_manager.js new file mode 100644 index 00000000..08c535bc --- /dev/null +++ b/lib/contracts/deploy_manager.js @@ -0,0 +1,83 @@ +var async = require('async'); +var Web3 = require('web3'); + +var Deploy = require('./deploy.js'); +var ContractsManager = require('./contracts.js'); +var ABIGenerator = require('./abi.js'); + +var DeployManager = function(options) { + this.config = options.config; + this.logger = options.logger; + this.plugins = options.plugins; + this.events = options.events; +}; + +DeployManager.prototype.deployContracts = function(done) { + var self = this; + async.waterfall([ + function buildContracts(callback) { + var contractsManager = new ContractsManager({ + contractFiles: self.config.contractsFiles, + contractsConfig: self.config.contractsConfig, + logger: self.logger, + plugins: self.plugins + }); + contractsManager.build(callback); + }, + function deployContracts(contractsManager, callback) { + + //TODO: figure out where to put this since the web3 can be passed along if needed + // perhaps it should go into the deploy object itself + // TODO: should come from the config object + var web3 = new Web3(); + var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort; + web3.setProvider(new web3.providers.HttpProvider(web3Endpoint)); + + if (!web3.isConnected()) { + console.log(("Couldn't connect to " + web3Endpoint.underline + " are you sure it's on?").red); + console.log("make sure you have an ethereum node or simulator running. e.g 'embark blockchain'".magenta); + // =================================== + // TODO: should throw exception instead + // =================================== + process.exit(); + } + + web3.eth.getAccounts(function(err, accounts) { + if (err) { + return callback(new Error(err)); + } + web3.eth.defaultAccount = accounts[0]; + + var deploy = new Deploy({ + web3: web3, + contractsManager: contractsManager, + logger: self.logger, + chainConfig: self.config.chainTracker, + env: self.config.env + }); + deploy.deployAll(function() { + callback(null, contractsManager); + }); + }); + }, + function generateABI(contractsManager, callback) { + var abiGenerator = new ABIGenerator({blockchainConfig: self.config.blockchainConfig, contractsManager: contractsManager, plugins: self.plugins, storageConfig: self.config.storageConfig}); + var embarkJSABI = abiGenerator.generateABI({useEmbarkJS: true}); + var vanillaABI = abiGenerator.generateABI({useEmbarkJS: false}); + + self.events.emit('abi-vanila', vanillaABI); + self.events.emit('abi', embarkJSABI); + + callback(null, embarkJSABI); + } + ], function(err, result) { + if (err) { + done(err, null); + } else { + done(null, result); + } + }); +}; + +module.exports = DeployManager; + diff --git a/lib/index.js b/lib/index.js index 8f2bf337..1ffed4ba 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,9 +7,7 @@ var Blockchain = require('./cmds/blockchain/blockchain.js'); var Simulator = require('./cmds/simulator.js'); var TemplateGenerator = require('./cmds/template_generator.js'); -var Deploy = require('./contracts/deploy.js'); -var ContractsManager = require('./contracts/contracts.js'); -var ABIGenerator = require('./contracts/abi.js'); +var DeployManager = require('./contracts/deploy_manager.js'); var Test = require('./core/test.js'); var Logger = require('./core/logger.js'); @@ -138,7 +136,20 @@ var Embark = { Embark.servicesMonitor.startMonitor(); callback(); }, - self.buildDeployGenerate.bind(self), + function (callback) { + var deployManager = new DeployManager({ + config: Embark.config, + logger: Embark.logger, + plugins: self.plugins, + events: self.events + }); + deployManager.deployContracts(function(abi) { + callback(null, abi); + }); + //if (Embark.dashboard) { + // Embark.dashboard.console.runCode(consoleABI); + //} + }, function buildPipeline(abi, callback) { self.logger.setStatus("Building Assets"); var pipeline = new Pipeline({ @@ -148,6 +159,7 @@ var Embark = { logger: self.logger, plugins: self.plugins }); + // TODO: do this with event instead pipeline.build(abi); callback(); }, @@ -158,7 +170,7 @@ var Embark = { self.events.on('file-event', function(fileType, path) { if (fileType === 'contract' || fileType === 'config') { self.logger.info("received redeploy event"); - Embark.redeploy(); + //Embark.redeploy(); } }); self.events.on('rebuildAssets', function(fileType, path) { @@ -166,7 +178,7 @@ var Embark = { self.logger.info("received rebuildAssets event"); // TODO: can just rebuild pipeline, no need to deploy contracts // again - Embark.redeploy(); + //Embark.redeploy(); } }); callback(); @@ -211,7 +223,9 @@ var Embark = { logger: self.logger, plugins: self.plugins }); - pipeline.build(abi); + Embark.events.on('abi', function(abi) { + pipeline.build(abi); + }); callback(); } ], function(err, result) { @@ -223,64 +237,6 @@ var Embark = { }); }, - buildAndDeploy: function(done) { - var self = this; - async.waterfall([ - function buildContracts(callback) { - var contractsManager = new ContractsManager({ - contractFiles: self.config.contractsFiles, - contractsConfig: self.config.contractsConfig, - logger: Embark.logger, - plugins: self.plugins - }); - contractsManager.build(callback); - }, - function deployContracts(contractsManager, callback) { - - //TODO: figure out where to put this since the web3 can be passed along if needed - // perhaps it should go into the deploy object itself - // TODO: should come from the config object - var web3 = new Web3(); - var web3Endpoint = 'http://' + self.config.blockchainConfig.rpcHost + ':' + self.config.blockchainConfig.rpcPort; - web3.setProvider(new web3.providers.HttpProvider(web3Endpoint)); - - if (!web3.isConnected()) { - console.log(("Couldn't connect to " + web3Endpoint.underline + " are you sure it's on?").red); - console.log("make sure you have an ethereum node or simulator running. e.g 'embark blockchain'".magenta); - // =================================== - // TODO: should throw exception instead - // =================================== - process.exit(); - } - - web3.eth.getAccounts(function(err, accounts) { - if (err) { - return callback(new Error(err)); - } - web3.eth.defaultAccount = accounts[0]; - - var deploy = new Deploy({ - web3: web3, - contractsManager: contractsManager, - logger: Embark.logger, - chainConfig: self.config.chainTracker, - env: self.config.env - }); - deploy.deployAll(function() { - callback(null, contractsManager); - }); - }); - - } - ], function(err, result) { - if (err) { - done(err, null); - } else { - done(null, result); - } - }); - }, - deploy: function(done) { var self = this; async.waterfall([ @@ -290,8 +246,6 @@ var Embark = { }); }, function generateABI(contractsManager, callback) { - var abiGenerator = new ABIGenerator({blockchainConfig: self.config.blockchainConfig, contractsManager: contractsManager, plugins: self.plugins, storageConfig: self.config.storageConfig}); - callback(null, abiGenerator.generateABI({useEmbarkJS: true})); } ], function(err, result) { if (err) { @@ -301,38 +255,16 @@ var Embark = { }); }, - buildDeployGenerate: function(done) { var self = this; - if (self.config.blockchainConfig.enabled === false) { - self.logger.info('== blockchain is disabled in this environment in config/blockchain.json'.underline); - return done(null, ""); - } - self.logger.setStatus("Deploying...".magenta.underline); async.waterfall([ - function deployAndBuildContractsManager(callback) { - Embark.buildAndDeploy(function(err, contractsManager) { - if (err) { - return callback(err); - } - return callback(null, contractsManager); - }); - }, function generateConsoleABI(contractsManager, callback) { - var abiGenerator = new ABIGenerator({blockchainConfig: self.config.blockchainConfig, contractsManager: contractsManager, storageConfig: self.config.storageConfig, communicationConfig: self.config.communicationConfig}); - var consoleABI = abiGenerator.generateABI({useEmbarkJS: false}); - // not good, better generate events when deployment is done and do this // through a listener - if (Embark.dashboard) { - Embark.dashboard.console.runCode(consoleABI); - } callback(null, contractsManager); }, function generateABI(contractsManager, callback) { - var abiGenerator = new ABIGenerator({blockchainConfig: self.config.blockchainConfig, contractsManager: contractsManager, plugins: self.plugins, storageConfig: self.config.storageConfig, communicationConfig: self.config.communicationConfig}); - callback(null, abiGenerator.generateABI({useEmbarkJS: true})); } ], function(err, result) { if (err) { From 4b119fffdea02c01790f5956a5478d37fe610a47 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 24 Feb 2017 19:27:27 -0500 Subject: [PATCH 2/9] add solc wrapper --- lib/contracts/compiler.js | 7 ++++++- lib/contracts/solcW.js | 12 ++++++++++++ lib/index.js | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 lib/contracts/solcW.js diff --git a/lib/contracts/compiler.js b/lib/contracts/compiler.js index 80cc8612..c4168efd 100644 --- a/lib/contracts/compiler.js +++ b/lib/contracts/compiler.js @@ -1,6 +1,6 @@ /*jshint esversion: 6, loopfunc: true */ -var solc = require('solc'); var async = require('async'); +var SolcW = require('./solcW.js'); function asyncEachObject(object, iterator, callback) { async.each( @@ -64,6 +64,11 @@ Compiler.prototype.compile_solidity = function(contractFiles, cb) { input[filename] = contractFiles[i].content.toString(); } + var solcW = new SolcW(); + console.log("loading solc.."); + var solc = solcW.load_compiler(function(){ + console.log("loaded solc"); + }); var output = solc.compile({sources: input}, 1); if (output.errors) { diff --git a/lib/contracts/solcW.js b/lib/contracts/solcW.js new file mode 100644 index 00000000..a62cfd57 --- /dev/null +++ b/lib/contracts/solcW.js @@ -0,0 +1,12 @@ + +var SolcW = function() { +}; + +SolcW.prototype.load_compiler = function(done) { + var solc = require('solc'); + done(); + return solc; +}; + +module.exports = SolcW; + diff --git a/lib/index.js b/lib/index.js index 1ffed4ba..2dc1cee4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -136,7 +136,7 @@ var Embark = { Embark.servicesMonitor.startMonitor(); callback(); }, - function (callback) { + function deploy(callback) { var deployManager = new DeployManager({ config: Embark.config, logger: Embark.logger, From d73eb802eaf728d49cc95cc6cda0e94a09106ac1 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 24 Feb 2017 22:49:34 -0500 Subject: [PATCH 3/9] refactor deployment --- lib/contracts/compiler.js | 80 +++++++++++------- lib/contracts/contracts.js | 2 +- lib/contracts/deploy_manager.js | 3 +- lib/contracts/solcP.js | 14 ++++ lib/contracts/solcW.js | 21 ++++- lib/index.js | 144 ++++++++++++-------------------- 6 files changed, 136 insertions(+), 128 deletions(-) create mode 100644 lib/contracts/solcP.js diff --git a/lib/contracts/compiler.js b/lib/contracts/compiler.js index c4168efd..5dfb6c6e 100644 --- a/lib/contracts/compiler.js +++ b/lib/contracts/compiler.js @@ -15,13 +15,14 @@ async.eachObject = asyncEachObject; var Compiler = function(options) { this.plugins = options.plugins; + this.logger = options.logger; }; Compiler.prototype.compile_contracts = function(contractFiles, cb) { var available_compilers = { //".se": this.compile_serpent - ".sol": this.compile_solidity + ".sol": this.compile_solidity.bind(this) }; if (this.plugins) { @@ -56,41 +57,56 @@ Compiler.prototype.compile_contracts = function(contractFiles, cb) { }; Compiler.prototype.compile_solidity = function(contractFiles, cb) { + var self = this; var input = {}; + var solcW; + async.waterfall([ + function prepareInput(callback) { + for (var i = 0; i < contractFiles.length; i++){ + // TODO: this depends on the config + var filename = contractFiles[i].filename.replace('app/contracts/',''); + input[filename] = contractFiles[i].content.toString(); + } + callback(); + }, + function loadCompiler(callback) { + // TODO: there ino need to load this twice + self.logger.info("loading solc compiler.."); + solcW = new SolcW(); + solcW.load_compiler(function(){ + callback(); + }); + }, + function compileContracts(callback) { + self.logger.info("compiling contracts..."); + solcW.compile({sources: input}, 1, function(output) { + // TODO: check error is handled properly + //if (output.errors) { + // throw new Error ("Solidity errors: " + output.errors); + //} + callback(null, output); + }); + }, + function createCompiledObject(output, callback) { + var json = output.contracts; - for (var i = 0; i < contractFiles.length; i++){ - // TODO: this depends on the config - var filename = contractFiles[i].filename.replace('app/contracts/',''); - input[filename] = contractFiles[i].content.toString(); - } + compiled_object = {}; - var solcW = new SolcW(); - console.log("loading solc.."); - var solc = solcW.load_compiler(function(){ - console.log("loaded solc"); + for (var className in json) { + var contract = json[className]; + + compiled_object[className] = {}; + compiled_object[className].code = contract.bytecode; + compiled_object[className].runtimeBytecode = contract.runtimeBytecode; + compiled_object[className].gasEstimates = contract.gasEstimates; + compiled_object[className].functionHashes = contract.functionHashes; + compiled_object[className].abiDefinition = JSON.parse(contract.interface); + } + callback(null, compiled_object); + } + ], function(err, result) { + cb(result); }); - var output = solc.compile({sources: input}, 1); - - if (output.errors) { - throw new Error ("Solidity errors: " + output.errors); - } - - var json = output.contracts; - - compiled_object = {}; - - for (var className in json) { - var contract = json[className]; - - compiled_object[className] = {}; - compiled_object[className].code = contract.bytecode; - compiled_object[className].runtimeBytecode = contract.runtimeBytecode; - compiled_object[className].gasEstimates = contract.gasEstimates; - compiled_object[className].functionHashes = contract.functionHashes; - compiled_object[className].abiDefinition = JSON.parse(contract.interface); - } - - cb(compiled_object); }; module.exports = Compiler; diff --git a/lib/contracts/contracts.js b/lib/contracts/contracts.js index ef7df60e..e4908d91 100644 --- a/lib/contracts/contracts.js +++ b/lib/contracts/contracts.js @@ -39,7 +39,7 @@ ContractsManager.prototype.build = function(done) { var self = this; async.waterfall([ function compileContracts(callback) { - var compiler = new Compiler({plugins: self.plugins}); + var compiler = new Compiler({plugins: self.plugins, logger: self.logger}); // TODO: check if try is still needed //try { compiler.compile_contracts(self.contractFiles, function(compiledObject) { diff --git a/lib/contracts/deploy_manager.js b/lib/contracts/deploy_manager.js index 08c535bc..4f5eb302 100644 --- a/lib/contracts/deploy_manager.js +++ b/lib/contracts/deploy_manager.js @@ -15,7 +15,7 @@ var DeployManager = function(options) { DeployManager.prototype.deployContracts = function(done) { var self = this; async.waterfall([ - function buildContracts(callback) { + function buildContracts(callback) { var contractsManager = new ContractsManager({ contractFiles: self.config.contractsFiles, contractsConfig: self.config.contractsConfig, @@ -57,6 +57,7 @@ DeployManager.prototype.deployContracts = function(done) { }); deploy.deployAll(function() { callback(null, contractsManager); + self.events.emit('contractsDeployed'); }); }); }, diff --git a/lib/contracts/solcP.js b/lib/contracts/solcP.js new file mode 100644 index 00000000..257579f6 --- /dev/null +++ b/lib/contracts/solcP.js @@ -0,0 +1,14 @@ +var solc; + +process.on('message', function(msg) { + if (msg.action === 'loadCompiler') { + solc = require('solc'); + process.send({result: "loadedCompiler"}); + } + + if (msg.action === 'compile') { + var output = solc.compile(msg.obj, msg.optimize); + process.send({result: "compilation", output: output}); + } +}); + diff --git a/lib/contracts/solcW.js b/lib/contracts/solcW.js index a62cfd57..62804094 100644 --- a/lib/contracts/solcW.js +++ b/lib/contracts/solcW.js @@ -1,11 +1,26 @@ +var solcProcess = require('child_process').fork(__dirname + '/solcP.js'); var SolcW = function() { }; SolcW.prototype.load_compiler = function(done) { - var solc = require('solc'); - done(); - return solc; + solcProcess.on('message', function(msg) { + if (msg.result !== 'loadedCompiler') { + return; + } + done(); + }); + solcProcess.send({action: 'loadCompiler'}); +}; + +SolcW.prototype.compile = function(obj, optimize, done) { + solcProcess.on('message', function(msg) { + if (msg.result !== 'compilation') { + return; + } + done(msg.output); + }); + solcProcess.send({action: 'compile', obj, optimize}); }; module.exports = SolcW; diff --git a/lib/index.js b/lib/index.js index 2dc1cee4..439b8ee2 100644 --- a/lib/index.js +++ b/lib/index.js @@ -60,60 +60,54 @@ var Embark = { templateGenerator.generate(destinationFolder, name); }, - redeploy: function(env) { - var self = this; - async.waterfall([ - function reloadFiles(callback) { - self.config.reloadConfig(); - callback(); - }, - self.buildDeployGenerate.bind(self), - function buildPipeline(abi, callback) { - self.logger.setStatus("Building Assets"); - var pipeline = new Pipeline({ - buildDir: self.config.buildDir, - contractsFiles: self.config.contractsFiles, - assetFiles: self.config.assetFiles, - logger: self.logger, - plugins: self.plugins - }); - pipeline.build(abi); - callback(); - } - ], function(err, result) { - if (err) { - self.logger.error(err.message); - } else { - self.logger.trace("finished".underline); - } - }); - }, - run: function(options) { var self = this; var env = options.env; - async.waterfall([ - function welcome(callback) { - if (!options.useDashboard) { - console.log('========================'.bold.green); - console.log(('Welcome to Embark ' + Embark.version).yellow.bold); - console.log('========================'.bold.green); - } - callback(); - }, + + if (!options.useDashboard) { + console.log('========================'.bold.green); + console.log(('Welcome to Embark ' + Embark.version).yellow.bold); + console.log('========================'.bold.green); + } + + async.parallel([ function startDashboard(callback) { if (!options.useDashboard) { return callback(); } - Embark.dashboard = new Dashboard({ + var dashboard = new Dashboard({ logger: Embark.logger, plugins: self.plugins, version: self.version, env: env }); - Embark.dashboard.start(callback); + dashboard.start(function() { + self.events.on('abi-vanila', function(abi) { + dashboard.console.runCode(abi); + }); + + callback(); + }); }, + function (callback) { + Embark.startEmbark(options, callback); + } + ], function(err, result) { + if (err) { + self.logger.error(err.message); + } else { + self.logger.setStatus("Ready".green); + self.logger.info("Looking for documentation? you can find it at ".cyan + "http://embark.readthedocs.io/".green.underline); + self.logger.info("Ready".underline); + } + }); + }, + + startEmbark: function(options, done) { + var self = this; + var env = options.env; + async.waterfall([ function displayLoadedPlugins(callback) { var pluginList = self.plugins.listPlugins(); if (pluginList.length > 0) { @@ -121,11 +115,12 @@ var Embark = { } callback(); }, + // can be done in paralell function monitorServices(callback) { if (!options.useDashboard) { return callback(); } - Embark.servicesMonitor = new ServicesMonitor({ + var servicesMonitor = new ServicesMonitor({ logger: Embark.logger, config: Embark.config, serverHost: options.serverHost, @@ -133,9 +128,10 @@ var Embark = { runWebserver: options.runWebserver, version: Embark.version }); - Embark.servicesMonitor.startMonitor(); + servicesMonitor.startMonitor(); callback(); }, + function deploy(callback) { var deployManager = new DeployManager({ config: Embark.config, @@ -143,14 +139,13 @@ var Embark = { plugins: self.plugins, events: self.events }); - deployManager.deployContracts(function(abi) { - callback(null, abi); + deployManager.deployContracts(function() { + callback(); }); - //if (Embark.dashboard) { - // Embark.dashboard.console.runCode(consoleABI); - //} }, - function buildPipeline(abi, callback) { + + + function buildPipeline(callback) { self.logger.setStatus("Building Assets"); var pipeline = new Pipeline({ buildDir: self.config.buildDir, @@ -159,10 +154,12 @@ var Embark = { logger: self.logger, plugins: self.plugins }); - // TODO: do this with event instead - pipeline.build(abi); + self.events.on('abi', function(abi) { + pipeline.build(abi); + }); callback(); }, + function watchFilesForChanges(callback) { self.logger.setStatus("Watching for changes"); var watch = new Watch({logger: self.logger, events: self.events}); @@ -183,6 +180,9 @@ var Embark = { }); callback(); }, + + + function startAssetServer(callback) { if (!options.runWebserver) { return callback(); @@ -195,6 +195,8 @@ var Embark = { }); server.start(callback); } + + ], function(err, result) { if (err) { self.logger.error(err.message); @@ -203,6 +205,7 @@ var Embark = { self.logger.info("Looking for documentation? you can find it at ".cyan + "http://embark.readthedocs.io/".green.underline); self.logger.info("Ready".underline); } + done(); }); }, @@ -237,47 +240,6 @@ var Embark = { }); }, - deploy: function(done) { - var self = this; - async.waterfall([ - function buildAndDeploy(callback) { - Embark.buildAndDeploy(function(err, contractsManager) { - callback(err, contractsManager); - }); - }, - function generateABI(contractsManager, callback) { - } - ], function(err, result) { - if (err) { - self.logger.error(err.message); - } - done(result); - }); - }, - - buildDeployGenerate: function(done) { - var self = this; - - self.logger.setStatus("Deploying...".magenta.underline); - async.waterfall([ - function generateConsoleABI(contractsManager, callback) { - // through a listener - callback(null, contractsManager); - }, - function generateABI(contractsManager, callback) { - } - ], function(err, result) { - if (err) { - self.logger.error("error deploying"); - self.logger.error(err.message); - self.logger.setStatus("Deployment Error".red); - } else { - self.logger.setStatus("Ready".green); - } - done(null, result); - }); - }, - initTests: function(options) { return new Test(options); }, From e9ce9dc6f160d93a7d083e158ec0eb219b1ff340 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sat, 25 Feb 2017 15:47:35 -0500 Subject: [PATCH 4/9] add redeploy; don't reload compiler if it's already loaded --- lib/contracts/compiler.js | 10 ++++-- lib/contracts/solcW.js | 11 +++++-- lib/core/core.js | 5 +++ lib/index.js | 55 ++++++++++++++++---------------- test_app/app/contracts/token.sol | 1 + 5 files changed, 50 insertions(+), 32 deletions(-) create mode 100644 lib/core/core.js diff --git a/lib/contracts/compiler.js b/lib/contracts/compiler.js index 5dfb6c6e..4f9b1cc2 100644 --- a/lib/contracts/compiler.js +++ b/lib/contracts/compiler.js @@ -71,11 +71,15 @@ Compiler.prototype.compile_solidity = function(contractFiles, cb) { }, function loadCompiler(callback) { // TODO: there ino need to load this twice - self.logger.info("loading solc compiler.."); solcW = new SolcW(); - solcW.load_compiler(function(){ + if (solcW.isCompilerLoaded()) { callback(); - }); + } else { + self.logger.info("loading solc compiler.."); + solcW.load_compiler(function(){ + callback(); + }); + } }, function compileContracts(callback) { self.logger.info("compiling contracts..."); diff --git a/lib/contracts/solcW.js b/lib/contracts/solcW.js index 62804094..8c9b0523 100644 --- a/lib/contracts/solcW.js +++ b/lib/contracts/solcW.js @@ -1,20 +1,27 @@ var solcProcess = require('child_process').fork(__dirname + '/solcP.js'); +var compilerLoaded = false; var SolcW = function() { }; SolcW.prototype.load_compiler = function(done) { - solcProcess.on('message', function(msg) { + if (compilerLoaded) { done(); } + solcProcess.once('message', function(msg) { if (msg.result !== 'loadedCompiler') { return; } + compilerLoaded = true; done(); }); solcProcess.send({action: 'loadCompiler'}); }; +SolcW.prototype.isCompilerLoaded = function() { + return (compilerLoaded === true); +} + SolcW.prototype.compile = function(obj, optimize, done) { - solcProcess.on('message', function(msg) { + solcProcess.once('message', function(msg) { if (msg.result !== 'compilation') { return; } diff --git a/lib/core/core.js b/lib/core/core.js new file mode 100644 index 00000000..424eda08 --- /dev/null +++ b/lib/core/core.js @@ -0,0 +1,5 @@ + +var Core = function() {}; + +module.exports = Core; + diff --git a/lib/index.js b/lib/index.js index 439b8ee2..a7bb06d6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -115,6 +115,7 @@ var Embark = { } callback(); }, + // can be done in paralell function monitorServices(callback) { if (!options.useDashboard) { @@ -132,18 +133,6 @@ var Embark = { callback(); }, - function deploy(callback) { - var deployManager = new DeployManager({ - config: Embark.config, - logger: Embark.logger, - plugins: self.plugins, - events: self.events - }); - deployManager.deployContracts(function() { - callback(); - }); - }, - function buildPipeline(callback) { self.logger.setStatus("Building Assets"); @@ -160,29 +149,41 @@ var Embark = { callback(); }, + function deploy(callback) { + var deployManager = new DeployManager({ + config: Embark.config, + logger: Embark.logger, + plugins: self.plugins, + events: self.events + }); + deployManager.deployContracts(function() { + callback(); + }); + + self.events.on('file-event', function(fileType, path) { + if (fileType === 'contract' || fileType === 'config') { + self.config.reloadConfig(); + deployManager.deployContracts(function() {}); + } + }); + self.events.on('file-event', function(fileType, path) { + if (fileType === 'asset') { + // TODO: can just rebuild pipeline, no need to deploy contracts + // again + self.config.reloadConfig(); + deployManager.deployContracts(function() {}); + } + }); + }, + function watchFilesForChanges(callback) { self.logger.setStatus("Watching for changes"); var watch = new Watch({logger: self.logger, events: self.events}); watch.start(); - self.events.on('file-event', function(fileType, path) { - if (fileType === 'contract' || fileType === 'config') { - self.logger.info("received redeploy event"); - //Embark.redeploy(); - } - }); - self.events.on('rebuildAssets', function(fileType, path) { - if (fileType === 'asset') { - self.logger.info("received rebuildAssets event"); - // TODO: can just rebuild pipeline, no need to deploy contracts - // again - //Embark.redeploy(); - } - }); callback(); }, - function startAssetServer(callback) { if (!options.runWebserver) { return callback(); diff --git a/test_app/app/contracts/token.sol b/test_app/app/contracts/token.sol index 9d5c34f8..0eff9e71 100644 --- a/test_app/app/contracts/token.sol +++ b/test_app/app/contracts/token.sol @@ -9,6 +9,7 @@ contract Token { mapping( address => uint ) _balances; mapping( address => mapping( address => uint ) ) _approvals; uint public _supply; + //uint public _supply2; function Token( uint initial_balance ) { _balances[msg.sender] = initial_balance; _supply = initial_balance; From 85519e95d8f3f85491799149414167d24b2d9bfa Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sat, 25 Feb 2017 20:45:40 -0500 Subject: [PATCH 5/9] add new deploy manager to build cmd --- lib/cmd.js | 1 + lib/index.js | 29 ++++++++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/cmd.js b/lib/cmd.js index 9ab1050b..f2587bca 100644 --- a/lib/cmd.js +++ b/lib/cmd.js @@ -150,6 +150,7 @@ Cmd.prototype.otherCommands = function() { .action(function(env){ console.log('unknown command "%s"'.red, env); console.log("type embark --help to see the available commands"); + process.exit(0); }); }; diff --git a/lib/index.js b/lib/index.js index a7bb06d6..aa64a034 100644 --- a/lib/index.js +++ b/lib/index.js @@ -133,7 +133,6 @@ var Embark = { callback(); }, - function buildPipeline(callback) { self.logger.setStatus("Building Assets"); var pipeline = new Pipeline({ @@ -183,7 +182,6 @@ var Embark = { callback(); }, - function startAssetServer(callback) { if (!options.runWebserver) { return callback(); @@ -197,14 +195,9 @@ var Embark = { server.start(callback); } - ], function(err, result) { if (err) { self.logger.error(err.message); - } else { - self.logger.setStatus("Ready".green); - self.logger.info("Looking for documentation? you can find it at ".cyan + "http://embark.readthedocs.io/".green.underline); - self.logger.info("Ready".underline); } done(); }); @@ -213,11 +206,26 @@ var Embark = { build: function(env) { var self = this; async.waterfall([ + function displayLoadedPlugins(callback) { + var pluginList = self.plugins.listPlugins(); + if (pluginList.length > 0) { + self.logger.info("loaded plugins: " + pluginList.join(", ")); + } + callback(); + }, + function deployAndGenerateABI(callback) { - Embark.deploy(function(abi) { + var deployManager = new DeployManager({ + config: Embark.config, + logger: Embark.logger, + plugins: self.plugins, + events: self.events + }); + deployManager.deployContracts(function(error, abi) { callback(null, abi); }); }, + function buildPipeline(abi, callback) { self.logger.trace("Building Assets"); var pipeline = new Pipeline({ @@ -227,11 +235,10 @@ var Embark = { logger: self.logger, plugins: self.plugins }); - Embark.events.on('abi', function(abi) { - pipeline.build(abi); - }); + pipeline.build(abi); callback(); } + ], function(err, result) { if (err) { self.logger.error(err.message); From 5fc2d976091f3ea8f76f37939031e57b1953b19c Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sat, 25 Feb 2017 22:39:40 -0500 Subject: [PATCH 6/9] fix so child process doesn't hang some cmds --- lib/contracts/solcP.js | 4 ++++ lib/contracts/solcW.js | 5 +++-- lib/index.js | 5 +++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/contracts/solcP.js b/lib/contracts/solcP.js index 257579f6..2332091f 100644 --- a/lib/contracts/solcP.js +++ b/lib/contracts/solcP.js @@ -12,3 +12,7 @@ process.on('message', function(msg) { } }); +process.on('exit', function() { + process.exit(0); +}); + diff --git a/lib/contracts/solcW.js b/lib/contracts/solcW.js index 8c9b0523..a3c9c33a 100644 --- a/lib/contracts/solcW.js +++ b/lib/contracts/solcW.js @@ -1,4 +1,4 @@ -var solcProcess = require('child_process').fork(__dirname + '/solcP.js'); +var solcProcess; var compilerLoaded = false; var SolcW = function() { @@ -6,6 +6,7 @@ var SolcW = function() { SolcW.prototype.load_compiler = function(done) { if (compilerLoaded) { done(); } + solcProcess = require('child_process').fork(__dirname + '/solcP.js'); solcProcess.once('message', function(msg) { if (msg.result !== 'loadedCompiler') { return; @@ -18,7 +19,7 @@ SolcW.prototype.load_compiler = function(done) { SolcW.prototype.isCompilerLoaded = function() { return (compilerLoaded === true); -} +}; SolcW.prototype.compile = function(obj, optimize, done) { solcProcess.once('message', function(msg) { diff --git a/lib/index.js b/lib/index.js index aa64a034..1123922d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -238,13 +238,14 @@ var Embark = { pipeline.build(abi); callback(); } - ], function(err, result) { if (err) { self.logger.error(err.message); } else { - self.logger.trace("finished".underline); + self.logger.info("finished building".underline); } + // needed due to child processes + process.exit(); }); }, From 562efc6f144bd4694649c7fa8fadd2dcc9091e05 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sat, 25 Feb 2017 22:57:22 -0500 Subject: [PATCH 7/9] test fixes --- lib/contracts/compiler.js | 1 + lib/contracts/solcW.js | 2 +- test/compiler.js | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/contracts/compiler.js b/lib/contracts/compiler.js index 4f9b1cc2..0069b008 100644 --- a/lib/contracts/compiler.js +++ b/lib/contracts/compiler.js @@ -67,6 +67,7 @@ Compiler.prototype.compile_solidity = function(contractFiles, cb) { var filename = contractFiles[i].filename.replace('app/contracts/',''); input[filename] = contractFiles[i].content.toString(); } + console.log(input); callback(); }, function loadCompiler(callback) { diff --git a/lib/contracts/solcW.js b/lib/contracts/solcW.js index a3c9c33a..a5015c59 100644 --- a/lib/contracts/solcW.js +++ b/lib/contracts/solcW.js @@ -28,7 +28,7 @@ SolcW.prototype.compile = function(obj, optimize, done) { } done(msg.output); }); - solcProcess.send({action: 'compile', obj, optimize}); + solcProcess.send({action: 'compile', object: obj, optimize: optimize}); }; module.exports = SolcW; diff --git a/test/compiler.js b/test/compiler.js index 3d4621e3..a7066d18 100644 --- a/test/compiler.js +++ b/test/compiler.js @@ -1,5 +1,6 @@ /*globals describe, it*/ var Compiler = require('../lib/contracts/compiler.js'); +var TestLogger = require('../lib/core/test_logger.js'); var assert = require('assert'); var fs = require('fs'); @@ -8,7 +9,7 @@ var readFile = function(file) { }; describe('embark.Compiler', function() { - var compiler = new Compiler({}); + var compiler = new Compiler({logger: new TestLogger({})}); describe('#compile_solidity', function() { var expectedObject = {}; @@ -22,7 +23,8 @@ describe('embark.Compiler', function() { readFile('test/contracts/simple_storage.sol'), readFile('test/contracts/token.sol') ], function(compiledContracts) { - assert.deepEqual(compiledContracts, expectedObject); + console.log(compiledContracts); + //assert.deepEqual(compiledContracts, expectedObject); done(); }); }); From 0dc21abd3c233323f52d17311d88862e2f0c249a Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sat, 25 Feb 2017 23:20:57 -0500 Subject: [PATCH 8/9] fix compiler argument --- lib/contracts/compiler.js | 1 - lib/contracts/solcW.js | 2 +- test/compiler.js | 3 +-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/contracts/compiler.js b/lib/contracts/compiler.js index 0069b008..4f9b1cc2 100644 --- a/lib/contracts/compiler.js +++ b/lib/contracts/compiler.js @@ -67,7 +67,6 @@ Compiler.prototype.compile_solidity = function(contractFiles, cb) { var filename = contractFiles[i].filename.replace('app/contracts/',''); input[filename] = contractFiles[i].content.toString(); } - console.log(input); callback(); }, function loadCompiler(callback) { diff --git a/lib/contracts/solcW.js b/lib/contracts/solcW.js index a5015c59..f31f122e 100644 --- a/lib/contracts/solcW.js +++ b/lib/contracts/solcW.js @@ -28,7 +28,7 @@ SolcW.prototype.compile = function(obj, optimize, done) { } done(msg.output); }); - solcProcess.send({action: 'compile', object: obj, optimize: optimize}); + solcProcess.send({action: 'compile', obj: obj, optimize: optimize}); }; module.exports = SolcW; diff --git a/test/compiler.js b/test/compiler.js index a7066d18..bf93ced1 100644 --- a/test/compiler.js +++ b/test/compiler.js @@ -23,8 +23,7 @@ describe('embark.Compiler', function() { readFile('test/contracts/simple_storage.sol'), readFile('test/contracts/token.sol') ], function(compiledContracts) { - console.log(compiledContracts); - //assert.deepEqual(compiledContracts, expectedObject); + assert.deepEqual(compiledContracts, expectedObject); done(); }); }); From dac6ca9fe62b7bda0b85ebd0b5590b84ef37f9d2 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sat, 25 Feb 2017 23:27:45 -0500 Subject: [PATCH 9/9] fix contract tests --- test/contracts.js | 144 +++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 71 deletions(-) diff --git a/test/contracts.js b/test/contracts.js index 056d46b9..873383a1 100644 --- a/test/contracts.js +++ b/test/contracts.js @@ -34,35 +34,36 @@ describe('embark.Contratcs', function() { }); describe('#build', function() { - it('generate contracts', function() { + it('generate contracts', function(done) { contractsManager.build(function(err, result) { if (err) { throw err; } + + var contracts = contractsManager.listContracts(); + assert.equal(contracts.length, 2); + + assert.equal(contracts[0].deploy, true); + assert.deepEqual(contracts[0].args, [100]); + assert.equal(contracts[0].className, "Token"); + assert.deepEqual(contracts[0].gas, 725000); + //assert.equal(contracts[0].gasPrice, []); // TODO: test this one + assert.equal(contracts[0].type, 'file'); + //assert.equal(contracts[0].abiDefinition, ''); + //assert.equal(contracts[0].code, ''); + //assert.equal(contracts[0].runtimeBytecode, ''); + + assert.equal(contracts[1].deploy, true); + assert.deepEqual(contracts[1].args, [200]); + assert.equal(contracts[1].className, "SimpleStorage"); + assert.deepEqual(contracts[1].gas, 725000); + //assert.equal(contracts[1].gasPrice, []); // TODO: test this one + assert.equal(contracts[1].type, 'file'); + //assert.equal(contracts[1].abiDefinition, ''); + //assert.equal(contracts[1].code, ''); + //assert.equal(contracts[1].runtimeBytecode, ''); + done(); }); - - var contracts = contractsManager.listContracts(); - assert.equal(contracts.length, 2); - - assert.equal(contracts[0].deploy, true); - assert.deepEqual(contracts[0].args, [100]); - assert.equal(contracts[0].className, "Token"); - assert.deepEqual(contracts[0].gas, 725000); - //assert.equal(contracts[0].gasPrice, []); // TODO: test this one - assert.equal(contracts[0].type, 'file'); - //assert.equal(contracts[0].abiDefinition, ''); - //assert.equal(contracts[0].code, ''); - //assert.equal(contracts[0].runtimeBytecode, ''); - - assert.equal(contracts[1].deploy, true); - assert.deepEqual(contracts[1].args, [200]); - assert.equal(contracts[1].className, "SimpleStorage"); - assert.deepEqual(contracts[1].gas, 725000); - //assert.equal(contracts[1].gasPrice, []); // TODO: test this one - assert.equal(contracts[1].type, 'file'); - //assert.equal(contracts[1].abiDefinition, ''); - //assert.equal(contracts[1].code, ''); - //assert.equal(contracts[1].runtimeBytecode, ''); }); }); }); @@ -102,58 +103,59 @@ describe('embark.Contratcs', function() { }); describe('#build', function() { - it('generate contracts', function() { + it('generate contracts', function(done) { contractsManager.build(function(err, result) { if (err) { throw err; } + + var contracts = contractsManager.listContracts(); + assert.equal(contracts.length, 4); + + assert.equal(contracts[0].className, "MySimpleStorage"); + assert.equal(contracts[1].className, "AnotherSimpleStorage"); + assert.equal(contracts[2].className, "SimpleStorage"); + assert.equal(contracts[3].className, "TokenStorage"); + + // TokenStorage + assert.equal(contracts[3].deploy, true); + assert.deepEqual(contracts[3].args, [100, '$SimpleStorage']); + assert.deepEqual(contracts[3].gas, 725000); + assert.equal(contracts[3].type, 'file'); + //assert.equal(contracts[3].abiDefinition, ''); + //assert.equal(contracts[3].code, ''); + //assert.equal(contracts[3].runtimeBytecode, ''); + + var parentContract = contracts[2]; + + //MySimpleStorage + assert.equal(contracts[0].deploy, true); + assert.deepEqual(contracts[0].args, [300]); + assert.deepEqual(contracts[0].gas, 725000); + assert.equal(contracts[0].type, 'instance'); + assert.equal(contracts[0].abiDefinition, parentContract.abiDefinition); + assert.equal(contracts[0].code, parentContract.code); + assert.equal(contracts[0].runtimeBytecode, parentContract.runtimeBytecode); + + // SimpleStorage + assert.equal(contracts[2].deploy, true); + assert.deepEqual(contracts[2].args, [200]); + assert.deepEqual(contracts[2].gas, 725000); + assert.equal(contracts[2].type, 'file'); + //assert.equal(contracts[2].abiDefinition, ''); + //assert.equal(contracts[2].code, ''); + //assert.equal(contracts[2].runtimeBytecode, ''); + + // AnotherSimpleStorage + assert.equal(contracts[1].deploy, true); + assert.deepEqual(contracts[1].args, [200]); + assert.deepEqual(contracts[1].gas, 725000); + assert.equal(contracts[1].type, 'instance'); + assert.equal(contracts[1].abiDefinition, parentContract.abiDefinition); + assert.equal(contracts[1].code, parentContract.code); + assert.equal(contracts[1].runtimeBytecode, parentContract.runtimeBytecode); + done(); }); - - var contracts = contractsManager.listContracts(); - assert.equal(contracts.length, 4); - - assert.equal(contracts[0].className, "MySimpleStorage"); - assert.equal(contracts[1].className, "AnotherSimpleStorage"); - assert.equal(contracts[2].className, "SimpleStorage"); - assert.equal(contracts[3].className, "TokenStorage"); - - // TokenStorage - assert.equal(contracts[3].deploy, true); - assert.deepEqual(contracts[3].args, [100, '$SimpleStorage']); - assert.deepEqual(contracts[3].gas, 725000); - assert.equal(contracts[3].type, 'file'); - //assert.equal(contracts[3].abiDefinition, ''); - //assert.equal(contracts[3].code, ''); - //assert.equal(contracts[3].runtimeBytecode, ''); - - var parentContract = contracts[2]; - - //MySimpleStorage - assert.equal(contracts[0].deploy, true); - assert.deepEqual(contracts[0].args, [300]); - assert.deepEqual(contracts[0].gas, 725000); - assert.equal(contracts[0].type, 'instance'); - assert.equal(contracts[0].abiDefinition, parentContract.abiDefinition); - assert.equal(contracts[0].code, parentContract.code); - assert.equal(contracts[0].runtimeBytecode, parentContract.runtimeBytecode); - - // SimpleStorage - assert.equal(contracts[2].deploy, true); - assert.deepEqual(contracts[2].args, [200]); - assert.deepEqual(contracts[2].gas, 725000); - assert.equal(contracts[2].type, 'file'); - //assert.equal(contracts[2].abiDefinition, ''); - //assert.equal(contracts[2].code, ''); - //assert.equal(contracts[2].runtimeBytecode, ''); - - // AnotherSimpleStorage - assert.equal(contracts[1].deploy, true); - assert.deepEqual(contracts[1].args, [200]); - assert.deepEqual(contracts[1].gas, 725000); - assert.equal(contracts[1].type, 'instance'); - assert.equal(contracts[1].abiDefinition, parentContract.abiDefinition); - assert.equal(contracts[1].code, parentContract.code); - assert.equal(contracts[1].runtimeBytecode, parentContract.runtimeBytecode); }); }); });