From 7545b7ce82dae75edf1abcf3c61bec49acb1b611 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 27 Jul 2021 15:44:18 +0200 Subject: [PATCH] maxFee and maxPriorityFee for eip1559 --- .../src/app/tabs/runTab/contractDropdown.js | 7 +-- .../remix-ide/src/app/tabs/runTab/recorder.js | 7 +-- apps/remix-ide/src/app/ui/confirmDialog.js | 62 +++++++++++++++---- apps/remix-ide/src/app/ui/sendTxCallbacks.js | 7 +-- .../src/blockchain/execution-context.js | 6 +- libs/remix-lib/src/execution/txRunnerWeb3.ts | 18 ++++-- 6 files changed, 77 insertions(+), 30 deletions(-) diff --git a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js index 0d3da9f1a2..8328e04bcb 100644 --- a/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js +++ b/apps/remix-ide/src/app/tabs/runTab/contractDropdown.js @@ -361,7 +361,7 @@ class ContractDropdownUI { return continueTxExecution(null) } const amount = this.blockchain.fromWei(tx.value, true, 'ether') - const content = confirmDialog(tx, amount, gasEstimation, null, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain)) + const content = confirmDialog(tx, network, amount, gasEstimation, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain)) modalDialog('Confirm transaction', content, { @@ -370,10 +370,9 @@ class ContractDropdownUI { this.blockchain.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') + cancelCb('Given transaction fee is not correct') } else { - var gasPrice = this.blockchain.toWei(content.querySelector('#gasprice').value, 'gwei') - continueTxExecution(gasPrice) + continueTxExecution(content.txFee) } } }, { diff --git a/apps/remix-ide/src/app/tabs/runTab/recorder.js b/apps/remix-ide/src/app/tabs/runTab/recorder.js index 47f6ff440b..52d5367464 100644 --- a/apps/remix-ide/src/app/tabs/runTab/recorder.js +++ b/apps/remix-ide/src/app/tabs/runTab/recorder.js @@ -104,7 +104,7 @@ class RecorderUI extends Plugin { return continueTxExecution(null) } const amount = this.blockchain.fromWei(tx.value, true, 'ether') - const content = confirmDialog(tx, amount, gasEstimation, null, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain)) + const content = confirmDialog(tx, network, amount, gasEstimation, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice.bind(this.blockchain)) modalDialog('Confirm transaction', content, { @@ -113,10 +113,9 @@ class RecorderUI extends Plugin { 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') + cancelCb('Given transaction fee is not correct') } else { - var gasPrice = this.blockchain.toWei(content.querySelector('#gasprice').value, 'gwei') - continueTxExecution(gasPrice) + continueTxExecution(content.txFee) } } }, { diff --git a/apps/remix-ide/src/app/ui/confirmDialog.js b/apps/remix-ide/src/app/ui/confirmDialog.js index a3246dcf6a..820243e0d7 100644 --- a/apps/remix-ide/src/app/ui/confirmDialog.js +++ b/apps/remix-ide/src/app/ui/confirmDialog.js @@ -14,20 +14,36 @@ var css = csjs` } ` -// TODO: self is not actually used and can be removed -function confirmDialog (tx, amount, gasEstimation, self, newGasPriceCb, initialParamsCb) { - var onGasPriceChange = function () { +function confirmDialog (tx, network, amount, gasEstimation, newGasPriceCb, initialParamsCb) { + const onGasPriceChange = function () { var gasPrice = el.querySelector('#gasprice').value newGasPriceCb(gasPrice, (txFeeText, priceStatus) => { el.querySelector('#txfee').innerHTML = txFeeText el.gasPriceStatus = priceStatus + el.txFee = { gasPrice } }) } - var el = yo` + const onMaxFeeChange = function () { + var maxFee = el.querySelector('#maxfee').value + var maxPriorityFee = el.querySelector('#maxpriorityfee').value + if (parseInt(network.lastBlock.baseFeePerGas, 16) > parseInt(maxFee)) { + el.querySelector('#txfee').innerHTML = 'Transaction is invalid. Base fee should not be bigger than Max fee' + el.gasPriceStatus = false + return + } else el.gasPriceStatus = true + + newGasPriceCb(maxFee, (txFeeText, priceStatus) => { + el.querySelector('#txfee').innerHTML = txFeeText + el.gasPriceStatus = priceStatus + el.txFee = { maxFee, maxPriorityFee, baseFeePerGas: network.lastBlock.baseFeePerGas } + }) + } + + const el = yo`
-
You are about to create a transaction on the Main Network. Confirm the details to send the info to your provider. -
The provider for many users is MetaMask. The provider will ask you to sign the transaction before it is sent to the Main Network.
+
You are about to create a transaction on ${network.name}. Confirm the details to send the info to your provider. +
The provider for many users is MetaMask. The provider will ask you to sign the transaction before it is sent to ${network.name}.
From: @@ -53,11 +69,29 @@ function confirmDialog (tx, amount, gasEstimation, self, newGasPriceCb, initialP Max transaction fee:
-
- Gas price: - - Gwei (visit ethgasstation.info for current gas price info.) -
+ ${ + network.lastBlock.baseFeePerGas ? yo`
+
+ Max Priority fee: + + Gwei +
+
Represents the part of the tx fee that goes to the miner
+
+
+
+ Max fee: + + Gwei +
+
Represents the maximum amount of fee that you will pay for this transaction. The minimun needs to be set to base fee.
+
` + : yo`
+ Gas price: + + Gwei (visit ethgasstation.info for current gas price info.) +
` + }
Data:
${tx.data && tx.data.length > 50 ? tx.data.substring(0, 49) + '...' : tx.data} ${copyToClipboard(() => { return tx.data })}
@@ -74,10 +108,14 @@ function confirmDialog (tx, amount, gasEstimation, self, newGasPriceCb, initialP if (txFeeText) { el.querySelector('#txfee').innerHTML = txFeeText } - if (gasPriceValue) { + if (el.querySelector('#gasprice') && gasPriceValue) { el.querySelector('#gasprice').value = gasPriceValue onGasPriceChange() } + if (el.querySelector('#maxfee') && network && network.lastBlock && network.lastBlock.baseFeePerGas && el.querySelector('#maxfee')) { + el.querySelector('#maxfee').value = parseInt(network.lastBlock.baseFeePerGas, 16) + onMaxFeeChange() + } if (gasPriceStatus !== undefined) { el.gasPriceStatus = gasPriceStatus } diff --git a/apps/remix-ide/src/app/ui/sendTxCallbacks.js b/apps/remix-ide/src/app/ui/sendTxCallbacks.js index f2785482b2..3f5c7c7506 100644 --- a/apps/remix-ide/src/app/ui/sendTxCallbacks.js +++ b/apps/remix-ide/src/app/ui/sendTxCallbacks.js @@ -51,7 +51,7 @@ const confirmationCb = function (network, tx, gasEstimation, continueTxExecution return continueTxExecution(null) } var amount = Web3.utils.fromWei(typeConversion.toInt(tx.value), 'ether') - var content = confirmDialog(tx, amount, gasEstimation, self.udappUI, + var content = confirmDialog(tx, network, amount, gasEstimation, (gasPrice, cb) => { let txFeeText, priceStatus // TODO: this try catch feels like an anti pattern, can/should be @@ -93,10 +93,9 @@ const confirmationCb = function (network, tx, gasEstimation, continueTxExecution ) // TODO: check if this is check is still valid given the refactor if (!content.gasPriceStatus) { - cancelCb('Given gas price is not correct') + cancelCb('Given transaction fee is not correct') } else { - var gasPrice = Web3.utils.toWei(content.querySelector('#gasprice').value, 'gwei') - continueTxExecution(gasPrice) + continueTxExecution(content.txFee) } } }, diff --git a/apps/remix-ide/src/blockchain/execution-context.js b/apps/remix-ide/src/blockchain/execution-context.js index f29d0ec0d4..69b7a1cc2c 100644 --- a/apps/remix-ide/src/blockchain/execution-context.js +++ b/apps/remix-ide/src/blockchain/execution-context.js @@ -20,6 +20,7 @@ export class ExecutionContext { constructor () { this.event = new EventManager() this.executionContext = null + this.lastBlock = null this.blockGasLimitDefault = 4300000 this.blockGasLimit = this.blockGasLimitDefault this.currentFork = 'berlin' @@ -86,10 +87,10 @@ export class ExecutionContext { web3.eth.getBlock(0, (error, block) => { if (error) console.log('cant query first block') if (block && block.hash !== this.mainNetGenesisHash) name = 'Custom' - callback(err, { id, name }) + callback(err, { id, name, lastBlock: this.lastBlock, currentFork: this.currentFork }) }) } else { - callback(err, { id, name }) + callback(err, { id, name, lastBlock: this.lastBlock, currentFork: this.currentFork }) } }) } @@ -176,6 +177,7 @@ export class ExecutionContext { const block = await web3.eth.getBlock('latest') // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506 this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault + this.lastBlock = block try { this.currentFork = execution.forkAt(await web3.eth.net.getId(), block.number) } catch (e) { diff --git a/libs/remix-lib/src/execution/txRunnerWeb3.ts b/libs/remix-lib/src/execution/txRunnerWeb3.ts index b36aaffdcc..64500d01a3 100644 --- a/libs/remix-lib/src/execution/txRunnerWeb3.ts +++ b/libs/remix-lib/src/execution/txRunnerWeb3.ts @@ -15,8 +15,18 @@ export class TxRunnerWeb3 { this._api = api } - _executeTx (tx, gasPrice, api, promptCb, callback) { - if (gasPrice) tx.gasPrice = this.getWeb3().utils.toHex(gasPrice) + _executeTx (tx, txFee, api, promptCb, callback) { + if (txFee) { + if (txFee.baseFeePerGas) { + tx.maxPriorityFee = this.getWeb3().utils.toHex(this.getWeb3().utils.toWei(txFee.maxPriorityFee, 'gwei')) + tx.maxFee = this.getWeb3().utils.toHex(this.getWeb3().utils.toWei(txFee.maxFee, 'gwei')) + tx.type = 2 + } else { + tx.gasPrice = this.getWeb3().utils.toHex(this.getWeb3().utils.toWei(txFee.gasPrice, 'gwei')) + tx.type = 1 + } + } + if (api.personalMode()) { promptCb( (value) => { @@ -100,8 +110,8 @@ export class TxRunnerWeb3 { return } - confirmCb(network, tx, tx['gas'], (gasPrice) => { - return this._executeTx(tx, gasPrice, this._api, promptCb, callback) + confirmCb(network, tx, tx['gas'], (txFee) => { + return this._executeTx(tx, txFee, this._api, promptCb, callback) }, (error) => { callback(error) })