From 8044b9e0c5c0cf00776d4c7a289db4323d6e610d Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Thu, 26 Dec 2019 10:48:27 -0500 Subject: [PATCH] refactor recorder logic to extract modal and confirm dialogs out, use blockchain class --- package-lock.json | 6 +- src/app/tabs/runTab/model/recorder.js | 92 ++++++++++----------------- src/app/tabs/runTab/recorder.js | 38 ++++++++++- src/app/udapp/run-tab.js | 6 +- 4 files changed, 77 insertions(+), 65 deletions(-) diff --git a/package-lock.json b/package-lock.json index c789aacdc0..6ae97f99eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17522,9 +17522,9 @@ } }, "solc": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.5.13.tgz", - "integrity": "sha512-osybDVPGjAqcmSKLU3vh5iHuxbhGlJjQI5ZvI7nRDR0fgblQqYte4MGvNjbew8DPvCrmoH0ZBiz/KBBLlPxfMg==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.6.0.tgz", + "integrity": "sha512-fYVRKbJLbg0oETBuAJN/ts0X/hj2YgOAl3ly3nrm/qhleVr22ecl3OSXW3hRmOWvH81hJ2KHRYRQWgqioK6d0A==", "dev": true, "requires": { "command-exists": "^1.2.8", diff --git a/src/app/tabs/runTab/model/recorder.js b/src/app/tabs/runTab/model/recorder.js index b25070aac2..73c15a15a7 100644 --- a/src/app/tabs/runTab/model/recorder.js +++ b/src/app/tabs/runTab/model/recorder.js @@ -288,7 +288,41 @@ class Recorder { return address } - runScenario (continueCb, promptCb, alertCb, confirmDialog, modalDialog, logCallBack, cb) { + fromWei (value, doTypeConversion, unit) { + if (doTypeConversion) { + return Web3.utils.fromWei(typeConversion.toInt(value), unit || 'ether') + } + return Web3.utils.fromWei(value.toString(10), unit || 'ether') + } + + toWei (value, unit) { + return Web3.utils.toWei(value, unit || 'gwei') + } + + calculateFee (gas, gasPrice, unit) { + return Web3.utils.toBN(gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10), unit || 'gwei'))) + } + + determineGasFees (tx) { + const determineGasFeesCb = (gasPrice, cb) => { + let txFeeText, priceStatus + // TODO: this try catch feels like an anti pattern, can/should be + // removed, but for now keeping the original logic + try { + var fee = this.calculateFee(tx.gas, gasPrice) + txFeeText = ' ' + this.fromWei(fee, false, 'ether') + ' Ether' + priceStatus = true + } catch (e) { + txFeeText = ' Please fix this issue before sending any transaction. ' + e.message + priceStatus = false + } + cb(txFeeText, priceStatus) + } + + return determineGasFeesCb + } + + runScenario (continueCb, promptCb, alertCb, confirmationCb, logCallBack, cb) { var currentFile = this.config.get('currentFile') this.fileManager.fileProviderOf(currentFile).get(currentFile, (error, json) => { if (error) { @@ -312,62 +346,6 @@ class Recorder { return } - var confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => { - if (network.name !== 'Main') { - return continueTxExecution(null) - } - var amount = Web3.utils.fromWei(typeConversion.toInt(tx.value), 'ether') - - // TODO: there is still a UI dependency to remove here, it's still too coupled at this point to remove easily - var content = confirmDialog(tx, amount, gasEstimation, this.recorder, - (gasPrice, cb) => { - let txFeeText, priceStatus - // TODO: this try catch feels like an anti pattern, can/should be - // removed, but for now keeping the original logic - try { - var fee = Web3.utils.toBN(tx.gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10), 'gwei'))) - txFeeText = ' ' + Web3.utils.fromWei(fee.toString(10), 'ether') + ' Ether' - priceStatus = true - } catch (e) { - txFeeText = ' Please fix this issue before sending any transaction. ' + e.message - priceStatus = false - } - cb(txFeeText, priceStatus) - }, - (cb) => { - this.executionContext.web3().eth.getGasPrice((error, gasPrice) => { - var warnMessage = ' Please fix this issue before sending any transaction. ' - if (error) { - return cb('Unable to retrieve the current network gas price.' + warnMessage + error) - } - try { - var gasPriceValue = Web3.utils.fromWei(gasPrice.toString(10), 'gwei') - cb(null, gasPriceValue) - } catch (e) { - cb(warnMessage + e.message, null, false) - } - }) - } - ) - modalDialog('Confirm transaction', content, - { label: 'Confirm', - fn: () => { - this.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked) - // TODO: check if this is check is still valid given the refactor - if (!content.gasPriceStatus) { - cancelCb('Given gas price is not correct') - } else { - var gasPrice = Web3.utils.toWei(content.querySelector('#gasprice').value, 'gwei') - continueTxExecution(gasPrice) - } - }}, { - label: 'Cancel', - fn: () => { - return cancelCb('Transaction canceled by user.') - } - }) - } - this.run(txArray, accounts, options, abis, linkReferences, confirmationCb, continueCb, promptCb, alertCb, logCallBack, (abi, address, contractName) => { cb(null, abi, address, contractName) }) diff --git a/src/app/tabs/runTab/recorder.js b/src/app/tabs/runTab/recorder.js index 2dca5afbe6..cbef6f1d71 100644 --- a/src/app/tabs/runTab/recorder.js +++ b/src/app/tabs/runTab/recorder.js @@ -10,7 +10,8 @@ var confirmDialog = require('../../ui/confirmDialog') class RecorderUI { - constructor (recorder, logCallBack) { + constructor (blockchain, recorder, logCallBack) { + this.blockchain = blockchain this.recorder = recorder this.logCallBack = logCallBack this.event = new EventManager() @@ -63,8 +64,10 @@ class RecorderUI { modalDialogCustom.alert(msg) } + const confirmationCb = this.getConfirmationCb(modalDialog, confirmDialog) + // TODO: there is still a UI dependency to remove here, it's still too coupled at this point to remove easily - this.recorder.runScenario(continueCb, promptCb, alertCb, confirmDialog, modalDialog, this.logCallBack, (error, abi, address, contractName) => { + this.recorder.runScenario(continueCb, promptCb, alertCb, confirmationCb, this.logCallBack, (error, abi, address, contractName) => { if (error) { return modalDialogCustom.alert(error) } @@ -73,6 +76,37 @@ class RecorderUI { }) } + getConfirmationCb (modalDialog, confirmDialog) { + const confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => { + if (network.name !== 'Main') { + return continueTxExecution(null) + } + const amount = this.recorder.fromWei(tx.value, true, 'ether') + const content = confirmDialog(tx, amount, gasEstimation, null, this.recorder.determineGasFees(tx), this.blockchain.determineGasPrice) + + modalDialog('Confirm transaction', content, + { label: 'Confirm', + fn: () => { + this.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked) + // TODO: check if this is check is still valid given the refactor + if (!content.gasPriceStatus) { + cancelCb('Given gas price is not correct') + } else { + var gasPrice = this.recorder.toWei(content.querySelector('#gasprice').value, 'gwei') + continueTxExecution(gasPrice) + } + }}, { + label: 'Cancel', + fn: () => { + return cancelCb('Transaction canceled by user.') + } + } + ) + } + + return confirmationCb + } + triggerRecordButton () { this.recorder.saveScenario( (path, cb) => { diff --git a/src/app/udapp/run-tab.js b/src/app/udapp/run-tab.js index a9e33c7184..41124684f6 100644 --- a/src/app/udapp/run-tab.js +++ b/src/app/udapp/run-tab.js @@ -41,6 +41,7 @@ export class RunTab extends LibraryPlugin { this.config = config this.udapp = udapp this.executionContext = executionContext + this.blockchain = new Blockchain(this.executionContext, udapp) this.fileManager = fileManager this.editor = editor this.logCallback = (msg) => { mainView.getTerminal().logHtml(msg) } @@ -133,8 +134,7 @@ export class RunTab extends LibraryPlugin { renderDropdown (udappUI, fileManager, compilersArtefacts, config, editor, udapp, filePanel, logCallback) { const dropdownLogic = new DropdownLogic(compilersArtefacts, config, editor, this) - const blockchain = new Blockchain(this.executionContext, udapp) - this.contractDropdownUI = new ContractDropdownUI(blockchain, dropdownLogic, logCallback, this) + this.contractDropdownUI = new ContractDropdownUI(this.blockchain, dropdownLogic, logCallback, this) fileManager.events.on('currentFileChanged', this.contractDropdownUI.changeCurrentFile.bind(this.contractDropdownUI)) @@ -159,7 +159,7 @@ export class RunTab extends LibraryPlugin { }) this.event.register('clearInstance', recorder.clearAll.bind(recorder)) - this.recorderInterface = new RecorderUI(recorder, logCallback) + this.recorderInterface = new RecorderUI(this.blockchain, recorder, logCallback) this.recorderInterface.event.register('newScenario', (abi, address, contractName) => { var noInstancesText = this.noInstancesText