From c571e0d492183d874b1cdc250c44d7a0b491de68 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Thu, 7 Jun 2018 12:50:22 -0400 Subject: [PATCH 01/52] Adding proxy for simulator --- lib/cmds/simulator.js | 63 +++++++++++++++++++++++++++++++++++++++++-- lib/index.js | 7 ++++- package.json | 2 ++ 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index a68b27e7..d3d5a4c5 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -4,6 +4,8 @@ class Simulator { constructor(options) { this.blockchainConfig = options.blockchainConfig; this.logger = options.logger; + this.contractsConfig = options.contractsConfig; + this.events = options.events; } run(options) { @@ -17,7 +19,9 @@ class Simulator { process.exit(); } - cmds.push("-p " + (options.port || this.blockchainConfig.rpcPort || 8545)); + cmds.push("-p " + ((options.port || this.blockchainConfig.rpcPort || 8545) + 1)); + + cmds.push("-h " + (options.host || this.blockchainConfig.rpcHost || 'localhost')); cmds.push("-a " + (options.numAccounts || 10)); cmds.push("-e " + (options.defaultBalance || 100)); @@ -36,7 +40,62 @@ class Simulator { } const program = ganache ? 'ganache-cli' : 'testrpc'; - shelljs.exec(`${program} ${cmds.join(' ')}`, {async : true}); + + shelljs.exec(`${program} ${cmds.join(' ')} &`, {async : true}); + + let httpProxy = require('http-proxy'); + let http = require('http'); + let _port = options.port || this.blockchainConfig.rpcPort || 8545; + let _host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); + + let commList = {}; + + let proxy = httpProxy.createProxyServer({}); + let server = http.createServer((req, res) => { + + let reqBody = []; + req.on('data', (b) => { reqBody.push(b); }) + .on('end', () => { + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + let jsonO = JSON.parse(reqBody); + if(jsonO.method == "eth_sendTransaction"){ + commList[jsonO.id] = { + requestData: jsonO.params.data + }; + } + } + }); + + proxy.proxyRequest(req, res, { + target: `http://${_host}:${_port + 1}` + }); + + proxy.on('proxyRes', function (proxyRes, req, res) { + let resBody = []; + proxyRes.on('data', (b) => resBody.push(b)) + proxyRes.on('end', function () { + resBody = Buffer.concat(resBody).toString(); + try { + let jsonO = JSON.parse(resBody); + if(commList[jsonO.id]){ + commList[json0.id].transactionHash = resBody; + + // TODO: decode commlist + // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” + + delete commList[json0.id]; + } + } catch(e){ + // + } + }); + }); + + }); + + server.listen(_port); + } } diff --git a/lib/index.js b/lib/index.js index bc5410df..bb71aed1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -51,7 +51,12 @@ 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({ + contractsConfig: this.config.contractsConfig, + blockchainConfig: this.config.blockchainConfig, + logger: this.logger, + events: this.events + }); simulator.run(options); } diff --git a/package.json b/package.json index cd660c0a..57abdf87 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", From f84970f824ed6048176429423a3c69b078199c89 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Thu, 7 Jun 2018 13:03:04 -0400 Subject: [PATCH 02/52] Extracted proxy to its own file --- lib/cmds/proxy.js | 52 +++++++++++++++++++++++++++++++++ lib/cmds/simulator.js | 67 ++++++------------------------------------- 2 files changed, 60 insertions(+), 59 deletions(-) create mode 100644 lib/cmds/proxy.js diff --git a/lib/cmds/proxy.js b/lib/cmds/proxy.js new file mode 100644 index 00000000..2e52645c --- /dev/null +++ b/lib/cmds/proxy.js @@ -0,0 +1,52 @@ +const httpProxy = require('http-proxy'); +const http = require('http'); + +exports.serve = function(host, port){ + let commList = {}; + + let proxy = httpProxy.createProxyServer({}); + let server = http.createServer((req, res) => { + + let reqBody = []; + req.on('data', (b) => { reqBody.push(b); }) + .on('end', () => { + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + let jsonO = JSON.parse(reqBody); + if(jsonO.method == "eth_sendTransaction"){ + commList[jsonO.id] = { + requestData: jsonO.params.data + }; + } + } + }); + + proxy.proxyRequest(req, res, { + target: `http://${host}:${port + 1}` + }); + + proxy.on('proxyRes', (proxyRes, req, res) => { + let resBody = []; + proxyRes.on('data', (b) => resBody.push(b)) + proxyRes.on('end', function () { + resBody = Buffer.concat(resBody).toString(); + try { + let jsonO = JSON.parse(resBody); + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = resBody; + + // TODO: decode commlist + // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” + + delete commList[jsonO.id]; + } + } catch(e){ + // + } + }); + }); + + }); + + server.listen(port); +} diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index d3d5a4c5..ddfb18cb 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -1,5 +1,5 @@ let shelljs = require('shelljs'); - +let proxy = require('./proxy'); class Simulator { constructor(options) { this.blockchainConfig = options.blockchainConfig; @@ -19,10 +19,11 @@ class Simulator { process.exit(); } - cmds.push("-p " + ((options.port || this.blockchainConfig.rpcPort || 8545) + 1)); - - - cmds.push("-h " + (options.host || this.blockchainConfig.rpcHost || 'localhost')); + let host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); + let port = (options.port || this.blockchainConfig.rpcPort || 8545); + + cmds.push("-p " + (port + 1)); + cmds.push("-h " + host); cmds.push("-a " + (options.numAccounts || 10)); cmds.push("-e " + (options.defaultBalance || 100)); cmds.push("-l " + (options.gasLimit || 8000000)); @@ -41,61 +42,9 @@ class Simulator { const program = ganache ? 'ganache-cli' : 'testrpc'; - shelljs.exec(`${program} ${cmds.join(' ')} &`, {async : true}); + shelljs.exec(`${program} ${cmds.join(' ')} &`, {async : true}); - let httpProxy = require('http-proxy'); - let http = require('http'); - let _port = options.port || this.blockchainConfig.rpcPort || 8545; - let _host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); - - let commList = {}; - - let proxy = httpProxy.createProxyServer({}); - let server = http.createServer((req, res) => { - - let reqBody = []; - req.on('data', (b) => { reqBody.push(b); }) - .on('end', () => { - reqBody = Buffer.concat(reqBody).toString(); - if(reqBody){ - let jsonO = JSON.parse(reqBody); - if(jsonO.method == "eth_sendTransaction"){ - commList[jsonO.id] = { - requestData: jsonO.params.data - }; - } - } - }); - - proxy.proxyRequest(req, res, { - target: `http://${_host}:${_port + 1}` - }); - - proxy.on('proxyRes', function (proxyRes, req, res) { - let resBody = []; - proxyRes.on('data', (b) => resBody.push(b)) - proxyRes.on('end', function () { - resBody = Buffer.concat(resBody).toString(); - try { - let jsonO = JSON.parse(resBody); - if(commList[jsonO.id]){ - commList[json0.id].transactionHash = resBody; - - // TODO: decode commlist - // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” - - delete commList[json0.id]; - } - } catch(e){ - // - } - }); - }); - - }); - - server.listen(_port); - + proxy.serve(host, port); } } From b4934c7b1645d42d9a1b1907f3d6833da48e6d1a Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Thu, 7 Jun 2018 15:13:35 -0400 Subject: [PATCH 03/52] Added proxy to blockchain --- lib/cmds/blockchain/blockchain.js | 14 +++++++++- lib/cmds/proxy.js | 44 +++++++++++++++++-------------- lib/cmds/simulator.js | 17 ++++++------ lib/index.js | 4 +-- 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 213ac4fe..b1e75a5f 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -45,9 +45,11 @@ var Blockchain = function(options) { targetGasLimit: this.blockchainConfig.targetGasLimit || false, light: this.blockchainConfig.light || false, fast: this.blockchainConfig.fast || false, - verbosity: this.blockchainConfig.verbosity + 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 +74,16 @@ var Blockchain = function(options) { this.client = new options.client({config: this.config, env: this.env, isDev: this.isDev}); }; +Blockchain.prototype.setupProxy = function(){ + if(this.blockchainConfig.proxy){ + const proxy = require('../proxy'); + proxy.serve(this.config.rpcHost, this.config.rpcPort, false); + proxy.serve(this.config.wsHost, this.config.wsPort, true); + this.config.rpcPort += 10; + this.config.wsPort += 10; + } +} + Blockchain.prototype.runCommand = function(cmd, options, callback) { console.log(__("running: %s", cmd.underline).green); if (this.blockchainConfig.silent) { diff --git a/lib/cmds/proxy.js b/lib/cmds/proxy.js index 2e52645c..0f809fb1 100644 --- a/lib/cmds/proxy.js +++ b/lib/cmds/proxy.js @@ -1,7 +1,7 @@ const httpProxy = require('http-proxy'); const http = require('http'); -exports.serve = function(host, port){ +exports.serve = function(host, port, ws){ let commList = {}; let proxy = httpProxy.createProxyServer({}); @@ -10,19 +10,24 @@ exports.serve = function(host, port){ let reqBody = []; req.on('data', (b) => { reqBody.push(b); }) .on('end', () => { - reqBody = Buffer.concat(reqBody).toString(); - if(reqBody){ - let jsonO = JSON.parse(reqBody); - if(jsonO.method == "eth_sendTransaction"){ - commList[jsonO.id] = { - requestData: jsonO.params.data - }; + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + let jsonO = JSON.parse(reqBody); + if(jsonO.method == "eth_sendTransaction"){ + commList[jsonO.id] = { + address: jsonO.params[0].to, + requestData: jsonO.params[0].data + }; + } } - } }); proxy.proxyRequest(req, res, { - target: `http://${host}:${port + 1}` + target: { + host: host, + port: port + 10, + ws: ws + } }); proxy.on('proxyRes', (proxyRes, req, res) => { @@ -31,15 +36,14 @@ exports.serve = function(host, port){ proxyRes.on('end', function () { resBody = Buffer.concat(resBody).toString(); try { - let jsonO = JSON.parse(resBody); - if(commList[jsonO.id]){ - commList[jsonO.id].transactionHash = resBody; - - // TODO: decode commlist - // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” - - delete commList[jsonO.id]; - } + let jsonO = JSON.parse(resBody); + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = jsonO.result; + // TODO: decode commlist + // TODO: send messages to console + // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” + delete commList[jsonO.id]; + } } catch(e){ // } @@ -49,4 +53,4 @@ exports.serve = function(host, port){ }); server.listen(port); -} +}; diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index ddfb18cb..c319e842 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -4,12 +4,9 @@ class Simulator { constructor(options) { this.blockchainConfig = options.blockchainConfig; this.logger = options.logger; - this.contractsConfig = options.contractsConfig; - this.events = options.events; } - run(options) { - let cmds = []; + run(options) { let cmds = []; const testrpc = shelljs.which('testrpc'); const ganache = shelljs.which('ganache-cli'); @@ -19,10 +16,11 @@ class Simulator { process.exit(); } + 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 + 1)); + cmds.push("-p " + (port + (useProxy ? 10 : 0))); cmds.push("-h " + host); cmds.push("-a " + (options.numAccounts || 10)); cmds.push("-e " + (options.defaultBalance || 100)); @@ -42,9 +40,12 @@ class Simulator { const program = ganache ? 'ganache-cli' : 'testrpc'; - shelljs.exec(`${program} ${cmds.join(' ')} &`, {async : true}); - - proxy.serve(host, port); + shelljs.exec(`${program} ${cmds.join(' ')}`, {async : true}); + + if(useProxy){ + proxy.serve(host, port); + } + } } diff --git a/lib/index.js b/lib/index.js index bb71aed1..ae2a5b2f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -52,10 +52,8 @@ class Embark { this.context = options.context || [constants.contexts.simulator, constants.contexts.blockchain]; let Simulator = require('./cmds/simulator.js'); let simulator = new Simulator({ - contractsConfig: this.config.contractsConfig, blockchainConfig: this.config.blockchainConfig, - logger: this.logger, - events: this.events + logger: this.logger }); simulator.run(options); } From 586e7c7bbc50b2100f937290473f6779afc001e4 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 11:05:51 -0400 Subject: [PATCH 04/52] Moved proxy to core libraries, and logging on console methods invoked --- lib/cmds/blockchain/blockchain.js | 14 +- lib/cmds/proxy.js | 56 ----- lib/cmds/simulator.js | 7 +- lib/core/engine.js | 39 +++ lib/core/proxy.js | 66 +++++ lib/modules/solidity/solcW.js | 1 - package-lock.json | 399 +++++++++++++++++++++++++++++- 7 files changed, 510 insertions(+), 72 deletions(-) delete mode 100644 lib/cmds/proxy.js create mode 100644 lib/core/proxy.js diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index b1e75a5f..3bab4daa 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -76,13 +76,17 @@ var Blockchain = function(options) { Blockchain.prototype.setupProxy = function(){ if(this.blockchainConfig.proxy){ - const proxy = require('../proxy'); - proxy.serve(this.config.rpcHost, this.config.rpcPort, false); - proxy.serve(this.config.wsHost, this.config.wsPort, true); + 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 += 10; - this.config.wsPort += 10; + //this.config.wsPort += 10; } -} +}; Blockchain.prototype.runCommand = function(cmd, options, callback) { console.log(__("running: %s", cmd.underline).green); diff --git a/lib/cmds/proxy.js b/lib/cmds/proxy.js deleted file mode 100644 index 0f809fb1..00000000 --- a/lib/cmds/proxy.js +++ /dev/null @@ -1,56 +0,0 @@ -const httpProxy = require('http-proxy'); -const http = require('http'); - -exports.serve = function(host, port, ws){ - let commList = {}; - - let proxy = httpProxy.createProxyServer({}); - let server = http.createServer((req, res) => { - - let reqBody = []; - req.on('data', (b) => { reqBody.push(b); }) - .on('end', () => { - reqBody = Buffer.concat(reqBody).toString(); - if(reqBody){ - let jsonO = JSON.parse(reqBody); - if(jsonO.method == "eth_sendTransaction"){ - commList[jsonO.id] = { - address: jsonO.params[0].to, - requestData: jsonO.params[0].data - }; - } - } - }); - - proxy.proxyRequest(req, res, { - target: { - host: host, - port: port + 10, - ws: ws - } - }); - - proxy.on('proxyRes', (proxyRes, req, res) => { - let resBody = []; - proxyRes.on('data', (b) => resBody.push(b)) - proxyRes.on('end', function () { - resBody = Buffer.concat(resBody).toString(); - try { - let jsonO = JSON.parse(resBody); - if(commList[jsonO.id]){ - commList[jsonO.id].transactionHash = jsonO.result; - // TODO: decode commlist - // TODO: send messages to console - // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” - delete commList[jsonO.id]; - } - } catch(e){ - // - } - }); - }); - - }); - - server.listen(port); -}; diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index c319e842..da819246 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -1,5 +1,7 @@ let shelljs = require('shelljs'); -let proxy = require('./proxy'); +let proxy = require('../core/proxy'); +const Ipc = require('../core/ipc'); + class Simulator { constructor(options) { this.blockchainConfig = options.blockchainConfig; @@ -43,7 +45,8 @@ class Simulator { shelljs.exec(`${program} ${cmds.join(' ')}`, {async : true}); if(useProxy){ - proxy.serve(host, port); + let ipcObject = new Ipc({ipcRole: 'client'}); + proxy.serve(ipcObject, host, port, false); } } diff --git a/lib/core/engine.js b/lib/core/engine.js index cfd6fdf2..7ebb843e 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -184,6 +184,11 @@ 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'); @@ -219,6 +224,40 @@ class Engine { plugins: this.plugins }); + // Console logger + // TODO: extract to its own file + let addressToContract = {}; + this.ipc.on('log', (jsonObj) => { + if(jsonObj.type == 'contract-log'){ + if(!addressToContract[jsonObj.address]){ + let contractList = Object.keys(this.config.contractsConfig.contracts); + for(let i = 0; i < contractList.length; i++){ + let cont = this.config.contractsConfig.contracts[contractList[i]]; + if(!addressToContract[cont.deployedAddress.toLowerCase()]){ + let funcSignatures = {}; + cont.abiDefinition + .filter(func => func.type == "function") + .map(func => func.name + '(' + + (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + + ')') + .forEach(func => { + funcSignatures[utils.sha3(func).substring(0, 10)] = func; + }); + + addressToContract[cont.deployedAddress.toLowerCase()] = { + name: contractList[i], + functions: funcSignatures + }; + } + } + } + let funcHash = addressToContract[jsonObj.address].functions[jsonObj.data.substring(0, 10)]; + this.logger.debug(addressToContract[jsonObj.address].name + "." + funcHash + " : " + jsonObj.transactionHash); + } else { + this.logger.info(jsonObj); + } + }); + this.events.on('file-event', function (fileType) { clearTimeout(self.fileTimeout); self.fileTimeout = setTimeout(() => { diff --git a/lib/core/proxy.js b/lib/core/proxy.js new file mode 100644 index 00000000..4e975d16 --- /dev/null +++ b/lib/core/proxy.js @@ -0,0 +1,66 @@ +const httpProxy = require('http-proxy'); +const http = require('http'); + +exports.serve = function(ipc, host, port, ws){ + let commList = {}; + + let proxy = httpProxy.createProxyServer({ + target: { + host: host, + port: port + 10, + ws: ws + } + }); + + proxy.on('proxyRes', (proxyRes) => { + let resBody = []; + proxyRes.on('data', (b) => resBody.push(b)); + proxyRes.on('end', function () { + resBody = Buffer.concat(resBody).toString(); + try { + let jsonO = JSON.parse(resBody); + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = jsonO.result; + if(ipc.connected && !ipc.connecting){ + ipc.request('log', commList[jsonO.id]); + } else { + ipc.connecting = true; + ipc.connect((err) => { + ipc.connecting = false; + }); + } + delete commList[jsonO.id]; + } + } catch(e){ + // + } + }); + }); + + let server = http.createServer((req, res) => { + let reqBody = []; + req.on('data', (b) => { reqBody.push(b); }) + .on('end', () => { + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + let jsonO = JSON.parse(reqBody); + if(jsonO.method == "eth_sendTransaction"){ + commList[jsonO.id] = { + type: 'contract-log', + address: jsonO.params[0].to, + data: jsonO.params[0].data + }; + } + } + }); + + if(ws){ + proxy.ws(req, res); + } else { + proxy.web(req, res); + } + + }); + + server.listen(port); +}; 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/package-lock.json b/package-lock.json index 21d95370..88dfbfaf 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", @@ -3219,6 +3229,11 @@ "typechecker": "2.1.0" } }, + "easy-stack": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz", + "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=" + }, "ecc-jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", @@ -4102,6 +4117,11 @@ "es5-ext": "0.10.42" } }, + "event-pubsub": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", + "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==" + }, "eventemitter2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", @@ -5735,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", @@ -6500,6 +6537,19 @@ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz", "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==" }, + "js-message": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz", + "integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=" + }, + "js-queue": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.0.tgz", + "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=", + "requires": { + "easy-stack": "1.0.0" + } + }, "js-sha3": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz", @@ -8332,6 +8382,224 @@ "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", + "integrity": "sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w==", + "requires": { + "event-pubsub": "4.3.0", + "js-message": "1.0.5", + "js-queue": "2.0.0" + } + }, "node-libs-browser": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", @@ -8432,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", @@ -9111,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", @@ -10198,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", @@ -13020,8 +13303,10 @@ "p-each-series": "1.0.0", "p-lazy": "1.0.0", "prettier": "1.13.4", + "supports-color": "5.4.0", "v8-compile-cache": "2.0.0", "webpack-addons": "1.1.5", + "yargs": "11.1.0", "yeoman-environment": "2.2.0", "yeoman-generator": "2.0.5" }, @@ -13050,7 +13335,8 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5" + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" } }, "cliui": { @@ -13059,6 +13345,7 @@ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "requires": { "string-width": "2.1.1", + "strip-ansi": "4.0.0", "wrap-ansi": "2.1.0" } }, @@ -13085,7 +13372,8 @@ "integrity": "sha512-jox/62b2GofV1qTUQTMPEJSDIGycS43evqYzD/KVtEb9OCoki9cnacUPxCrZa7JfPzZSYOCZhu9O9luaMxAX8g==", "requires": { "graceful-fs": "4.1.11", - "memory-fs": "0.4.1" + "memory-fs": "0.4.1", + "tapable": "1.0.0" } }, "got": { @@ -13108,6 +13396,7 @@ "pify": "3.0.0", "safe-buffer": "5.1.1", "timed-out": "4.0.1", + "url-parse-lax": "3.0.0", "url-to-options": "1.0.1" } }, @@ -13132,6 +13421,7 @@ "run-async": "2.3.0", "rxjs": "5.5.11", "string-width": "2.1.1", + "strip-ansi": "4.0.0", "through": "2.3.8" } }, @@ -13153,10 +13443,44 @@ "p-finally": "1.0.0" } }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "requires": { + "has-flag": "3.0.0" + } + }, + "tapable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", + "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==" + }, "underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "2.0.0" + } } } }, @@ -13444,6 +13768,65 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "requires": { + "cliui": "4.1.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "9.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + } + } + }, "yauzl": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", From 9b37f807df5dbaa351371a3e3b0f871dff0d6df9 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 13:44:16 -0400 Subject: [PATCH 05/52] Websocket support --- lib/cmds/blockchain/blockchain.js | 4 ++-- lib/core/proxy.js | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 3bab4daa..ea492cdf 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -82,9 +82,9 @@ Blockchain.prototype.setupProxy = function(){ 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); + proxy.serve(ipcObject, this.config.wsHost, this.config.wsPort, true); this.config.rpcPort += 10; - //this.config.wsPort += 10; + this.config.wsPort += 10; } }; diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 4e975d16..8cdacef4 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -7,9 +7,9 @@ exports.serve = function(ipc, host, port, ws){ let proxy = httpProxy.createProxyServer({ target: { host: host, - port: port + 10, - ws: ws - } + port: port + 10 + }, + ws: ws }); proxy.on('proxyRes', (proxyRes) => { @@ -32,7 +32,7 @@ exports.serve = function(ipc, host, port, ws){ delete commList[jsonO.id]; } } catch(e){ - // + // } }); }); @@ -54,13 +54,16 @@ exports.serve = function(ipc, host, port, ws){ } }); - if(ws){ - proxy.ws(req, res); - } else { + if(!ws){ proxy.web(req, res); } - }); + if(ws){ + server.on('upgrade', function (req, socket, head) { + proxy.ws(req, socket, head); + }); + } + server.listen(port); }; From 66353bb8d5229d191db9ccb7f1428c19470081b9 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 14:36:35 -0400 Subject: [PATCH 06/52] Extracted console logging to its own file --- lib/core/engine.js | 36 +---------------- lib/modules/console_listener/index.js | 57 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 35 deletions(-) create mode 100644 lib/modules/console_listener/index.js diff --git a/lib/core/engine.js b/lib/core/engine.js index 7ebb843e..17b89b18 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -188,13 +188,13 @@ class Engine { 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({ @@ -224,40 +224,6 @@ class Engine { plugins: this.plugins }); - // Console logger - // TODO: extract to its own file - let addressToContract = {}; - this.ipc.on('log', (jsonObj) => { - if(jsonObj.type == 'contract-log'){ - if(!addressToContract[jsonObj.address]){ - let contractList = Object.keys(this.config.contractsConfig.contracts); - for(let i = 0; i < contractList.length; i++){ - let cont = this.config.contractsConfig.contracts[contractList[i]]; - if(!addressToContract[cont.deployedAddress.toLowerCase()]){ - let funcSignatures = {}; - cont.abiDefinition - .filter(func => func.type == "function") - .map(func => func.name + '(' + - (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + - ')') - .forEach(func => { - funcSignatures[utils.sha3(func).substring(0, 10)] = func; - }); - - addressToContract[cont.deployedAddress.toLowerCase()] = { - name: contractList[i], - functions: funcSignatures - }; - } - } - } - let funcHash = addressToContract[jsonObj.address].functions[jsonObj.data.substring(0, 10)]; - this.logger.debug(addressToContract[jsonObj.address].name + "." + funcHash + " : " + jsonObj.transactionHash); - } else { - this.logger.info(jsonObj); - } - }); - this.events.on('file-event', function (fileType) { clearTimeout(self.fileTimeout); self.fileTimeout = setTimeout(() => { diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js new file mode 100644 index 00000000..8194c03e --- /dev/null +++ b/lib/modules/console_listener/index.js @@ -0,0 +1,57 @@ +const utils = require('../../utils/utils.js'); + +class ConsoleListener { + constructor(embark, options) { + this.logger = embark.logger; + this.ipc = options.ipc; + this.addressToContract = []; + this.contractsConfig = embark.config.contractsConfig; + this.listenForLogRequests(); + } + + _updateContractList(){ + Object.keys(this.contractsConfig.contracts).forEach(contractName => { + let contract = this.contractsConfig.contracts[contractName]; + let address = contract.deployedAddress.toLowerCase(); + + if(!this.addressToContract[address]){ + let funcSignatures = {}; + contract.abiDefinition + .filter(func => func.type == "function") + .map(func => func.name + + '(' + + (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + + ')') + .forEach(func => { + funcSignatures[utils.sha3(func).substring(0, 10)] = func; + }); + + this.addressToContract[address] = { + name: contractName, + functions: funcSignatures + }; + } + }); + } + + listenForLogRequests(){ + this.ipc.on('log', (request) => { + if(request.type == 'contract-log'){ + + let {address, data, transactionHash} = request; + if(!this.addressToContract[address]){ + this._updateContractList(); + } + + let name = this.addressToContract[address].name; + let funcHash = this.addressToContract[address].functions[data.substring(0, 10)]; + + this.logger.debug(`${name}.${funcHash} : ${transactionHash}`); + } else { + this.logger.debug(request); + } + }); + } +} + +module.exports = ConsoleListener; From 744ec4428ee5a8952db9aefee7c8aeba3c0eb407 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 15:30:20 -0400 Subject: [PATCH 07/52] Displaying status, gas and block number --- lib/core/proxy.js | 18 +++++++++++++++++- lib/modules/console_listener/index.js | 9 ++++++--- lib/utils/utils.js | 5 +++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 8cdacef4..c4e00c56 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -3,6 +3,8 @@ const http = require('http'); exports.serve = function(ipc, host, port, ws){ let commList = {}; + let transactions = {}; + let receipts = {}; let proxy = httpProxy.createProxyServer({ target: { @@ -21,14 +23,23 @@ exports.serve = function(ipc, host, port, ws){ let jsonO = JSON.parse(resBody); if(commList[jsonO.id]){ commList[jsonO.id].transactionHash = jsonO.result; + transactions[jsonO.result] = {commListId: jsonO.id}; + } else if(receipts[jsonO.id]){ + 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[jsonO.id]); + ipc.request('log', commList[receipts[jsonO.id]]); } else { ipc.connecting = true; ipc.connect((err) => { ipc.connecting = false; }); } + + delete transactions[commList[receipts[jsonO.id]].transactionHash]; + delete receipts[jsonO.id]; delete commList[jsonO.id]; } } catch(e){ @@ -50,6 +61,11 @@ exports.serve = function(ipc, host, port, ws){ 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; + } } } }); diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 8194c03e..00cfbaf7 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -38,15 +38,18 @@ class ConsoleListener { this.ipc.on('log', (request) => { if(request.type == 'contract-log'){ - let {address, data, transactionHash} = request; + let {address, data, transactionHash, blockNumber, gasUsed, status} = request; if(!this.addressToContract[address]){ this._updateContractList(); } let name = this.addressToContract[address].name; let funcHash = this.addressToContract[address].functions[data.substring(0, 10)]; - - this.logger.debug(`${name}.${funcHash} : ${transactionHash}`); + + gasUsed = utils.hexToNumber(gasUsed); + blockNumber = utils.hexToNumber(blockNumber); + + this.logger.debug(`${name}.${funcHash} : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); } else { this.logger.debug(request); } diff --git a/lib/utils/utils.js b/lib/utils/utils.js index 6d92422f..a57b3ba5 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -185,6 +185,10 @@ function getExternalContractUrl(file) { }; } +function hexToNumber(hex){ + return Web3.utils.hexToNumber(hex); +} + function toChecksumAddress(address) { return Web3.utils.toChecksumAddress(address); } @@ -253,6 +257,7 @@ module.exports = { httpsGet: httpsGet, httpGetJson: httpGetJson, httpsGetJson: httpsGetJson, + hexToNumber: hexToNumber, runCmd: runCmd, cd: cd, sed: sed, From 87a49900b407601236e3cc8d287be79652fba8d6 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 16:34:35 -0400 Subject: [PATCH 08/52] Formatting input parameters --- lib/modules/console_listener/index.js | 33 ++++++++++++++++++++------- lib/utils/utils.js | 6 +++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 00cfbaf7..5fd1a3ec 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -18,12 +18,18 @@ class ConsoleListener { let funcSignatures = {}; contract.abiDefinition .filter(func => func.type == "function") - .map(func => func.name + - '(' + - (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + - ')') + .map(func => { + return { + name: func.name + + '(' + + (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + + ')', + abi: func, + functionName: func.name + }; + }) .forEach(func => { - funcSignatures[utils.sha3(func).substring(0, 10)] = func; + funcSignatures[utils.sha3(func.name).substring(0, 10)] = func; }); this.addressToContract[address] = { @@ -44,12 +50,23 @@ class ConsoleListener { } let name = this.addressToContract[address].name; - let funcHash = this.addressToContract[address].functions[data.substring(0, 10)]; - + let func = this.addressToContract[address].functions[data.substring(0, 10)]; + let functionName = func.functionName; + + let 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.debug(`${name}.${funcHash} : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); + this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); } else { this.logger.debug(request); } diff --git a/lib/utils/utils.js b/lib/utils/utils.js index a57b3ba5..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'); @@ -189,6 +190,10 @@ 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); } @@ -258,6 +263,7 @@ module.exports = { httpGetJson: httpGetJson, httpsGetJson: httpsGetJson, hexToNumber: hexToNumber, + decodeParams: decodeParams, runCmd: runCmd, cd: cd, sed: sed, From ba092d277a5f83f926a9134e02161d3364027707 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 16:59:33 -0400 Subject: [PATCH 09/52] Adding proxy to config, and closing on error --- lib/core/proxy.js | 4 ++++ templates/boilerplate/config/blockchain.json | 1 + templates/demo/config/blockchain.json | 1 + 3 files changed, 6 insertions(+) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index c4e00c56..60054a42 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -14,6 +14,10 @@ exports.serve = function(ipc, host, port, ws){ ws: ws }); + proxy.on('error', function (err, req, res) { + proxy.close(); + }); + proxy.on('proxyRes', (proxyRes) => { let resBody = []; proxyRes.on('data', (b) => resBody.push(b)); 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" }, From 93b48638f25f0af45605a01ac816c825e29ac743 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 17:02:45 -0400 Subject: [PATCH 10/52] Typo --- lib/cmds/blockchain/blockchain.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index ea492cdf..4841e4bf 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -45,7 +45,7 @@ var Blockchain = function(options) { targetGasLimit: this.blockchainConfig.targetGasLimit || false, light: this.blockchainConfig.light || false, fast: this.blockchainConfig.fast || false, - verbosity: this.blockchainConfig.verbosity, + verbosity: this.blockchainConfig.verbosity }; this.setupProxy(); From 9869a740b8eacd062e53166ba028b8e8fc0e1450 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 17:22:53 -0400 Subject: [PATCH 11/52] Removing unused variables --- lib/core/proxy.js | 4 +- lib/modules/console_listener/index.js | 60 ++++++++++++++------------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 60054a42..14b33025 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -14,7 +14,7 @@ exports.serve = function(ipc, host, port, ws){ ws: ws }); - proxy.on('error', function (err, req, res) { + proxy.on('error', function () { proxy.close(); }); @@ -37,7 +37,7 @@ exports.serve = function(ipc, host, port, ws){ ipc.request('log', commList[receipts[jsonO.id]]); } else { ipc.connecting = true; - ipc.connect((err) => { + ipc.connect(() => { ipc.connecting = false; }); } diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 5fd1a3ec..d1330345 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -41,36 +41,40 @@ class ConsoleListener { } listenForLogRequests(){ - this.ipc.on('log', (request) => { - if(request.type == 'contract-log'){ + try { + this.ipc.on('log', (request) => { + if(request.type == 'contract-log'){ - let {address, data, transactionHash, blockNumber, gasUsed, status} = request; - if(!this.addressToContract[address]){ - this._updateContractList(); + let {address, data, transactionHash, blockNumber, gasUsed, status} = request; + if(!this.addressToContract[address]){ + this._updateContractList(); + } + + let name = this.addressToContract[address].name; + let func = this.addressToContract[address].functions[data.substring(0, 10)]; + let functionName = func.functionName; + + let 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.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); + } else { + this.logger.debug(request); } - - let name = this.addressToContract[address].name; - let func = this.addressToContract[address].functions[data.substring(0, 10)]; - let functionName = func.functionName; - - let 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.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); - } else { - this.logger.debug(request); - } - }); + }); + } catch(e) { + // + } } } From 7baad579954d8a033d22a8ffdeb1e669c01849d1 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 19:08:32 -0400 Subject: [PATCH 12/52] Launching ipc connection depending on role --- lib/modules/console_listener/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index d1330345..6b1aaf52 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -41,7 +41,7 @@ class ConsoleListener { } listenForLogRequests(){ - try { + if(this.ipc.ipcRole === 'server'){ this.ipc.on('log', (request) => { if(request.type == 'contract-log'){ @@ -72,8 +72,6 @@ class ConsoleListener { this.logger.debug(request); } }); - } catch(e) { - // } } } From 22021ccca93444bfb28438f99d7f88855c6b4fa2 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sat, 9 Jun 2018 19:29:32 -0400 Subject: [PATCH 13/52] extend with current contract methods --- js/embark.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/js/embark.js b/js/embark.js index 755060fe..534943ef 100644 --- a/js/embark.js +++ b/js/embark.js @@ -30,6 +30,29 @@ EmbarkJS.Contract = function(options) { ContractClass.options.data = this.code; ContractClass.abi = ContractClass.options.abi; ContractClass.address = this.address; + + let originalMethods = Object.keys(ContractClass); + + ContractClass._jsonInterface.forEach((abi) => { + if (originalMethods.indexOf(abi.name) >= 0) { + console.log(abi.name + " is a reserved word and cannot be used as a contract method, property or event"); + return; + } + if (abi.constant) { + ContractClass[abi.name] = function() { + let ref = ContractClass.methods[abi.name]; + let send = ref.apply(ref, ..arguments).send; + return send.apply(call, []); + }; + } else { + ContractClass[abi.name] = function() { + let ref = ContractClass.methods[abi.name]; + let call = ref.apply(ref, ..arguments).call; + return call.apply(call, []); + }; + } + }); + return ContractClass; } else { ContractClass = this.web3.eth.contract(this.abi); From 3185a1374c4937129c295e3b9d14d38522dd193c Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sun, 10 Jun 2018 10:07:02 -0400 Subject: [PATCH 14/52] fix passing options; add events --- js/embark.js | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/js/embark.js b/js/embark.js index 534943ef..7aa33559 100644 --- a/js/embark.js +++ b/js/embark.js @@ -32,24 +32,54 @@ EmbarkJS.Contract = function(options) { ContractClass.address = this.address; let originalMethods = Object.keys(ContractClass); + let methods = []; ContractClass._jsonInterface.forEach((abi) => { if (originalMethods.indexOf(abi.name) >= 0) { console.log(abi.name + " is a reserved word and cannot be used as a contract method, property or event"); return; } - if (abi.constant) { + methods.push(abi.name); + + if (!abi.inputs) { + return; + } + + let numExpectedInputs = abi.inputs.length; + + if (abi.type === 'function' && abi.constant) { ContractClass[abi.name] = function() { + let options = {}, cb = null, args = Array.from(arguments || []).slice(0, numExpectedInputs); + if (typeof (arguments[numExpectedInputs]) === 'function') { + cb = arguments[numExpectedInputs]; + } else if (typeof (arguments[numExpectedInputs]) === 'object') { + options = arguments[numExpectedInputs]; + cb = arguments[numExpectedInputs + 1]; + } + let ref = ContractClass.methods[abi.name]; - let send = ref.apply(ref, ..arguments).send; - return send.apply(call, []); - }; - } else { - ContractClass[abi.name] = function() { - let ref = ContractClass.methods[abi.name]; - let call = ref.apply(ref, ..arguments).call; + let call = ref.apply(ref, ...arguments).call; return call.apply(call, []); }; + } else if (abi.type === 'function') { + ContractClass[abi.name] = function() { + let options = {}, cb = null, args = Array.from(arguments || []).slice(0, numExpectedInputs); + if (typeof (arguments[numExpectedInputs]) === 'function') { + cb = arguments[numExpectedInputs]; + } else if (typeof (arguments[numExpectedInputs]) === 'object') { + options = arguments[numExpectedInputs]; + cb = arguments[numExpectedInputs + 1]; + } + + let ref = ContractClass.methods[abi.name]; + let send = ref.apply(ref, args).send; + return send.apply(send, [options, cb]); + }; + } else if (abi.type === 'event') { + ContractClass[abi.name] = function(options, cb) { + let ref = ContractClass.events[abi.name]; + return ref.apply(ref, [options, cb]); + } } }); From e119007f76bad756ee2e4a6da5f4e288ff04a7ac Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sun, 10 Jun 2018 10:22:09 -0400 Subject: [PATCH 15/52] clean up, improve setting the web3 object --- js/embark.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/js/embark.js b/js/embark.js index 7aa33559..19fe6d88 100644 --- a/js/embark.js +++ b/js/embark.js @@ -19,27 +19,28 @@ EmbarkJS.Contract = function(options) { this.address = options.address; this.code = '0x' + options.code; //this.web3 = options.web3 || web3; - this.web3 = options.web3 || window.web3; + this.web3 = options.web3; + if (!this.web3 && typeof ('web3') !== 'undefined') { + this.web3 = web3; + } else { + this.web3 = window.web3; + } if (EmbarkJS.isNewWeb3()) { - // TODO: - // add default **from** address - // add gasPrice ContractClass = new this.web3.eth.Contract(this.abi, this.address); ContractClass.setProvider(this.web3.currentProvider); ContractClass.options.data = this.code; + ContractClass.options.from = this.from; ContractClass.abi = ContractClass.options.abi; ContractClass.address = this.address; let originalMethods = Object.keys(ContractClass); - let methods = []; ContractClass._jsonInterface.forEach((abi) => { if (originalMethods.indexOf(abi.name) >= 0) { console.log(abi.name + " is a reserved word and cannot be used as a contract method, property or event"); return; } - methods.push(abi.name); if (!abi.inputs) { return; From c4ca4e52b88ce2ebec5c7ae20b47f5498635970c Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sun, 10 Jun 2018 12:11:34 -0400 Subject: [PATCH 16/52] support embarkjs in the tests --- js/embark.js | 20 +++++++++++++------ lib/tests/test.js | 13 ++++++++---- .../test_app/test/another_storage_spec.js | 5 +++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/js/embark.js b/js/embark.js index 19fe6d88..4412a5d5 100644 --- a/js/embark.js +++ b/js/embark.js @@ -1,9 +1,14 @@ var EmbarkJS = { - onReady: __embarkContext.execWhenReady + onReady: function(cb) { + if (typeof (__embarkContext) === 'undefined') { + return cb(); + } + return __embarkContext.execWhenReady(cb); + } }; -EmbarkJS.isNewWeb3 = function() { - var _web3 = new Web3(); +EmbarkJS.isNewWeb3 = function(web3Obj) { + var _web3 = web3Obj || (new Web3()); if (typeof(_web3.version) === "string") { return true; } @@ -17,22 +22,24 @@ EmbarkJS.Contract = function(options) { this.abi = options.abi; this.address = options.address; + this.gas = options.gas; this.code = '0x' + options.code; //this.web3 = options.web3 || web3; this.web3 = options.web3; if (!this.web3 && typeof ('web3') !== 'undefined') { this.web3 = web3; - } else { + } else if (!this.web3) { this.web3 = window.web3; } - if (EmbarkJS.isNewWeb3()) { + if (EmbarkJS.isNewWeb3(this.web3)) { ContractClass = new this.web3.eth.Contract(this.abi, this.address); ContractClass.setProvider(this.web3.currentProvider); ContractClass.options.data = this.code; ContractClass.options.from = this.from; ContractClass.abi = ContractClass.options.abi; ContractClass.address = this.address; + ContractClass.gas = this.gas; let originalMethods = Object.keys(ContractClass); @@ -386,4 +393,5 @@ EmbarkJS.Utils = { } }; -export default EmbarkJS; +//export default EmbarkJS; +module.exports = EmbarkJS; diff --git a/lib/tests/test.js b/lib/tests/test.js index a6789da9..4ebcfddd 100644 --- a/lib/tests/test.js +++ b/lib/tests/test.js @@ -8,6 +8,8 @@ const cloneDeep = require('clone-deep'); const AccountParser = require('../contracts/accountParser'); const Provider = require('../contracts/provider'); +const EmbarkJS = require('../../js/embark'); + function getSimulator() { try { return require('ganache-cli'); @@ -241,8 +243,10 @@ class Test { } else { data = self.contracts[contractName].options.data; } - Object.assign(self.contracts[contractName], new self.web3.eth.Contract(contract.abiDefinition, contract.deployedAddress, - {from: self.web3.eth.defaultAccount, gas: 6000000})); + //Object.assign(self.contracts[contractName], new self.web3.eth.Contract(contract.abiDefinition, contract.deployedAddress, + // {from: self.web3.eth.defaultAccount, gas: 6000000})); + Object.assign(self.contracts[contractName], new EmbarkJS.Contract({abi: contract.abiDefinition, address: contract.deployedAddress, from: self.web3.eth.defaultAccount, gas: 6000000, web3: self.web3})); + self.contracts[contractName].address = contract.deployedAddress; if (self.contracts[contractName].options) { self.contracts[contractName].options.from = self.contracts[contractName].options.from || self.web3.eth.defaultAccount; @@ -288,8 +292,9 @@ class Test { contract = this.engine.contractsManager.contracts[contractNames[0]]; } } - this.contracts[contractName] = new this.web3.eth.Contract(contract.abiDefinition, contract.address, - {from: this.web3.eth.defaultAccount, gas: 6000000}); + //this.contracts[contractName] = new this.web3.eth.Contract(contract.abiDefinition, contract.address, + // {from: this.web3.eth.defaultAccount, gas: 6000000}); + this.contracts[contractName] = new EmbarkJS.Contract({abi: contract.abiDefinition, address: contract.address, from: this.web3.eth.defaultAccount, gas: 6000000, web3: this.web3}); this.contracts[contractName].address = contract.address; this.contracts[contractName].options.data = contract.code; this.web3.eth.getAccounts().then((accounts) => { diff --git a/test_apps/test_app/test/another_storage_spec.js b/test_apps/test_app/test/another_storage_spec.js index 8ebc9e3f..5bdc738c 100644 --- a/test_apps/test_app/test/another_storage_spec.js +++ b/test_apps/test_app/test/another_storage_spec.js @@ -40,6 +40,11 @@ contract("AnotherStorage", function() { assert.equal(result.toString(), SimpleStorage.options.address); }); + it("set SimpleStorage address with alternative syntax", async function() { + let result = await AnotherStorage.simpleStorageAddress(); + assert.equal(result.toString(), SimpleStorage.options.address); + }); + it('should set the balance correctly', async function () { const balance = await web3.eth.getBalance(accounts[0]); assert.ok(balance < 5000000000000000000); From 8783f04a9cae540a72b281ea34ba28bd3bc733a9 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Sun, 10 Jun 2018 12:55:59 -0400 Subject: [PATCH 17/52] add node version of embarkjs to avoid export issues with webpack.. (for now...) --- js/embark.js | 3 +- js/embark_node.js | 396 ++++++++++++++++++++++++++++++++++++++++++++++ lib/tests/test.js | 2 +- 3 files changed, 398 insertions(+), 3 deletions(-) create mode 100644 js/embark_node.js diff --git a/js/embark.js b/js/embark.js index 4412a5d5..b3e7114d 100644 --- a/js/embark.js +++ b/js/embark.js @@ -393,5 +393,4 @@ EmbarkJS.Utils = { } }; -//export default EmbarkJS; -module.exports = EmbarkJS; +export default EmbarkJS; diff --git a/js/embark_node.js b/js/embark_node.js new file mode 100644 index 00000000..bfcda6da --- /dev/null +++ b/js/embark_node.js @@ -0,0 +1,396 @@ +var EmbarkJS = { + onReady: function(cb) { + if (typeof (__embarkContext) === 'undefined') { + return cb(); + } + return __embarkContext.execWhenReady(cb); + } +}; + +EmbarkJS.isNewWeb3 = function(web3Obj) { + var _web3 = web3Obj || (new Web3()); + if (typeof(_web3.version) === "string") { + return true; + } + return parseInt(_web3.version.api.split('.')[0], 10) >= 1; +}; + +EmbarkJS.Contract = function(options) { + var self = this; + var i, abiElement; + var ContractClass; + + this.abi = options.abi; + this.address = options.address; + this.gas = options.gas; + this.code = '0x' + options.code; + //this.web3 = options.web3 || web3; + this.web3 = options.web3; + if (!this.web3 && typeof ('web3') !== 'undefined') { + this.web3 = web3; + } else if (!this.web3) { + this.web3 = window.web3; + } + + if (EmbarkJS.isNewWeb3(this.web3)) { + ContractClass = new this.web3.eth.Contract(this.abi, this.address); + ContractClass.setProvider(this.web3.currentProvider); + ContractClass.options.data = this.code; + ContractClass.options.from = this.from; + ContractClass.abi = ContractClass.options.abi; + ContractClass.address = this.address; + ContractClass.gas = this.gas; + + let originalMethods = Object.keys(ContractClass); + + ContractClass._jsonInterface.forEach((abi) => { + if (originalMethods.indexOf(abi.name) >= 0) { + console.log(abi.name + " is a reserved word and cannot be used as a contract method, property or event"); + return; + } + + if (!abi.inputs) { + return; + } + + let numExpectedInputs = abi.inputs.length; + + if (abi.type === 'function' && abi.constant) { + ContractClass[abi.name] = function() { + let options = {}, cb = null, args = Array.from(arguments || []).slice(0, numExpectedInputs); + if (typeof (arguments[numExpectedInputs]) === 'function') { + cb = arguments[numExpectedInputs]; + } else if (typeof (arguments[numExpectedInputs]) === 'object') { + options = arguments[numExpectedInputs]; + cb = arguments[numExpectedInputs + 1]; + } + + let ref = ContractClass.methods[abi.name]; + let call = ref.apply(ref, ...arguments).call; + return call.apply(call, []); + }; + } else if (abi.type === 'function') { + ContractClass[abi.name] = function() { + let options = {}, cb = null, args = Array.from(arguments || []).slice(0, numExpectedInputs); + if (typeof (arguments[numExpectedInputs]) === 'function') { + cb = arguments[numExpectedInputs]; + } else if (typeof (arguments[numExpectedInputs]) === 'object') { + options = arguments[numExpectedInputs]; + cb = arguments[numExpectedInputs + 1]; + } + + let ref = ContractClass.methods[abi.name]; + let send = ref.apply(ref, args).send; + return send.apply(send, [options, cb]); + }; + } else if (abi.type === 'event') { + ContractClass[abi.name] = function(options, cb) { + let ref = ContractClass.events[abi.name]; + return ref.apply(ref, [options, cb]); + } + } + }); + + return ContractClass; + } else { + ContractClass = this.web3.eth.contract(this.abi); + + this.eventList = []; + + if (this.abi) { + for (i = 0; i < this.abi.length; i++) { + abiElement = this.abi[i]; + if (abiElement.type === 'event') { + this.eventList.push(abiElement.name); + } + } + } + + var messageEvents = function() { + this.cb = function() {}; + }; + + messageEvents.prototype.then = function(cb) { + this.cb = cb; + }; + + messageEvents.prototype.error = function(err) { + return err; + }; + + this._originalContractObject = ContractClass.at(this.address); + this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function(p) { + // TODO: check for forbidden properties + if (self.eventList.indexOf(p) >= 0) { + + self[p] = function() { + var promise = new messageEvents(); + var args = Array.prototype.slice.call(arguments); + args.push(function(err, result) { + if (err) { + promise.error(err); + } else { + promise.cb(result); + } + }); + + self._originalContractObject[p].apply(self._originalContractObject[p], args); + return promise; + }; + return true; + } else if (typeof self._originalContractObject[p] === 'function') { + self[p] = function(_args) { + var args = Array.prototype.slice.call(arguments); + var fn = self._originalContractObject[p]; + var props = self.abi.find((x) => x.name == p); + + var promise = new Promise(function(resolve, reject) { + args.push(function(err, transaction) { + promise.tx = transaction; + if (err) { + return reject(err); + } + + var getConfirmation = function() { + self.web3.eth.getTransactionReceipt(transaction, function(err, receipt) { + if (err) { + return reject(err); + } + + if (receipt !== null) { + return resolve(receipt); + } + + setTimeout(getConfirmation, 1000); + }); + }; + + if (typeof(transaction) !== "string" || props.constant) { + resolve(transaction); + } else { + getConfirmation(); + } + }); + + fn.apply(fn, args); + }); + + return promise; + }; + return true; + } + return false; + }); + } +}; + +EmbarkJS.Contract.prototype.deploy = function(args, _options) { + var self = this; + var contractParams; + var options = _options || {}; + + contractParams = args || []; + + contractParams.push({ + from: this.web3.eth.accounts[0], + data: this.code, + gas: options.gas || 800000 + }); + + var contractObject = this.web3.eth.contract(this.abi); + + var promise = new Promise(function(resolve, reject) { + contractParams.push(function(err, transaction) { + if (err) { + reject(err); + } else if (transaction.address !== undefined) { + resolve(new EmbarkJS.Contract({ + abi: self.abi, + code: self.code, + address: transaction.address + })); + } + }); + + // returns promise + // deploys contract + // wraps it around EmbarkJS.Contract + contractObject["new"].apply(contractObject, contractParams); + }); + + + return promise; +}; + +EmbarkJS.Contract.prototype.new = EmbarkJS.Contract.prototype.deploy; + +EmbarkJS.Contract.prototype.at = function(address) { + return new EmbarkJS.Contract({ abi: this.abi, code: this.code, address: address }); +}; + +EmbarkJS.Contract.prototype.send = function(value, unit, _options) { + var options, wei; + if (typeof unit === 'object') { + options = unit; + wei = value; + } else { + options = _options || {}; + wei = this.web3.toWei(value, unit); + } + + options.to = this.address; + options.value = wei; + + this.web3.eth.sendTransaction(options); +}; + +EmbarkJS.Storage = {}; + +EmbarkJS.Storage.Providers = {}; + +EmbarkJS.Storage.saveText = function(text) { + if (!this.currentStorage) { + throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); + } + return this.currentStorage.saveText(text); +}; + +EmbarkJS.Storage.get = function(hash) { + if (!this.currentStorage) { + throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); + } + return this.currentStorage.get(hash); +}; + +EmbarkJS.Storage.uploadFile = function(inputSelector) { + if (!this.currentStorage) { + throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); + } + return this.currentStorage.uploadFile(inputSelector); +}; + +EmbarkJS.Storage.getUrl = function(hash) { + if (!this.currentStorage) { + throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); + } + return this.currentStorage.getUrl(hash); +}; + +EmbarkJS.Storage.registerProvider = function(providerName, obj) { + EmbarkJS.Storage.Providers[providerName] = obj; +}; + +EmbarkJS.Storage.setProvider = function(provider, options) { + let providerObj = this.Providers[provider]; + + if (!providerObj) { + throw new Error('Unknown storage provider'); + } + + this.currentStorage = providerObj; + + return providerObj.setProvider(options); +}; + +EmbarkJS.Storage.isAvailable = function(){ + if (!this.currentStorage) { + throw new Error('Storage provider not set; e.g EmbarkJS.Storage.setProvider("ipfs")'); + } + return this.currentStorage.isAvailable(); +}; + +EmbarkJS.Messages = {}; + +EmbarkJS.Messages.Providers = {}; + +EmbarkJS.Messages.registerProvider = function(providerName, obj) { + EmbarkJS.Messages.Providers[providerName] = obj; +}; + +EmbarkJS.Messages.setProvider = function(provider, options) { + let providerObj = this.Providers[provider]; + + if (!providerObj) { + throw new Error('Unknown messages provider'); + } + + this.currentMessages = providerObj; + + return providerObj.setProvider(options); +}; + +EmbarkJS.Messages.isAvailable = function(){ + return this.currentMessages.isAvailable(); +}; + +EmbarkJS.Messages.sendMessage = function(options) { + if (!this.currentMessages) { + throw new Error('Messages provider not set; e.g EmbarkJS.Messages.setProvider("whisper")'); + } + return this.currentMessages.sendMessage(options); +}; + +EmbarkJS.Messages.listenTo = function(options, callback) { + if (!this.currentMessages) { + throw new Error('Messages provider not set; e.g EmbarkJS.Messages.setProvider("whisper")'); + } + return this.currentMessages.listenTo(options, callback); +}; + +EmbarkJS.Names = {}; + +EmbarkJS.Names.Providers = {}; + +EmbarkJS.Names.registerProvider = function(providerName, obj) { + EmbarkJS.Names.Providers[providerName] = obj; +} + +EmbarkJS.Names.setProvider = function(provider, options) { + let providerObj = this.Providers[provider]; + + if (!providerObj) { + throw new Error('Unknown name system provider'); + } + + this.currentNameSystems = providerObj; + + return providerObj.setProvider(options); +}; + +// resolve resolves a name into an identifier of some kind +EmbarkJS.Names.resolve = function(name) { + if (!this.currentNameSystems) { + throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")'); + } + return this.currentNameSystems.resolve(name); +} + +// the reverse of resolve, resolves using an identifier to get to a name +EmbarkJS.Names.lookup = function(identifier) { + if (!this.currentNameSystems) { + throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")'); + } + return this.currentNameSystems.lookup(identifier); +} + +// To Implement + +/* +// register a name +EmbarkJS.Names.register = function(name, options) { + +} +*/ + +EmbarkJS.Utils = { + fromAscii: function(str) { + var _web3 = new Web3(); + return _web3.utils ? _web3.utils.fromAscii(str) : _web3.fromAscii(str); + }, + toAscii: function(str) { + var _web3 = new Web3(); + return _web3.utils.toAscii(str); + } +}; + +module.exports = EmbarkJS; diff --git a/lib/tests/test.js b/lib/tests/test.js index 4ebcfddd..ad91ae77 100644 --- a/lib/tests/test.js +++ b/lib/tests/test.js @@ -8,7 +8,7 @@ const cloneDeep = require('clone-deep'); const AccountParser = require('../contracts/accountParser'); const Provider = require('../contracts/provider'); -const EmbarkJS = require('../../js/embark'); +const EmbarkJS = require('../../js/embark_node'); function getSimulator() { try { From 373a25e06451beb4c9af790b8ca77aa722007012 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 09:02:52 -0400 Subject: [PATCH 18/52] Adding line break --- lib/cmds/simulator.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index da819246..4c0a89f0 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -8,7 +8,8 @@ class Simulator { this.logger = options.logger; } - run(options) { let cmds = []; + run(options) { + let cmds = []; const testrpc = shelljs.which('testrpc'); const ganache = shelljs.which('ganache-cli'); From c8eab0d88a92108e4eb8c8d8989de26c3dd40205 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 09:19:24 -0400 Subject: [PATCH 19/52] Displays json as a string in the console --- lib/modules/console_listener/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 6b1aaf52..6d022fdf 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -69,7 +69,7 @@ class ConsoleListener { this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); } else { - this.logger.debug(request); + this.logger.debug(JSON.stringify(request)); } }); } From a4a812e7b1aa147c716d477ca74a004774e27ab6 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 11 Jun 2018 12:02:00 -0400 Subject: [PATCH 20/52] make proxy mode the default --- lib/cmds/blockchain/blockchain.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 4841e4bf..67a7b05b 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -74,18 +74,19 @@ var Blockchain = function(options) { this.client = new options.client({config: this.config, env: this.env, isDev: this.isDev}); }; -Blockchain.prototype.setupProxy = function(){ - if(this.blockchainConfig.proxy){ - 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 += 10; - this.config.wsPort += 10; +Blockchain.prototype.setupProxy = function() { + if (this.blockchainConfig.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 += 10; + this.config.wsPort += 10; }; Blockchain.prototype.runCommand = function(cmd, options, callback) { From c4eb042efff43666d455a17db1827a758d0ae7a3 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 11 Jun 2018 12:13:30 -0400 Subject: [PATCH 21/52] color output --- lib/modules/console_listener/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 6d022fdf..ca058035 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -67,9 +67,9 @@ class ConsoleListener { gasUsed = utils.hexToNumber(gasUsed); blockNumber = utils.hexToNumber(blockNumber); - this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); + this.logger.info(`Blockchain>`.underline + ` ${name}.${functionName}(${paramString})`.bold + ` | ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); } else { - this.logger.debug(JSON.stringify(request)); + this.logger.info(JSON.stringify(request)); } }); } From 6b26f2a9d7ea924cc9c526fddab5f57321de46cb Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 11 Jun 2018 13:37:06 -0400 Subject: [PATCH 22/52] set default gas --- lib/tests/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tests/test.js b/lib/tests/test.js index ad91ae77..a6c83657 100644 --- a/lib/tests/test.js +++ b/lib/tests/test.js @@ -243,14 +243,13 @@ class Test { } else { data = self.contracts[contractName].options.data; } - //Object.assign(self.contracts[contractName], new self.web3.eth.Contract(contract.abiDefinition, contract.deployedAddress, - // {from: self.web3.eth.defaultAccount, gas: 6000000})); Object.assign(self.contracts[contractName], new EmbarkJS.Contract({abi: contract.abiDefinition, address: contract.deployedAddress, from: self.web3.eth.defaultAccount, gas: 6000000, web3: self.web3})); self.contracts[contractName].address = contract.deployedAddress; if (self.contracts[contractName].options) { self.contracts[contractName].options.from = self.contracts[contractName].options.from || self.web3.eth.defaultAccount; self.contracts[contractName].options.data = data; + self.contracts[contractName].options.gas = 6000000; } eachCb(); }, (err) => { @@ -297,6 +296,7 @@ class Test { this.contracts[contractName] = new EmbarkJS.Contract({abi: contract.abiDefinition, address: contract.address, from: this.web3.eth.defaultAccount, gas: 6000000, web3: this.web3}); this.contracts[contractName].address = contract.address; this.contracts[contractName].options.data = contract.code; + this.contracts[contractName].options.gas = 6000000; this.web3.eth.getAccounts().then((accounts) => { this.contracts[contractName].options.from = contract.from || accounts[0]; }); From 57ef5731426f16966563ba06833df2eb4ecfdf0e Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 11 Jun 2018 13:41:26 -0400 Subject: [PATCH 23/52] remove trailing whitespace --- js/embark.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/embark.js b/js/embark.js index b3e7114d..06817208 100644 --- a/js/embark.js +++ b/js/embark.js @@ -376,9 +376,9 @@ EmbarkJS.Names.lookup = function(identifier) { // To Implement /* -// register a name +// register a name EmbarkJS.Names.register = function(name, options) { - + } */ From a02c7053bd4621a02409ce557855fabdfc22bede Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 15:43:45 -0400 Subject: [PATCH 24/52] Changes based on code review --- lib/cmds/blockchain/blockchain.js | 5 +- lib/cmds/simulator.js | 5 +- lib/constants.json | 3 +- lib/core/proxy.js | 61 +++++++------ lib/modules/console_listener/index.js | 124 ++++++++++++++------------ 5 files changed, 107 insertions(+), 91 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 4841e4bf..f5cd0832 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'); @@ -83,8 +84,8 @@ Blockchain.prototype.setupProxy = function(){ proxy.serve(ipcObject, this.config.rpcHost, this.config.rpcPort, false); proxy.serve(ipcObject, this.config.wsHost, this.config.wsPort, true); - this.config.rpcPort += 10; - this.config.wsPort += 10; + this.config.rpcPort += constants.blockchain.servicePortOnProxy; + this.config.wsPort += constants.blockchain.servicePortOnProxy; } }; diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index 4c0a89f0..638020e3 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -1,6 +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) { @@ -8,7 +9,7 @@ class Simulator { this.logger = options.logger; } - run(options) { + run(options) { let cmds = []; const testrpc = shelljs.which('testrpc'); @@ -23,7 +24,7 @@ class Simulator { let host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); let port = (options.port || this.blockchainConfig.rpcPort || 8545); - cmds.push("-p " + (port + (useProxy ? 10 : 0))); + 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)); 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/proxy.js b/lib/core/proxy.js index 14b33025..71e2a95a 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -1,5 +1,6 @@ const httpProxy = require('http-proxy'); const http = require('http'); +const constants = require('../constants.json'); exports.serve = function(ipc, host, port, ws){ let commList = {}; @@ -8,14 +9,15 @@ exports.serve = function(ipc, host, port, ws){ let proxy = httpProxy.createProxyServer({ target: { - host: host, - port: port + 10 + host, + port: port + constants.blockchain.servicePortOnProxy }, ws: ws }); proxy.on('error', function () { - proxy.close(); + console.log(__("Error forwarding requests to blockchain/simulator")); + process.exit(); }); proxy.on('proxyRes', (proxyRes) => { @@ -23,31 +25,34 @@ exports.serve = function(ipc, host, port, ws){ proxyRes.on('data', (b) => resBody.push(b)); proxyRes.on('end', function () { resBody = Buffer.concat(resBody).toString(); - try { - let jsonO = JSON.parse(resBody); - if(commList[jsonO.id]){ - commList[jsonO.id].transactionHash = jsonO.result; - transactions[jsonO.result] = {commListId: jsonO.id}; - } else if(receipts[jsonO.id]){ - 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]; + let jsonO; + try { + jsonO = JSON.parse(resBody); + } catch(e) { + return; + } + + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = jsonO.result; + transactions[jsonO.result] = {commListId: jsonO.id}; + } else if(receipts[jsonO.id]){ + 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; + }); } - } catch(e){ - // + + delete transactions[commList[receipts[jsonO.id]].transactionHash]; + delete receipts[jsonO.id]; + delete commList[jsonO.id]; } }); }); @@ -59,13 +64,13 @@ exports.serve = function(ipc, host, port, ws){ reqBody = Buffer.concat(reqBody).toString(); if(reqBody){ let jsonO = JSON.parse(reqBody); - if(jsonO.method == "eth_sendTransaction"){ + 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"){ + } 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; diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 6d022fdf..174d9f22 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -4,75 +4,83 @@ 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.listenForLogRequests(); - } + this.contractsDeployed = false; - _updateContractList(){ - Object.keys(this.contractsConfig.contracts).forEach(contractName => { - let contract = this.contractsConfig.contracts[contractName]; - let address = contract.deployedAddress.toLowerCase(); + this._listenForLogRequests(); - if(!this.addressToContract[address]){ - let funcSignatures = {}; - contract.abiDefinition - .filter(func => func.type == "function") - .map(func => { - return { - name: func.name + - '(' + - (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + - ')', - abi: func, - functionName: func.name - }; - }) - .forEach(func => { - funcSignatures[utils.sha3(func.name).substring(0, 10)] = func; - }); - - this.addressToContract[address] = { - name: contractName, - functions: funcSignatures - }; - } + this.events.on("contractsDeployed", () => { + this.contractsDeployed = true; }); } - listenForLogRequests(){ - if(this.ipc.ipcRole === 'server'){ - this.ipc.on('log', (request) => { - if(request.type == 'contract-log'){ - - let {address, data, transactionHash, blockNumber, gasUsed, status} = request; - if(!this.addressToContract[address]){ - this._updateContractList(); - } - - let name = this.addressToContract[address].name; - let func = this.addressToContract[address].functions[data.substring(0, 10)]; - let functionName = func.functionName; - - let 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 + ", "; + _updateContractList(){ + this.events.request("contracts:list", (_err, contractsList) => { + if(_err) return; + contractsList.forEach(contract => { + 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 + }; }); - paramString = paramString.substring(0, paramString.length - 2); - } - gasUsed = utils.hexToNumber(gasUsed); - blockNumber = utils.hexToNumber(blockNumber); - - this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); - } else { - this.logger.debug(JSON.stringify(request)); + 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.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); + } else { + this.logger.debug(JSON.stringify(request)); + } + }); } } From 812cefafb174dfbcfc0b474051ea962413fcfcf1 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Mon, 11 Jun 2018 15:55:57 -0400 Subject: [PATCH 25/52] kill processes when they are over --- lib/pipeline/pipeline.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pipeline/pipeline.js b/lib/pipeline/pipeline.js index ca61b515..7d7a0e54 100644 --- a/lib/pipeline/pipeline.js +++ b/lib/pipeline/pipeline.js @@ -107,7 +107,7 @@ class Pipeline { webpackProcess.send({action: constants.pipeline.build, file, importsList}); webpackProcess.once('result', constants.pipeline.built, (msg) => { - webpackProcess.disconnect(); + webpackProcess.kill(); return next(msg.error); }); }, From 94de4c795a793f415e48a3fa4959ef09411e1ec0 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 16:26:32 -0400 Subject: [PATCH 26/52] Updating tests --- lib/cmds/blockchain/blockchain.js | 3 +++ test/blockchain.js | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index f9b2a290..dc17da8b 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -76,9 +76,12 @@ var Blockchain = function(options) { }; 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'); 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(); }); From 5f8f7f35acc3d82f71a101914ddbc3fce263cae4 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 11 Jun 2018 16:27:39 -0400 Subject: [PATCH 27/52] fix checking web3 --- js/embark.js | 2 +- js/embark_node.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/embark.js b/js/embark.js index 06817208..86d31a04 100644 --- a/js/embark.js +++ b/js/embark.js @@ -26,7 +26,7 @@ EmbarkJS.Contract = function(options) { this.code = '0x' + options.code; //this.web3 = options.web3 || web3; this.web3 = options.web3; - if (!this.web3 && typeof ('web3') !== 'undefined') { + if (!this.web3 && typeof (web3) !== 'undefined') { this.web3 = web3; } else if (!this.web3) { this.web3 = window.web3; diff --git a/js/embark_node.js b/js/embark_node.js index bfcda6da..9e9ea8b7 100644 --- a/js/embark_node.js +++ b/js/embark_node.js @@ -26,7 +26,7 @@ EmbarkJS.Contract = function(options) { this.code = '0x' + options.code; //this.web3 = options.web3 || web3; this.web3 = options.web3; - if (!this.web3 && typeof ('web3') !== 'undefined') { + if (!this.web3 && typeof (web3) !== 'undefined') { this.web3 = web3; } else if (!this.web3) { this.web3 = window.web3; From 20acb5425f3ffb9391a34df3c7c9081dcfeff118 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 11 Jun 2018 16:34:41 -0400 Subject: [PATCH 28/52] remove comment --- lib/tests/test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/tests/test.js b/lib/tests/test.js index a6c83657..d594ab3e 100644 --- a/lib/tests/test.js +++ b/lib/tests/test.js @@ -291,8 +291,6 @@ class Test { contract = this.engine.contractsManager.contracts[contractNames[0]]; } } - //this.contracts[contractName] = new this.web3.eth.Contract(contract.abiDefinition, contract.address, - // {from: this.web3.eth.defaultAccount, gas: 6000000}); this.contracts[contractName] = new EmbarkJS.Contract({abi: contract.abiDefinition, address: contract.address, from: this.web3.eth.defaultAccount, gas: 6000000, web3: this.web3}); this.contracts[contractName].address = contract.address; this.contracts[contractName].options.data = contract.code; From 339ffa5869a756a2739c74556ceedfc3cedf563c Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Thu, 7 Jun 2018 12:50:22 -0400 Subject: [PATCH 29/52] Adding proxy for simulator --- lib/cmds/simulator.js | 63 +++++++++++++++++++++++++++++++++++++++++-- lib/index.js | 7 ++++- package.json | 2 ++ 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index a68b27e7..d3d5a4c5 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -4,6 +4,8 @@ class Simulator { constructor(options) { this.blockchainConfig = options.blockchainConfig; this.logger = options.logger; + this.contractsConfig = options.contractsConfig; + this.events = options.events; } run(options) { @@ -17,7 +19,9 @@ class Simulator { process.exit(); } - cmds.push("-p " + (options.port || this.blockchainConfig.rpcPort || 8545)); + cmds.push("-p " + ((options.port || this.blockchainConfig.rpcPort || 8545) + 1)); + + cmds.push("-h " + (options.host || this.blockchainConfig.rpcHost || 'localhost')); cmds.push("-a " + (options.numAccounts || 10)); cmds.push("-e " + (options.defaultBalance || 100)); @@ -36,7 +40,62 @@ class Simulator { } const program = ganache ? 'ganache-cli' : 'testrpc'; - shelljs.exec(`${program} ${cmds.join(' ')}`, {async : true}); + + shelljs.exec(`${program} ${cmds.join(' ')} &`, {async : true}); + + let httpProxy = require('http-proxy'); + let http = require('http'); + let _port = options.port || this.blockchainConfig.rpcPort || 8545; + let _host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); + + let commList = {}; + + let proxy = httpProxy.createProxyServer({}); + let server = http.createServer((req, res) => { + + let reqBody = []; + req.on('data', (b) => { reqBody.push(b); }) + .on('end', () => { + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + let jsonO = JSON.parse(reqBody); + if(jsonO.method == "eth_sendTransaction"){ + commList[jsonO.id] = { + requestData: jsonO.params.data + }; + } + } + }); + + proxy.proxyRequest(req, res, { + target: `http://${_host}:${_port + 1}` + }); + + proxy.on('proxyRes', function (proxyRes, req, res) { + let resBody = []; + proxyRes.on('data', (b) => resBody.push(b)) + proxyRes.on('end', function () { + resBody = Buffer.concat(resBody).toString(); + try { + let jsonO = JSON.parse(resBody); + if(commList[jsonO.id]){ + commList[json0.id].transactionHash = resBody; + + // TODO: decode commlist + // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” + + delete commList[json0.id]; + } + } catch(e){ + // + } + }); + }); + + }); + + server.listen(_port); + } } diff --git a/lib/index.js b/lib/index.js index 338ee7fc..f3f6bb99 100644 --- a/lib/index.js +++ b/lib/index.js @@ -51,7 +51,12 @@ 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({ + contractsConfig: this.config.contractsConfig, + blockchainConfig: this.config.blockchainConfig, + logger: this.logger, + events: this.events + }); simulator.run(options); } diff --git a/package.json b/package.json index cd660c0a..57abdf87 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", From 84c01c3197ca131e317734acf7e070cd84522de9 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Thu, 7 Jun 2018 13:03:04 -0400 Subject: [PATCH 30/52] Extracted proxy to its own file --- lib/cmds/proxy.js | 52 +++++++++++++++++++++++++++++++++ lib/cmds/simulator.js | 67 ++++++------------------------------------- 2 files changed, 60 insertions(+), 59 deletions(-) create mode 100644 lib/cmds/proxy.js diff --git a/lib/cmds/proxy.js b/lib/cmds/proxy.js new file mode 100644 index 00000000..2e52645c --- /dev/null +++ b/lib/cmds/proxy.js @@ -0,0 +1,52 @@ +const httpProxy = require('http-proxy'); +const http = require('http'); + +exports.serve = function(host, port){ + let commList = {}; + + let proxy = httpProxy.createProxyServer({}); + let server = http.createServer((req, res) => { + + let reqBody = []; + req.on('data', (b) => { reqBody.push(b); }) + .on('end', () => { + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + let jsonO = JSON.parse(reqBody); + if(jsonO.method == "eth_sendTransaction"){ + commList[jsonO.id] = { + requestData: jsonO.params.data + }; + } + } + }); + + proxy.proxyRequest(req, res, { + target: `http://${host}:${port + 1}` + }); + + proxy.on('proxyRes', (proxyRes, req, res) => { + let resBody = []; + proxyRes.on('data', (b) => resBody.push(b)) + proxyRes.on('end', function () { + resBody = Buffer.concat(resBody).toString(); + try { + let jsonO = JSON.parse(resBody); + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = resBody; + + // TODO: decode commlist + // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” + + delete commList[jsonO.id]; + } + } catch(e){ + // + } + }); + }); + + }); + + server.listen(port); +} diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index d3d5a4c5..ddfb18cb 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -1,5 +1,5 @@ let shelljs = require('shelljs'); - +let proxy = require('./proxy'); class Simulator { constructor(options) { this.blockchainConfig = options.blockchainConfig; @@ -19,10 +19,11 @@ class Simulator { process.exit(); } - cmds.push("-p " + ((options.port || this.blockchainConfig.rpcPort || 8545) + 1)); - - - cmds.push("-h " + (options.host || this.blockchainConfig.rpcHost || 'localhost')); + let host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); + let port = (options.port || this.blockchainConfig.rpcPort || 8545); + + cmds.push("-p " + (port + 1)); + cmds.push("-h " + host); cmds.push("-a " + (options.numAccounts || 10)); cmds.push("-e " + (options.defaultBalance || 100)); cmds.push("-l " + (options.gasLimit || 8000000)); @@ -41,61 +42,9 @@ class Simulator { const program = ganache ? 'ganache-cli' : 'testrpc'; - shelljs.exec(`${program} ${cmds.join(' ')} &`, {async : true}); + shelljs.exec(`${program} ${cmds.join(' ')} &`, {async : true}); - let httpProxy = require('http-proxy'); - let http = require('http'); - let _port = options.port || this.blockchainConfig.rpcPort || 8545; - let _host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); - - let commList = {}; - - let proxy = httpProxy.createProxyServer({}); - let server = http.createServer((req, res) => { - - let reqBody = []; - req.on('data', (b) => { reqBody.push(b); }) - .on('end', () => { - reqBody = Buffer.concat(reqBody).toString(); - if(reqBody){ - let jsonO = JSON.parse(reqBody); - if(jsonO.method == "eth_sendTransaction"){ - commList[jsonO.id] = { - requestData: jsonO.params.data - }; - } - } - }); - - proxy.proxyRequest(req, res, { - target: `http://${_host}:${_port + 1}` - }); - - proxy.on('proxyRes', function (proxyRes, req, res) { - let resBody = []; - proxyRes.on('data', (b) => resBody.push(b)) - proxyRes.on('end', function () { - resBody = Buffer.concat(resBody).toString(); - try { - let jsonO = JSON.parse(resBody); - if(commList[jsonO.id]){ - commList[json0.id].transactionHash = resBody; - - // TODO: decode commlist - // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” - - delete commList[json0.id]; - } - } catch(e){ - // - } - }); - }); - - }); - - server.listen(_port); - + proxy.serve(host, port); } } From 05f5a145f1602571e17334737dd0e059528dcb8b Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Thu, 7 Jun 2018 15:13:35 -0400 Subject: [PATCH 31/52] Added proxy to blockchain --- lib/cmds/blockchain/blockchain.js | 14 +++++++++- lib/cmds/proxy.js | 44 +++++++++++++++++-------------- lib/cmds/simulator.js | 17 ++++++------ lib/index.js | 4 +-- 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 213ac4fe..b1e75a5f 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -45,9 +45,11 @@ var Blockchain = function(options) { targetGasLimit: this.blockchainConfig.targetGasLimit || false, light: this.blockchainConfig.light || false, fast: this.blockchainConfig.fast || false, - verbosity: this.blockchainConfig.verbosity + 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 +74,16 @@ var Blockchain = function(options) { this.client = new options.client({config: this.config, env: this.env, isDev: this.isDev}); }; +Blockchain.prototype.setupProxy = function(){ + if(this.blockchainConfig.proxy){ + const proxy = require('../proxy'); + proxy.serve(this.config.rpcHost, this.config.rpcPort, false); + proxy.serve(this.config.wsHost, this.config.wsPort, true); + this.config.rpcPort += 10; + this.config.wsPort += 10; + } +} + Blockchain.prototype.runCommand = function(cmd, options, callback) { console.log(__("running: %s", cmd.underline).green); if (this.blockchainConfig.silent) { diff --git a/lib/cmds/proxy.js b/lib/cmds/proxy.js index 2e52645c..0f809fb1 100644 --- a/lib/cmds/proxy.js +++ b/lib/cmds/proxy.js @@ -1,7 +1,7 @@ const httpProxy = require('http-proxy'); const http = require('http'); -exports.serve = function(host, port){ +exports.serve = function(host, port, ws){ let commList = {}; let proxy = httpProxy.createProxyServer({}); @@ -10,19 +10,24 @@ exports.serve = function(host, port){ let reqBody = []; req.on('data', (b) => { reqBody.push(b); }) .on('end', () => { - reqBody = Buffer.concat(reqBody).toString(); - if(reqBody){ - let jsonO = JSON.parse(reqBody); - if(jsonO.method == "eth_sendTransaction"){ - commList[jsonO.id] = { - requestData: jsonO.params.data - }; + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + let jsonO = JSON.parse(reqBody); + if(jsonO.method == "eth_sendTransaction"){ + commList[jsonO.id] = { + address: jsonO.params[0].to, + requestData: jsonO.params[0].data + }; + } } - } }); proxy.proxyRequest(req, res, { - target: `http://${host}:${port + 1}` + target: { + host: host, + port: port + 10, + ws: ws + } }); proxy.on('proxyRes', (proxyRes, req, res) => { @@ -31,15 +36,14 @@ exports.serve = function(host, port){ proxyRes.on('end', function () { resBody = Buffer.concat(resBody).toString(); try { - let jsonO = JSON.parse(resBody); - if(commList[jsonO.id]){ - commList[jsonO.id].transactionHash = resBody; - - // TODO: decode commlist - // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” - - delete commList[jsonO.id]; - } + let jsonO = JSON.parse(resBody); + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = jsonO.result; + // TODO: decode commlist + // TODO: send messages to console + // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” + delete commList[jsonO.id]; + } } catch(e){ // } @@ -49,4 +53,4 @@ exports.serve = function(host, port){ }); server.listen(port); -} +}; diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index ddfb18cb..c319e842 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -4,12 +4,9 @@ class Simulator { constructor(options) { this.blockchainConfig = options.blockchainConfig; this.logger = options.logger; - this.contractsConfig = options.contractsConfig; - this.events = options.events; } - run(options) { - let cmds = []; + run(options) { let cmds = []; const testrpc = shelljs.which('testrpc'); const ganache = shelljs.which('ganache-cli'); @@ -19,10 +16,11 @@ class Simulator { process.exit(); } + 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 + 1)); + cmds.push("-p " + (port + (useProxy ? 10 : 0))); cmds.push("-h " + host); cmds.push("-a " + (options.numAccounts || 10)); cmds.push("-e " + (options.defaultBalance || 100)); @@ -42,9 +40,12 @@ class Simulator { const program = ganache ? 'ganache-cli' : 'testrpc'; - shelljs.exec(`${program} ${cmds.join(' ')} &`, {async : true}); - - proxy.serve(host, port); + shelljs.exec(`${program} ${cmds.join(' ')}`, {async : true}); + + if(useProxy){ + proxy.serve(host, port); + } + } } diff --git a/lib/index.js b/lib/index.js index f3f6bb99..9cac7e81 100644 --- a/lib/index.js +++ b/lib/index.js @@ -52,10 +52,8 @@ class Embark { this.context = options.context || [constants.contexts.simulator, constants.contexts.blockchain]; let Simulator = require('./cmds/simulator.js'); let simulator = new Simulator({ - contractsConfig: this.config.contractsConfig, blockchainConfig: this.config.blockchainConfig, - logger: this.logger, - events: this.events + logger: this.logger }); simulator.run(options); } From bf25381fa6485033a17268715f909a6d2ba952ad Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 16:40:14 -0400 Subject: [PATCH 32/52] Rebasing changes from develop --- lib/cmds/blockchain/blockchain.js | 14 ++++--- lib/cmds/proxy.js | 56 -------------------------- lib/cmds/simulator.js | 7 +++- lib/core/engine.js | 39 ++++++++++++++++++ lib/core/proxy.js | 66 +++++++++++++++++++++++++++++++ lib/modules/solidity/solcW.js | 1 - package-lock.json | 54 ++++++++++++++++++++++--- 7 files changed, 167 insertions(+), 70 deletions(-) delete mode 100644 lib/cmds/proxy.js create mode 100644 lib/core/proxy.js diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index b1e75a5f..3bab4daa 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -76,13 +76,17 @@ var Blockchain = function(options) { Blockchain.prototype.setupProxy = function(){ if(this.blockchainConfig.proxy){ - const proxy = require('../proxy'); - proxy.serve(this.config.rpcHost, this.config.rpcPort, false); - proxy.serve(this.config.wsHost, this.config.wsPort, true); + 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 += 10; - this.config.wsPort += 10; + //this.config.wsPort += 10; } -} +}; Blockchain.prototype.runCommand = function(cmd, options, callback) { console.log(__("running: %s", cmd.underline).green); diff --git a/lib/cmds/proxy.js b/lib/cmds/proxy.js deleted file mode 100644 index 0f809fb1..00000000 --- a/lib/cmds/proxy.js +++ /dev/null @@ -1,56 +0,0 @@ -const httpProxy = require('http-proxy'); -const http = require('http'); - -exports.serve = function(host, port, ws){ - let commList = {}; - - let proxy = httpProxy.createProxyServer({}); - let server = http.createServer((req, res) => { - - let reqBody = []; - req.on('data', (b) => { reqBody.push(b); }) - .on('end', () => { - reqBody = Buffer.concat(reqBody).toString(); - if(reqBody){ - let jsonO = JSON.parse(reqBody); - if(jsonO.method == "eth_sendTransaction"){ - commList[jsonO.id] = { - address: jsonO.params[0].to, - requestData: jsonO.params[0].data - }; - } - } - }); - - proxy.proxyRequest(req, res, { - target: { - host: host, - port: port + 10, - ws: ws - } - }); - - proxy.on('proxyRes', (proxyRes, req, res) => { - let resBody = []; - proxyRes.on('data', (b) => resBody.push(b)) - proxyRes.on('end', function () { - resBody = Buffer.concat(resBody).toString(); - try { - let jsonO = JSON.parse(resBody); - if(commList[jsonO.id]){ - commList[jsonO.id].transactionHash = jsonO.result; - // TODO: decode commlist - // TODO: send messages to console - // ” SimpleStorage> set(5) | tx: 0xef234f16etc ” - delete commList[jsonO.id]; - } - } catch(e){ - // - } - }); - }); - - }); - - server.listen(port); -}; diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index c319e842..da819246 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -1,5 +1,7 @@ let shelljs = require('shelljs'); -let proxy = require('./proxy'); +let proxy = require('../core/proxy'); +const Ipc = require('../core/ipc'); + class Simulator { constructor(options) { this.blockchainConfig = options.blockchainConfig; @@ -43,7 +45,8 @@ class Simulator { shelljs.exec(`${program} ${cmds.join(' ')}`, {async : true}); if(useProxy){ - proxy.serve(host, port); + let ipcObject = new Ipc({ipcRole: 'client'}); + proxy.serve(ipcObject, host, port, false); } } diff --git a/lib/core/engine.js b/lib/core/engine.js index 28640f0d..c6a02012 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -184,6 +184,11 @@ 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'); @@ -219,6 +224,40 @@ class Engine { plugins: this.plugins }); + // Console logger + // TODO: extract to its own file + let addressToContract = {}; + this.ipc.on('log', (jsonObj) => { + if(jsonObj.type == 'contract-log'){ + if(!addressToContract[jsonObj.address]){ + let contractList = Object.keys(this.config.contractsConfig.contracts); + for(let i = 0; i < contractList.length; i++){ + let cont = this.config.contractsConfig.contracts[contractList[i]]; + if(!addressToContract[cont.deployedAddress.toLowerCase()]){ + let funcSignatures = {}; + cont.abiDefinition + .filter(func => func.type == "function") + .map(func => func.name + '(' + + (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + + ')') + .forEach(func => { + funcSignatures[utils.sha3(func).substring(0, 10)] = func; + }); + + addressToContract[cont.deployedAddress.toLowerCase()] = { + name: contractList[i], + functions: funcSignatures + }; + } + } + } + let funcHash = addressToContract[jsonObj.address].functions[jsonObj.data.substring(0, 10)]; + this.logger.debug(addressToContract[jsonObj.address].name + "." + funcHash + " : " + jsonObj.transactionHash); + } else { + this.logger.info(jsonObj); + } + }); + this.events.on('file-event', function (fileType) { clearTimeout(self.fileTimeout); self.fileTimeout = setTimeout(() => { diff --git a/lib/core/proxy.js b/lib/core/proxy.js new file mode 100644 index 00000000..4e975d16 --- /dev/null +++ b/lib/core/proxy.js @@ -0,0 +1,66 @@ +const httpProxy = require('http-proxy'); +const http = require('http'); + +exports.serve = function(ipc, host, port, ws){ + let commList = {}; + + let proxy = httpProxy.createProxyServer({ + target: { + host: host, + port: port + 10, + ws: ws + } + }); + + proxy.on('proxyRes', (proxyRes) => { + let resBody = []; + proxyRes.on('data', (b) => resBody.push(b)); + proxyRes.on('end', function () { + resBody = Buffer.concat(resBody).toString(); + try { + let jsonO = JSON.parse(resBody); + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = jsonO.result; + if(ipc.connected && !ipc.connecting){ + ipc.request('log', commList[jsonO.id]); + } else { + ipc.connecting = true; + ipc.connect((err) => { + ipc.connecting = false; + }); + } + delete commList[jsonO.id]; + } + } catch(e){ + // + } + }); + }); + + let server = http.createServer((req, res) => { + let reqBody = []; + req.on('data', (b) => { reqBody.push(b); }) + .on('end', () => { + reqBody = Buffer.concat(reqBody).toString(); + if(reqBody){ + let jsonO = JSON.parse(reqBody); + if(jsonO.method == "eth_sendTransaction"){ + commList[jsonO.id] = { + type: 'contract-log', + address: jsonO.params[0].to, + data: jsonO.params[0].data + }; + } + } + }); + + if(ws){ + proxy.ws(req, res); + } else { + proxy.web(req, res); + } + + }); + + server.listen(port); +}; 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/package-lock.json b/package-lock.json index 2595336b..44543521 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", @@ -8465,6 +8492,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 +9176,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 +10268,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", From c1621c402975175fac3b845f1d49af222b8acd70 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 13:44:16 -0400 Subject: [PATCH 33/52] Websocket support --- lib/cmds/blockchain/blockchain.js | 4 ++-- lib/core/proxy.js | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 3bab4daa..ea492cdf 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -82,9 +82,9 @@ Blockchain.prototype.setupProxy = function(){ 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); + proxy.serve(ipcObject, this.config.wsHost, this.config.wsPort, true); this.config.rpcPort += 10; - //this.config.wsPort += 10; + this.config.wsPort += 10; } }; diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 4e975d16..8cdacef4 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -7,9 +7,9 @@ exports.serve = function(ipc, host, port, ws){ let proxy = httpProxy.createProxyServer({ target: { host: host, - port: port + 10, - ws: ws - } + port: port + 10 + }, + ws: ws }); proxy.on('proxyRes', (proxyRes) => { @@ -32,7 +32,7 @@ exports.serve = function(ipc, host, port, ws){ delete commList[jsonO.id]; } } catch(e){ - // + // } }); }); @@ -54,13 +54,16 @@ exports.serve = function(ipc, host, port, ws){ } }); - if(ws){ - proxy.ws(req, res); - } else { + if(!ws){ proxy.web(req, res); } - }); + if(ws){ + server.on('upgrade', function (req, socket, head) { + proxy.ws(req, socket, head); + }); + } + server.listen(port); }; From 8ef2dc124faf965f38fccf930bc5a0f438174a09 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 14:36:35 -0400 Subject: [PATCH 34/52] Extracted console logging to its own file --- lib/core/engine.js | 36 +---------------- lib/modules/console_listener/index.js | 57 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 35 deletions(-) create mode 100644 lib/modules/console_listener/index.js diff --git a/lib/core/engine.js b/lib/core/engine.js index c6a02012..f0d8fb08 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -188,13 +188,13 @@ class Engine { 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({ @@ -224,40 +224,6 @@ class Engine { plugins: this.plugins }); - // Console logger - // TODO: extract to its own file - let addressToContract = {}; - this.ipc.on('log', (jsonObj) => { - if(jsonObj.type == 'contract-log'){ - if(!addressToContract[jsonObj.address]){ - let contractList = Object.keys(this.config.contractsConfig.contracts); - for(let i = 0; i < contractList.length; i++){ - let cont = this.config.contractsConfig.contracts[contractList[i]]; - if(!addressToContract[cont.deployedAddress.toLowerCase()]){ - let funcSignatures = {}; - cont.abiDefinition - .filter(func => func.type == "function") - .map(func => func.name + '(' + - (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + - ')') - .forEach(func => { - funcSignatures[utils.sha3(func).substring(0, 10)] = func; - }); - - addressToContract[cont.deployedAddress.toLowerCase()] = { - name: contractList[i], - functions: funcSignatures - }; - } - } - } - let funcHash = addressToContract[jsonObj.address].functions[jsonObj.data.substring(0, 10)]; - this.logger.debug(addressToContract[jsonObj.address].name + "." + funcHash + " : " + jsonObj.transactionHash); - } else { - this.logger.info(jsonObj); - } - }); - this.events.on('file-event', function (fileType) { clearTimeout(self.fileTimeout); self.fileTimeout = setTimeout(() => { diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js new file mode 100644 index 00000000..8194c03e --- /dev/null +++ b/lib/modules/console_listener/index.js @@ -0,0 +1,57 @@ +const utils = require('../../utils/utils.js'); + +class ConsoleListener { + constructor(embark, options) { + this.logger = embark.logger; + this.ipc = options.ipc; + this.addressToContract = []; + this.contractsConfig = embark.config.contractsConfig; + this.listenForLogRequests(); + } + + _updateContractList(){ + Object.keys(this.contractsConfig.contracts).forEach(contractName => { + let contract = this.contractsConfig.contracts[contractName]; + let address = contract.deployedAddress.toLowerCase(); + + if(!this.addressToContract[address]){ + let funcSignatures = {}; + contract.abiDefinition + .filter(func => func.type == "function") + .map(func => func.name + + '(' + + (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + + ')') + .forEach(func => { + funcSignatures[utils.sha3(func).substring(0, 10)] = func; + }); + + this.addressToContract[address] = { + name: contractName, + functions: funcSignatures + }; + } + }); + } + + listenForLogRequests(){ + this.ipc.on('log', (request) => { + if(request.type == 'contract-log'){ + + let {address, data, transactionHash} = request; + if(!this.addressToContract[address]){ + this._updateContractList(); + } + + let name = this.addressToContract[address].name; + let funcHash = this.addressToContract[address].functions[data.substring(0, 10)]; + + this.logger.debug(`${name}.${funcHash} : ${transactionHash}`); + } else { + this.logger.debug(request); + } + }); + } +} + +module.exports = ConsoleListener; From 39d510cef42e5326400987db6cc91744dc22e24b Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 15:30:20 -0400 Subject: [PATCH 35/52] Displaying status, gas and block number --- lib/core/proxy.js | 18 +++++++++++++++++- lib/modules/console_listener/index.js | 9 ++++++--- lib/utils/utils.js | 5 +++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 8cdacef4..c4e00c56 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -3,6 +3,8 @@ const http = require('http'); exports.serve = function(ipc, host, port, ws){ let commList = {}; + let transactions = {}; + let receipts = {}; let proxy = httpProxy.createProxyServer({ target: { @@ -21,14 +23,23 @@ exports.serve = function(ipc, host, port, ws){ let jsonO = JSON.parse(resBody); if(commList[jsonO.id]){ commList[jsonO.id].transactionHash = jsonO.result; + transactions[jsonO.result] = {commListId: jsonO.id}; + } else if(receipts[jsonO.id]){ + 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[jsonO.id]); + ipc.request('log', commList[receipts[jsonO.id]]); } else { ipc.connecting = true; ipc.connect((err) => { ipc.connecting = false; }); } + + delete transactions[commList[receipts[jsonO.id]].transactionHash]; + delete receipts[jsonO.id]; delete commList[jsonO.id]; } } catch(e){ @@ -50,6 +61,11 @@ exports.serve = function(ipc, host, port, ws){ 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; + } } } }); diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 8194c03e..00cfbaf7 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -38,15 +38,18 @@ class ConsoleListener { this.ipc.on('log', (request) => { if(request.type == 'contract-log'){ - let {address, data, transactionHash} = request; + let {address, data, transactionHash, blockNumber, gasUsed, status} = request; if(!this.addressToContract[address]){ this._updateContractList(); } let name = this.addressToContract[address].name; let funcHash = this.addressToContract[address].functions[data.substring(0, 10)]; - - this.logger.debug(`${name}.${funcHash} : ${transactionHash}`); + + gasUsed = utils.hexToNumber(gasUsed); + blockNumber = utils.hexToNumber(blockNumber); + + this.logger.debug(`${name}.${funcHash} : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); } else { this.logger.debug(request); } diff --git a/lib/utils/utils.js b/lib/utils/utils.js index 6d92422f..a57b3ba5 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -185,6 +185,10 @@ function getExternalContractUrl(file) { }; } +function hexToNumber(hex){ + return Web3.utils.hexToNumber(hex); +} + function toChecksumAddress(address) { return Web3.utils.toChecksumAddress(address); } @@ -253,6 +257,7 @@ module.exports = { httpsGet: httpsGet, httpGetJson: httpGetJson, httpsGetJson: httpsGetJson, + hexToNumber: hexToNumber, runCmd: runCmd, cd: cd, sed: sed, From c9a2014ac7bda0f68b2a2bda5a334c83af48f2f9 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 16:34:35 -0400 Subject: [PATCH 36/52] Formatting input parameters --- lib/modules/console_listener/index.js | 33 ++++++++++++++++++++------- lib/utils/utils.js | 6 +++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 00cfbaf7..5fd1a3ec 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -18,12 +18,18 @@ class ConsoleListener { let funcSignatures = {}; contract.abiDefinition .filter(func => func.type == "function") - .map(func => func.name + - '(' + - (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + - ')') + .map(func => { + return { + name: func.name + + '(' + + (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + + ')', + abi: func, + functionName: func.name + }; + }) .forEach(func => { - funcSignatures[utils.sha3(func).substring(0, 10)] = func; + funcSignatures[utils.sha3(func.name).substring(0, 10)] = func; }); this.addressToContract[address] = { @@ -44,12 +50,23 @@ class ConsoleListener { } let name = this.addressToContract[address].name; - let funcHash = this.addressToContract[address].functions[data.substring(0, 10)]; - + let func = this.addressToContract[address].functions[data.substring(0, 10)]; + let functionName = func.functionName; + + let 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.debug(`${name}.${funcHash} : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); + this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); } else { this.logger.debug(request); } diff --git a/lib/utils/utils.js b/lib/utils/utils.js index a57b3ba5..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'); @@ -189,6 +190,10 @@ 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); } @@ -258,6 +263,7 @@ module.exports = { httpGetJson: httpGetJson, httpsGetJson: httpsGetJson, hexToNumber: hexToNumber, + decodeParams: decodeParams, runCmd: runCmd, cd: cd, sed: sed, From a669538e7097d4e46608e635b3c0663399197f52 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 16:59:33 -0400 Subject: [PATCH 37/52] Adding proxy to config, and closing on error --- lib/core/proxy.js | 4 ++++ templates/boilerplate/config/blockchain.json | 1 + templates/demo/config/blockchain.json | 1 + 3 files changed, 6 insertions(+) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index c4e00c56..60054a42 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -14,6 +14,10 @@ exports.serve = function(ipc, host, port, ws){ ws: ws }); + proxy.on('error', function (err, req, res) { + proxy.close(); + }); + proxy.on('proxyRes', (proxyRes) => { let resBody = []; proxyRes.on('data', (b) => resBody.push(b)); 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" }, From 0f853ba8412260131cec001e0e3919d1bcc59c87 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 17:02:45 -0400 Subject: [PATCH 38/52] Typo --- lib/cmds/blockchain/blockchain.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index ea492cdf..4841e4bf 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -45,7 +45,7 @@ var Blockchain = function(options) { targetGasLimit: this.blockchainConfig.targetGasLimit || false, light: this.blockchainConfig.light || false, fast: this.blockchainConfig.fast || false, - verbosity: this.blockchainConfig.verbosity, + verbosity: this.blockchainConfig.verbosity }; this.setupProxy(); From 09c11662aa96667651e7823209f9a5511d267178 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 17:22:53 -0400 Subject: [PATCH 39/52] Removing unused variables --- lib/core/proxy.js | 4 +- lib/modules/console_listener/index.js | 60 ++++++++++++++------------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 60054a42..14b33025 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -14,7 +14,7 @@ exports.serve = function(ipc, host, port, ws){ ws: ws }); - proxy.on('error', function (err, req, res) { + proxy.on('error', function () { proxy.close(); }); @@ -37,7 +37,7 @@ exports.serve = function(ipc, host, port, ws){ ipc.request('log', commList[receipts[jsonO.id]]); } else { ipc.connecting = true; - ipc.connect((err) => { + ipc.connect(() => { ipc.connecting = false; }); } diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 5fd1a3ec..d1330345 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -41,36 +41,40 @@ class ConsoleListener { } listenForLogRequests(){ - this.ipc.on('log', (request) => { - if(request.type == 'contract-log'){ + try { + this.ipc.on('log', (request) => { + if(request.type == 'contract-log'){ - let {address, data, transactionHash, blockNumber, gasUsed, status} = request; - if(!this.addressToContract[address]){ - this._updateContractList(); + let {address, data, transactionHash, blockNumber, gasUsed, status} = request; + if(!this.addressToContract[address]){ + this._updateContractList(); + } + + let name = this.addressToContract[address].name; + let func = this.addressToContract[address].functions[data.substring(0, 10)]; + let functionName = func.functionName; + + let 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.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); + } else { + this.logger.debug(request); } - - let name = this.addressToContract[address].name; - let func = this.addressToContract[address].functions[data.substring(0, 10)]; - let functionName = func.functionName; - - let 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.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); - } else { - this.logger.debug(request); - } - }); + }); + } catch(e) { + // + } } } From f467fc5a31b5694fe23f86792b9ddf7772d0d833 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 8 Jun 2018 19:08:32 -0400 Subject: [PATCH 40/52] Launching ipc connection depending on role --- lib/modules/console_listener/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index d1330345..6b1aaf52 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -41,7 +41,7 @@ class ConsoleListener { } listenForLogRequests(){ - try { + if(this.ipc.ipcRole === 'server'){ this.ipc.on('log', (request) => { if(request.type == 'contract-log'){ @@ -72,8 +72,6 @@ class ConsoleListener { this.logger.debug(request); } }); - } catch(e) { - // } } } From 6040509942b335d52d8177cd91e5c59d40ae273c Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 09:02:52 -0400 Subject: [PATCH 41/52] Adding line break --- lib/cmds/simulator.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index da819246..4c0a89f0 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -8,7 +8,8 @@ class Simulator { this.logger = options.logger; } - run(options) { let cmds = []; + run(options) { + let cmds = []; const testrpc = shelljs.which('testrpc'); const ganache = shelljs.which('ganache-cli'); From 80052fc5e13f44fb8bbffcc03fe7f74b4abbfff2 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 09:19:24 -0400 Subject: [PATCH 42/52] Displays json as a string in the console --- lib/modules/console_listener/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 6b1aaf52..6d022fdf 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -69,7 +69,7 @@ class ConsoleListener { this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); } else { - this.logger.debug(request); + this.logger.debug(JSON.stringify(request)); } }); } From a4985fde4007fc65b5df0e8fa7c0e6b25c369e11 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 11 Jun 2018 12:02:00 -0400 Subject: [PATCH 43/52] make proxy mode the default --- lib/cmds/blockchain/blockchain.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 4841e4bf..67a7b05b 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -74,18 +74,19 @@ var Blockchain = function(options) { this.client = new options.client({config: this.config, env: this.env, isDev: this.isDev}); }; -Blockchain.prototype.setupProxy = function(){ - if(this.blockchainConfig.proxy){ - 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 += 10; - this.config.wsPort += 10; +Blockchain.prototype.setupProxy = function() { + if (this.blockchainConfig.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 += 10; + this.config.wsPort += 10; }; Blockchain.prototype.runCommand = function(cmd, options, callback) { From e46f6aa5b7de66638dd3a423b14905c6cd4f4cdf Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 11 Jun 2018 12:13:30 -0400 Subject: [PATCH 44/52] color output --- lib/modules/console_listener/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 6d022fdf..ca058035 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -67,9 +67,9 @@ class ConsoleListener { gasUsed = utils.hexToNumber(gasUsed); blockNumber = utils.hexToNumber(blockNumber); - this.logger.debug(`${name}.${functionName}(${paramString}) : ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); + this.logger.info(`Blockchain>`.underline + ` ${name}.${functionName}(${paramString})`.bold + ` | ${transactionHash} | gas:${gasUsed} | blk:${blockNumber} | status:${status}`); } else { - this.logger.debug(JSON.stringify(request)); + this.logger.info(JSON.stringify(request)); } }); } From 48a3f2afdcfa711ca892ae4b1a9b893523ffdc85 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 16:43:08 -0400 Subject: [PATCH 45/52] Fixing conflicts --- lib/cmds/blockchain/blockchain.js | 9 ++ lib/cmds/simulator.js | 5 +- lib/constants.json | 3 +- lib/core/proxy.js | 61 +++++++------ lib/modules/console_listener/index.js | 124 ++++++++++++++------------ 5 files changed, 113 insertions(+), 89 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 67a7b05b..1a9e8f86 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'); @@ -83,10 +84,18 @@ Blockchain.prototype.setupProxy = function() { let ipcObject = new Ipc({ipcRole: 'client'}); +<<<<<<< HEAD proxy.serve(ipcObject, this.config.rpcHost, this.config.rpcPort, false); proxy.serve(ipcObject, this.config.wsHost, this.config.wsPort, true); this.config.rpcPort += 10; this.config.wsPort += 10; +======= + 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; + } +>>>>>>> Changes based on code review }; Blockchain.prototype.runCommand = function(cmd, options, callback) { diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index 4c0a89f0..638020e3 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -1,6 +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) { @@ -8,7 +9,7 @@ class Simulator { this.logger = options.logger; } - run(options) { + run(options) { let cmds = []; const testrpc = shelljs.which('testrpc'); @@ -23,7 +24,7 @@ class Simulator { let host = (options.host || this.blockchainConfig.rpcHost || 'localhost'); let port = (options.port || this.blockchainConfig.rpcPort || 8545); - cmds.push("-p " + (port + (useProxy ? 10 : 0))); + 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)); 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/proxy.js b/lib/core/proxy.js index 14b33025..71e2a95a 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -1,5 +1,6 @@ const httpProxy = require('http-proxy'); const http = require('http'); +const constants = require('../constants.json'); exports.serve = function(ipc, host, port, ws){ let commList = {}; @@ -8,14 +9,15 @@ exports.serve = function(ipc, host, port, ws){ let proxy = httpProxy.createProxyServer({ target: { - host: host, - port: port + 10 + host, + port: port + constants.blockchain.servicePortOnProxy }, ws: ws }); proxy.on('error', function () { - proxy.close(); + console.log(__("Error forwarding requests to blockchain/simulator")); + process.exit(); }); proxy.on('proxyRes', (proxyRes) => { @@ -23,31 +25,34 @@ exports.serve = function(ipc, host, port, ws){ proxyRes.on('data', (b) => resBody.push(b)); proxyRes.on('end', function () { resBody = Buffer.concat(resBody).toString(); - try { - let jsonO = JSON.parse(resBody); - if(commList[jsonO.id]){ - commList[jsonO.id].transactionHash = jsonO.result; - transactions[jsonO.result] = {commListId: jsonO.id}; - } else if(receipts[jsonO.id]){ - 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]; + let jsonO; + try { + jsonO = JSON.parse(resBody); + } catch(e) { + return; + } + + if(commList[jsonO.id]){ + commList[jsonO.id].transactionHash = jsonO.result; + transactions[jsonO.result] = {commListId: jsonO.id}; + } else if(receipts[jsonO.id]){ + 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; + }); } - } catch(e){ - // + + delete transactions[commList[receipts[jsonO.id]].transactionHash]; + delete receipts[jsonO.id]; + delete commList[jsonO.id]; } }); }); @@ -59,13 +64,13 @@ exports.serve = function(ipc, host, port, ws){ reqBody = Buffer.concat(reqBody).toString(); if(reqBody){ let jsonO = JSON.parse(reqBody); - if(jsonO.method == "eth_sendTransaction"){ + 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"){ + } 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; diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index ca058035..64f02dc8 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -4,75 +4,83 @@ 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.listenForLogRequests(); - } + this.contractsDeployed = false; - _updateContractList(){ - Object.keys(this.contractsConfig.contracts).forEach(contractName => { - let contract = this.contractsConfig.contracts[contractName]; - let address = contract.deployedAddress.toLowerCase(); + this._listenForLogRequests(); - if(!this.addressToContract[address]){ - let funcSignatures = {}; - contract.abiDefinition - .filter(func => func.type == "function") - .map(func => { - return { - name: func.name + - '(' + - (func.inputs ? func.inputs.map(input => input.type).join(',') : '') + - ')', - abi: func, - functionName: func.name - }; - }) - .forEach(func => { - funcSignatures[utils.sha3(func.name).substring(0, 10)] = func; - }); - - this.addressToContract[address] = { - name: contractName, - functions: funcSignatures - }; - } + this.events.on("contractsDeployed", () => { + this.contractsDeployed = true; }); } - listenForLogRequests(){ - if(this.ipc.ipcRole === 'server'){ - this.ipc.on('log', (request) => { - if(request.type == 'contract-log'){ - - let {address, data, transactionHash, blockNumber, gasUsed, status} = request; - if(!this.addressToContract[address]){ - this._updateContractList(); - } - - let name = this.addressToContract[address].name; - let func = this.addressToContract[address].functions[data.substring(0, 10)]; - let functionName = func.functionName; - - let 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 + ", "; + _updateContractList(){ + this.events.request("contracts:list", (_err, contractsList) => { + if(_err) return; + contractsList.forEach(contract => { + 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 + }; }); - 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)); + 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)); + } + }); } } From 38e6a9571d8c2d86f22f8a8bbc9a3b24fcd1cde0 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 16:26:32 -0400 Subject: [PATCH 46/52] Updating tests --- lib/cmds/blockchain/blockchain.js | 3 +++ test/blockchain.js | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 1a9e8f86..bcb6dcce 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -76,9 +76,12 @@ var Blockchain = function(options) { }; 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'); 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(); }); From 03483052ea625c6037857ba6f3c520602fae43c8 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 16:35:42 -0400 Subject: [PATCH 47/52] Adding error messages --- lib/core/proxy.js | 1 + lib/modules/console_listener/index.js | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 71e2a95a..ebac2faa 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -30,6 +30,7 @@ exports.serve = function(ipc, host, port, ws){ try { jsonO = JSON.parse(resBody); } catch(e) { + console.log(__("Cannot parse node response")); return; } diff --git a/lib/modules/console_listener/index.js b/lib/modules/console_listener/index.js index 64f02dc8..e5c8874d 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -18,7 +18,10 @@ class ConsoleListener { _updateContractList(){ this.events.request("contracts:list", (_err, contractsList) => { - if(_err) return; + if(_err) { + this.logger.error(__("no contracts found")); + return; + } contractsList.forEach(contract => { let address = contract.deployedAddress.toLowerCase(); if(!this.addressToContract[address]){ From 9e920696672dd97fe781c1b7823b4080f8dab750 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 16:44:34 -0400 Subject: [PATCH 48/52] Fixing conflicts --- lib/cmds/blockchain/blockchain.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index bcb6dcce..dc17da8b 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -87,18 +87,10 @@ Blockchain.prototype.setupProxy = function() { let ipcObject = new Ipc({ipcRole: 'client'}); -<<<<<<< HEAD proxy.serve(ipcObject, this.config.rpcHost, this.config.rpcPort, false); proxy.serve(ipcObject, this.config.wsHost, this.config.wsPort, true); - this.config.rpcPort += 10; - this.config.wsPort += 10; -======= - 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; - } ->>>>>>> Changes based on code review + this.config.rpcPort += constants.blockchain.servicePortOnProxy; + this.config.wsPort += constants.blockchain.servicePortOnProxy; }; Blockchain.prototype.runCommand = function(cmd, options, callback) { From a50e7c25a95425f6d4bc269568dc2b1a2a7a069b Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 16:46:57 -0400 Subject: [PATCH 49/52] Not all messages received are json objects --- lib/core/proxy.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index ebac2faa..71e2a95a 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -30,7 +30,6 @@ exports.serve = function(ipc, host, port, ws){ try { jsonO = JSON.parse(resBody); } catch(e) { - console.log(__("Cannot parse node response")); return; } From 3ae6bbf5a48900e6ed28f9db73274459173f461f Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Mon, 11 Jun 2018 17:14:02 -0400 Subject: [PATCH 50/52] Adding proxy to testapp --- test_apps/test_app/config/blockchain.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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", From a9065b1eaeb620b41d522e0bfb48c41b5b12b9d5 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Tue, 12 Jun 2018 08:50:49 -0400 Subject: [PATCH 51/52] Websocket handling --- lib/core/proxy.js | 121 ++++++++++++++++---------- lib/modules/console_listener/index.js | 8 +- package.json | 1 + 3 files changed, 82 insertions(+), 48 deletions(-) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 71e2a95a..66784549 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -2,11 +2,63 @@ const httpProxy = require('http-proxy'); const http = require('http'); const constants = require('../constants.json'); -exports.serve = function(ipc, host, port, ws){ - let commList = {}; - let transactions = {}; - let receipts = {}; +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, @@ -25,34 +77,8 @@ exports.serve = function(ipc, host, port, ws){ proxyRes.on('data', (b) => resBody.push(b)); proxyRes.on('end', function () { resBody = Buffer.concat(resBody).toString(); - - let jsonO; - try { - jsonO = JSON.parse(resBody); - } catch(e) { - return; - } - - if(commList[jsonO.id]){ - commList[jsonO.id].transactionHash = jsonO.result; - transactions[jsonO.result] = {commListId: jsonO.id}; - } else if(receipts[jsonO.id]){ - 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]; + if(resBody){ + parseResponse(ipc, resBody); } }); }); @@ -63,19 +89,7 @@ exports.serve = function(ipc, host, port, ws){ .on('end', () => { reqBody = Buffer.concat(reqBody).toString(); if(reqBody){ - let jsonO = JSON.parse(reqBody); - 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; - } - } + parseRequest(reqBody); } }); @@ -85,9 +99,26 @@ exports.serve = function(ipc, host, port, ws){ }); 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/modules/console_listener/index.js b/lib/modules/console_listener/index.js index e5c8874d..210b6ae2 100644 --- a/lib/modules/console_listener/index.js +++ b/lib/modules/console_listener/index.js @@ -8,11 +8,11 @@ class ConsoleListener { this.addressToContract = []; this.contractsConfig = embark.config.contractsConfig; this.contractsDeployed = false; - this._listenForLogRequests(); this.events.on("contractsDeployed", () => { this.contractsDeployed = true; + this._updateContractList(); }); } @@ -23,6 +23,8 @@ class ConsoleListener { return; } contractsList.forEach(contract => { + if(!contract.deployedAddress) return; + let address = contract.deployedAddress.toLowerCase(); if(!this.addressToContract[address]){ let funcSignatures = {}; @@ -49,7 +51,7 @@ class ConsoleListener { }); } - _listenForLogRequests(){ + _listenForLogRequests(){ if(this.ipc.ipcRole !== 'server') return; this.ipc.on('log', (request) => { if(request.type == 'contract-log'){ @@ -59,9 +61,9 @@ class ConsoleListener { 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; diff --git a/package.json b/package.json index 57abdf87..363d1f06 100644 --- a/package.json +++ b/package.json @@ -65,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", From 8f52dd4cf326ff8cfeef7922ce867716a1fd2d04 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Tue, 12 Jun 2018 10:15:54 -0400 Subject: [PATCH 52/52] Missing semicolon --- lib/core/proxy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/proxy.js b/lib/core/proxy.js index 66784549..4a2a6bd4 100644 --- a/lib/core/proxy.js +++ b/lib/core/proxy.js @@ -56,7 +56,7 @@ const parseResponse = function(ipc, resBody){ delete receipts[jsonO.id]; delete commList[jsonO.id]; } -} +}; exports.serve = function(ipc, host, port, ws){ let proxy = httpProxy.createProxyServer({