diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 213ac4fe..dc17da8b 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -3,6 +3,7 @@ const child_process = require('child_process'); const _ = require('underscore'); const fs = require('../../core/fs.js'); +const constants = require('../../constants.json'); const GethCommands = require('./geth_commands.js'); @@ -48,6 +49,8 @@ var Blockchain = function(options) { verbosity: this.blockchainConfig.verbosity }; + this.setupProxy(); + if (this.blockchainConfig === {} || JSON.stringify(this.blockchainConfig) === '{"enabled":true}') { this.config.account = {}; this.config.account.password = fs.embarkPath("templates/boilerplate/config/development/password"); @@ -72,6 +75,24 @@ var Blockchain = function(options) { this.client = new options.client({config: this.config, env: this.env, isDev: this.isDev}); }; +Blockchain.prototype.setupProxy = function() { + this.config.proxy = true; + if (this.blockchainConfig.proxy === false) { + this.config.proxy = false; + return; + } + + const proxy = require('../../core/proxy'); + const Ipc = require('../../core/ipc'); + + let ipcObject = new Ipc({ipcRole: 'client'}); + + proxy.serve(ipcObject, this.config.rpcHost, this.config.rpcPort, false); + proxy.serve(ipcObject, this.config.wsHost, this.config.wsPort, true); + this.config.rpcPort += constants.blockchain.servicePortOnProxy; + this.config.wsPort += constants.blockchain.servicePortOnProxy; +}; + Blockchain.prototype.runCommand = function(cmd, options, callback) { console.log(__("running: %s", cmd.underline).green); if (this.blockchainConfig.silent) { diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index a68b27e7..638020e3 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -1,4 +1,7 @@ let shelljs = require('shelljs'); +let proxy = require('../core/proxy'); +const Ipc = require('../core/ipc'); +const constants = require('../constants.json'); class Simulator { constructor(options) { @@ -17,8 +20,12 @@ class Simulator { process.exit(); } - cmds.push("-p " + (options.port || this.blockchainConfig.rpcPort || 8545)); - cmds.push("-h " + (options.host || this.blockchainConfig.rpcHost || 'localhost')); + let useProxy = this.blockchainConfig.proxy || false; + let host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); + let port = (options.port || this.blockchainConfig.rpcPort || 8545); + + cmds.push("-p " + (port + (useProxy ? constants.blockchain.servicePortOnProxy : 0))); + cmds.push("-h " + host); cmds.push("-a " + (options.numAccounts || 10)); cmds.push("-e " + (options.defaultBalance || 100)); cmds.push("-l " + (options.gasLimit || 8000000)); @@ -36,7 +43,14 @@ class Simulator { } const program = ganache ? 'ganache-cli' : 'testrpc'; + shelljs.exec(`${program} ${cmds.join(' ')}`, {async : true}); + + if(useProxy){ + let ipcObject = new Ipc({ipcRole: 'client'}); + proxy.serve(ipcObject, host, port, false); + } + } } diff --git a/lib/constants.json b/lib/constants.json index 0315ffbe..d8a0759b 100644 --- a/lib/constants.json +++ b/lib/constants.json @@ -35,7 +35,8 @@ "blockchain": { "blockchainReady": "blockchainReady", "init": "init", - "initiated": "initiated" + "initiated": "initiated", + "servicePortOnProxy": 10 }, "storage": { "init": "init", diff --git a/lib/core/engine.js b/lib/core/engine.js index 28640f0d..f0d8fb08 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -184,12 +184,17 @@ class Engine { }); this.ipc = new IPC({logger: this.logger, ipcRole: options.ipcRole}); + if (this.ipc.isServer()) { + this.ipc.serve(); + } + this.registerModule('solidity', {ipc: this.ipc}); this.registerModule('vyper'); this.registerModule('profiler'); this.registerModule('fuzzer'); this.registerModule('deploytracker'); this.registerModule('specialconfigs'); + this.registerModule('console_listener', {ipc: this.ipc}); const ContractsManager = require('../contracts/contracts.js'); this.contractsManager = new ContractsManager({ diff --git a/lib/core/proxy.js b/lib/core/proxy.js new file mode 100644 index 00000000..4a2a6bd4 --- /dev/null +++ b/lib/core/proxy.js @@ -0,0 +1,125 @@ +const httpProxy = require('http-proxy'); +const http = require('http'); +const constants = require('../constants.json'); + +let commList = {}; +let transactions = {}; +let receipts = {}; + +const parseRequest = function(reqBody){ + let jsonO; + try { + jsonO = JSON.parse(reqBody); + } catch(e){ + return; // Request is not a json. Do nothing + } + if(jsonO.method === "eth_sendTransaction"){ + commList[jsonO.id] = { + type: 'contract-log', + address: jsonO.params[0].to, + data: jsonO.params[0].data + }; + } else if(jsonO.method === "eth_getTransactionReceipt"){ + if(transactions[jsonO.params[0]]){ + transactions[jsonO.params[0]].receiptId = jsonO.id; + receipts[jsonO.id] = transactions[jsonO.params[0]].commListId; + } + } +}; + +const parseResponse = function(ipc, resBody){ + let jsonO; + try { + jsonO = JSON.parse(resBody); + } catch(e) { + return; // Response is not a json. Do nothing + } + + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = jsonO.result; + transactions[jsonO.result] = {commListId: jsonO.id}; + } else if(receipts[jsonO.id] && jsonO.result && jsonO.result.blockNumber){ + commList[receipts[jsonO.id]].blockNumber = jsonO.result.blockNumber; + commList[receipts[jsonO.id]].gasUsed = jsonO.result.gasUsed; + commList[receipts[jsonO.id]].status = jsonO.result.status; + + if(ipc.connected && !ipc.connecting){ + ipc.request('log', commList[receipts[jsonO.id]]); + } else { + ipc.connecting = true; + ipc.connect(() => { + ipc.connecting = false; + }); + } + + delete transactions[commList[receipts[jsonO.id]].transactionHash]; + delete receipts[jsonO.id]; + delete commList[jsonO.id]; + } +}; + +exports.serve = function(ipc, host, port, ws){ + let proxy = httpProxy.createProxyServer({ + target: { + host, + port: port + constants.blockchain.servicePortOnProxy + }, + ws: ws + }); + + proxy.on('error', function () { + console.log(__("Error forwarding requests to blockchain/simulator")); + process.exit(); + }); + + proxy.on('proxyRes', (proxyRes) => { + let resBody = []; + proxyRes.on('data', (b) => resBody.push(b)); + proxyRes.on('end', function () { + resBody = Buffer.concat(resBody).toString(); + if(resBody){ + parseResponse(ipc, resBody); + } + }); + }); + + let server = http.createServer((req, res) => { + let reqBody = []; + req.on('data', (b) => { reqBody.push(b); }) + .on('end', () => { + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + parseRequest(reqBody); + } + }); + + if(!ws){ + proxy.web(req, res); + } + }); + + if(ws){ + const WsParser = require('simples/lib/parsers/ws'); // npm install simples + + server.on('upgrade', function (req, socket, head) { + proxy.ws(req, socket, head); + }); + + proxy.on('open', (proxySocket) => { + proxySocket.on('data', (data) => { + parseResponse(ipc, data.toString().substr(data.indexOf("{"))); + }); + }); + + proxy.on('proxyReqWs', (proxyReq, req, socket) => { + var parser = new WsParser(0, false); + socket.pipe(parser); + parser.on('frame', function (frame) { + parseRequest(frame.data); + }); + + }); + } + + server.listen(port); +}; diff --git a/lib/index.js b/lib/index.js index 338ee7fc..9cac7e81 100644 --- a/lib/index.js +++ b/lib/index.js @@ -51,7 +51,10 @@ class Embark { simulator(options) { this.context = options.context || [constants.contexts.simulator, constants.contexts.blockchain]; let Simulator = require('./cmds/simulator.js'); - let simulator = new Simulator({blockchainConfig: this.config.blockchainConfig, logger: this.logger}); + let simulator = new Simulator({ + blockchainConfig: this.config.blockchainConfig, + logger: this.logger + }); simulator.run(options); } diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js new file mode 100644 index 00000000..210b6ae2 --- /dev/null +++ b/lib/modules/console_listener/index.js @@ -0,0 +1,92 @@ +const utils = require('../../utils/utils.js'); + +class ConsoleListener { + constructor(embark, options) { + this.logger = embark.logger; + this.ipc = options.ipc; + this.events = embark.events; + this.addressToContract = []; + this.contractsConfig = embark.config.contractsConfig; + this.contractsDeployed = false; + this._listenForLogRequests(); + + this.events.on("contractsDeployed", () => { + this.contractsDeployed = true; + this._updateContractList(); + }); + } + + _updateContractList(){ + this.events.request("contracts:list", (_err, contractsList) => { + if(_err) { + this.logger.error(__("no contracts found")); + return; + } + contractsList.forEach(contract => { + if(!contract.deployedAddress) return; + + let address = contract.deployedAddress.toLowerCase(); + if(!this.addressToContract[address]){ + let funcSignatures = {}; + contract.abiDefinition + .filter(func => func.type == "function") + .map(func => { + const name = func.name + + '(' + + (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + + ')'; + funcSignatures[utils.sha3(name).substring(0, 10)] = { + name, + abi: func, + functionName: func.name + }; + }); + + this.addressToContract[address] = { + name: contract.className, + functions: funcSignatures + }; + } + }); + }); + } + + _listenForLogRequests(){ + if(this.ipc.ipcRole !== 'server') return; + this.ipc.on('log', (request) => { + if(request.type == 'contract-log'){ + if(!this.contractsDeployed) return; + + let {address, data, transactionHash, blockNumber, gasUsed, status} = request; + if(!this.addressToContract[address]){ + this._updateContractList(); + } + if(!this.addressToContract[address]) return; + + + const name = this.addressToContract[address].name; + const func = this.addressToContract[address].functions[data.substring(0, 10)]; + const functionName = func.functionName; + + const decodedParameters = utils.decodeParams(func.abi.inputs, data.substring(10)); + let paramString = ""; + if(func.abi.inputs){ + func.abi.inputs.forEach((input) => { + let quote = input.type.indexOf("int") == -1 ? '"' : ''; + paramString += quote + decodedParameters[input.name] + quote + ", "; + }); + paramString = paramString.substring(0, paramString.length - 2); + } + + gasUsed = utils.hexToNumber(gasUsed); + blockNumber = utils.hexToNumber(blockNumber); + + this.logger.info(`Blockchain>`.underline + ` ${name}.${functionName}(${paramString})`.bold + ` | ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); + } else { + this.logger.info(JSON.stringify(request)); + } + }); + } +} + +module.exports = ConsoleListener; diff --git a/lib/modules/solidity/solcW.js b/lib/modules/solidity/solcW.js index 510ef98f..4dff3f67 100644 --- a/lib/modules/solidity/solcW.js +++ b/lib/modules/solidity/solcW.js @@ -47,7 +47,6 @@ class SolcW { }); if (this.ipc.isServer()) { - this.ipc.serve(); this.ipc.on('compile', self.compile.bind(this)); } diff --git a/lib/utils/utils.js b/lib/utils/utils.js index 6d92422f..3a0a9020 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -7,6 +7,7 @@ let shelljs = require('shelljs'); var tar = require('tar'); var propose = require('propose'); var Web3 = require('web3'); +var Web3EthAbi = require('web3-eth-abi'); const constants = require('../constants'); //let fs = require('../core/fs.js'); @@ -185,6 +186,14 @@ function getExternalContractUrl(file) { }; } +function hexToNumber(hex){ + return Web3.utils.hexToNumber(hex); +} + +function decodeParams(typesArray, hexString){ + return Web3EthAbi.decodeParameters(typesArray, hexString); +} + function toChecksumAddress(address) { return Web3.utils.toChecksumAddress(address); } @@ -253,6 +262,8 @@ module.exports = { httpsGet: httpsGet, httpGetJson: httpGetJson, httpsGetJson: httpsGetJson, + hexToNumber: hexToNumber, + decodeParams: decodeParams, runCmd: runCmd, cd: cd, sed: sed, diff --git a/package-lock.json b/package-lock.json index 2595336b..a04637a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.2.tgz", "integrity": "sha512-Q3FWsbdmkQd1ib11A4XNWQvRD//5KpPoGawA8aB2DR7pWKoW9XQv3+dGxD/Z1eVFze23Okdo27ZQytVFlweKvQ==", "requires": { - "@types/node": "10.1.4" + "@types/node": "10.3.1" } }, "@types/lockfile": { @@ -59,16 +59,16 @@ "integrity": "sha512-pD6JuijPmrfi84qF3/TzGQ7zi0QIX+d7ZdetD6jUA6cp+IsCzAquXZfi5viesew+pfpOTIdAVKuh1SHA7KeKzg==" }, "@types/node": { - "version": "10.1.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.1.4.tgz", - "integrity": "sha512-GpQxofkdlHYxjHad98UUdNoMO7JrmzQZoAaghtNg14Gwg7YkohcrCoJEcEMSgllx4VIZ+mYw7ZHjfaeIagP/rg==" + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.3.1.tgz", + "integrity": "sha512-IsX9aDHDzJohkm3VCDB8tkzl5RQ34E/PFA29TQk6uDGb7Oc869ZBtmdKVDBzY3+h9GnXB8ssrRXEPVZrlIOPOw==" }, "@types/node-fetch": { "version": "1.6.9", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-1.6.9.tgz", "integrity": "sha512-n2r6WLoY7+uuPT7pnEtKJCmPUGyJ+cbyBR8Avnu4+m1nzz7DwBVuyIvvlBzCZ/nrpC7rIgb3D6pNavL7rFEa9g==", "requires": { - "@types/node": "10.1.4" + "@types/node": "10.3.1" } }, "@types/semver": { @@ -81,7 +81,7 @@ "resolved": "https://registry.npmjs.org/@types/tar/-/tar-4.0.0.tgz", "integrity": "sha512-YybbEHNngcHlIWVCYsoj7Oo1JU9JqONuAlt1LlTH/lmL8BMhbzdFUgReY87a05rY1j8mfK47Del+TCkaLAXwLw==", "requires": { - "@types/node": "10.1.4" + "@types/node": "10.3.1" } }, "@types/url-join": { @@ -1913,6 +1913,11 @@ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, + "bufferhelper": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bufferhelper/-/bufferhelper-0.2.0.tgz", + "integrity": "sha1-7C842SU4dpzqKQFIeTXp4h2Bc7M=" + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -2842,6 +2847,11 @@ "source-map": "0.5.7" } }, + "ctype": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", + "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=" + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -5745,6 +5755,23 @@ "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "requires": { + "eventemitter3": "3.1.0", + "follow-redirects": "1.4.1", + "requires-port": "1.0.0" + }, + "dependencies": { + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==" + } + } + }, "http-shutdown": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-shutdown/-/http-shutdown-1.2.0.tgz", @@ -8355,6 +8382,214 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.4.tgz", "integrity": "sha512-8Df0906+tq/omxuCZD6PqhPaQDYuyJ1d+VITgxoIA8zvQd1ru+nMJcDChHH324MWitIgbVkAkQoGEEVJNpn/PA==" }, + "node-http-proxy": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/node-http-proxy/-/node-http-proxy-0.2.3.tgz", + "integrity": "sha1-ZFv8yESYGkEnBz//Php2ff50NLc=", + "requires": { + "bufferhelper": "0.2.0", + "commander": "2.6.0", + "pm": "2.2.5", + "request": "2.51.0" + }, + "dependencies": { + "asn1": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", + "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=" + }, + "assert-plus": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=" + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "aws-sign2": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", + "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=" + }, + "bl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", + "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", + "requires": { + "readable-stream": "1.0.34" + } + }, + "boom": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", + "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", + "requires": { + "hoek": "0.9.1" + } + }, + "caseless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.8.0.tgz", + "integrity": "sha1-W8oogdQUN/VLJAfr40iIx7mtT30=" + }, + "combined-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", + "requires": { + "delayed-stream": "0.0.5" + } + }, + "commander": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", + "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=" + }, + "cryptiles": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", + "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", + "requires": { + "boom": "0.4.2" + } + }, + "delayed-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", + "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=" + }, + "forever-agent": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", + "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=" + }, + "form-data": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", + "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=", + "requires": { + "async": "0.9.2", + "combined-stream": "0.0.7", + "mime-types": "2.0.14" + }, + "dependencies": { + "mime-types": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", + "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", + "requires": { + "mime-db": "1.12.0" + } + } + } + }, + "hawk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", + "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", + "requires": { + "boom": "0.4.2", + "cryptiles": "0.2.2", + "hoek": "0.9.1", + "sntp": "0.2.4" + } + }, + "hoek": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" + }, + "http-signature": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", + "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", + "requires": { + "asn1": "0.1.11", + "assert-plus": "0.1.5", + "ctype": "0.5.3" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "mime-db": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", + "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=" + }, + "mime-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", + "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" + }, + "oauth-sign": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.5.0.tgz", + "integrity": "sha1-12f1FpMlYg6rLgh+8MRy53PbZGE=" + }, + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "request": { + "version": "2.51.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.51.0.tgz", + "integrity": "sha1-NdALvswBLlX5B7G9ng29V3v+8m4=", + "requires": { + "aws-sign2": "0.5.0", + "bl": "0.9.5", + "caseless": "0.8.0", + "combined-stream": "0.0.7", + "forever-agent": "0.5.2", + "form-data": "0.2.0", + "hawk": "1.1.1", + "http-signature": "0.10.1", + "json-stringify-safe": "5.0.1", + "mime-types": "1.0.2", + "node-uuid": "1.4.8", + "oauth-sign": "0.5.0", + "qs": "2.3.3", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.4.3" + } + }, + "sntp": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", + "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", + "requires": { + "hoek": "0.9.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + } + } + }, "node-ipc": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.1.tgz", @@ -8465,6 +8700,11 @@ } } }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, "nodeify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nodeify/-/nodeify-1.0.1.tgz", @@ -9144,6 +9384,11 @@ "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, + "pm": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/pm/-/pm-2.2.5.tgz", + "integrity": "sha1-IgJZn1m/trOID6naI0rdL0NLYK8=" + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -10231,6 +10476,11 @@ "resolve-from": "1.0.1" } }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "resolve": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", diff --git a/package.json b/package.json index cd660c0a..363d1f06 100644 --- a/package.json +++ b/package.json @@ -49,11 +49,13 @@ "ganache-cli": "^6.1.0", "globule": "^1.1.0", "hard-source-webpack-plugin": "^0.6.6", + "http-proxy": "^1.17.0", "http-shutdown": "^1.2.0", "i18n": "^0.8.3", "ipfs-api": "17.2.4", "live-plugin-manager": "https://github.com/iurimatias/live-plugin-manager.git", "merge": "^1.2.0", + "node-http-proxy": "^0.2.3", "node-ipc": "^9.1.1", "os-locale": "^2.1.0", "p-iteration": "^1.1.7", @@ -63,6 +65,7 @@ "request": "^2.85.0", "serve-static": "^1.11.1", "shelljs": "^0.5.0", + "simples": "^0.8.8", "solc": "0.4.24", "string-replace-async": "^1.2.1", "style-loader": "^0.19.0", diff --git a/templates/boilerplate/config/blockchain.json b/templates/boilerplate/config/blockchain.json index b72f107a..f80d68c6 100644 --- a/templates/boilerplate/config/blockchain.json +++ b/templates/boilerplate/config/blockchain.json @@ -12,6 +12,7 @@ "rpcHost": "localhost", "rpcPort": 8545, "rpcCorsDomain": "auto", + "proxy": true, "account": { "password": "config/development/password" }, diff --git a/templates/demo/config/blockchain.json b/templates/demo/config/blockchain.json index 8e299188..9b7162c0 100644 --- a/templates/demo/config/blockchain.json +++ b/templates/demo/config/blockchain.json @@ -12,6 +12,7 @@ "rpcHost": "localhost", "rpcPort": 8545, "rpcCorsDomain": "auto", + "proxy": true, "account": { "password": "config/development/password" }, diff --git a/test/blockchain.js b/test/blockchain.js index e9dfc40d..4590236b 100644 --- a/test/blockchain.js +++ b/test/blockchain.js @@ -1,5 +1,6 @@ /*globals describe, it*/ const Blockchain = require('../lib/cmds/blockchain/blockchain'); +const constants = require('../lib/constants.json'); const assert = require('assert'); @@ -39,10 +40,15 @@ describe('embark.Blockchain', function () { targetGasLimit: false, fast: false, light: false, - verbosity: undefined + verbosity: undefined, + proxy: true }; let blockchain = new Blockchain(config, 'geth'); + if(config.proxy){ + config.wsPort += constants.blockchain.servicePortOnProxy; + config.rpcPort += constants.blockchain.servicePortOnProxy; + } assert.deepEqual(blockchain.config, config); done(); }); @@ -77,10 +83,16 @@ describe('embark.Blockchain', function () { targetGasLimit: false, fast: false, light: false, - verbosity: undefined + verbosity: undefined, + proxy: true }; let blockchain = new Blockchain(config, 'geth'); + if(config.proxy){ + config.wsPort += constants.blockchain.servicePortOnProxy; + config.rpcPort += constants.blockchain.servicePortOnProxy; + } + assert.deepEqual(blockchain.config, config); done(); }); diff --git a/test_apps/test_app/config/blockchain.json b/test_apps/test_app/config/blockchain.json index d86d2c76..5835745d 100644 --- a/test_apps/test_app/config/blockchain.json +++ b/test_apps/test_app/config/blockchain.json @@ -19,8 +19,8 @@ "wsOrigins": "auto", "wsRPC": true, "wsHost": "localhost", - "wsPort": 8546 - + "wsPort": 8546, + "proxy": true }, "testnet": { "networkType": "testnet",