fix: gas estimate error

fixes #935
A bug occurs when someone requests a large amount of funds from you since the gas estimation will fail and there isn't a way of handling errors in the source yet.

This PR handles the error appropriatley for both `estimateGas` and `estimateTokenGas` where the response is only converted from hex to int if the RPC call was successful. Otherwise return the error message as the response and let the UI decide how to display it.

Currently the error for gas estimation in transaction bubbles is displayed in a popup however, ive come to realize that 2 popups open instead of one. This is a new bug of which I can't pinpoint the root cause at the moment and have opted to file a separate issue for it.
This commit is contained in:
Malik Al-Jabr 2021-01-18 14:44:33 +02:00 committed by Iuri Matias
parent 086c868bdc
commit 3ad3739218
4 changed files with 23 additions and 13 deletions

View File

@ -273,13 +273,18 @@ QtObject:
proc estimateGas*(self: WalletView, from_addr: string, to: string, assetAddress: string, value: string, data: string = ""): string {.slot.} = proc estimateGas*(self: WalletView, from_addr: string, to: string, assetAddress: string, value: string, data: string = ""): string {.slot.} =
var var
response: int response: string
success: bool success: bool
if assetAddress != ZERO_ADDRESS and not assetAddress.isEmptyOrWhitespace: if assetAddress != ZERO_ADDRESS and not assetAddress.isEmptyOrWhitespace:
response = self.status.wallet.estimateTokenGas(from_addr, to, assetAddress, value, success) response = self.status.wallet.estimateTokenGas(from_addr, to, assetAddress, value, success)
else: else:
response = self.status.wallet.estimateGas(from_addr, to, value, data, success) response = self.status.wallet.estimateGas(from_addr, to, value, data, success)
result = $(%* { "result": %response, "success": %success })
if success == true:
let res = fromHex[int](response)
result = $(%* { "result": %res, "success": %success })
else:
result = $(%* { "result": "-1", "success": %success, "error": { "message": %response } })
proc transactionWasSent*(self: WalletView, txResult: string) {.signal.} proc transactionWasSent*(self: WalletView, txResult: string) {.signal.}

View File

@ -72,15 +72,14 @@ proc buildTokenTransaction(self: WalletModel, source, to, assetAddress: Address,
proc getKnownTokenContract*(self: WalletModel, address: Address): Erc20Contract = proc getKnownTokenContract*(self: WalletModel, address: Address): Erc20Contract =
getErc20Contracts().concat(getCustomTokens()).getErc20ContractByAddress(address) getErc20Contracts().concat(getCustomTokens()).getErc20ContractByAddress(address)
proc estimateGas*(self: WalletModel, source, to, value, data: string, success: var bool): int = proc estimateGas*(self: WalletModel, source, to, value, data: string, success: var bool): string =
var tx = transactions.buildTransaction( var tx = transactions.buildTransaction(
parseAddress(source), parseAddress(source),
eth2Wei(parseFloat(value), 18), eth2Wei(parseFloat(value), 18),
data = data data = data
) )
tx.to = parseAddress(to).some tx.to = parseAddress(to).some
let response = eth.estimateGas(tx, success) result = eth.estimateGas(tx, success)
result = fromHex[int](response)
proc getTransactionReceipt*(self: WalletModel, transactionHash: string): JsonNode = proc getTransactionReceipt*(self: WalletModel, transactionHash: string): JsonNode =
result = status_wallet.getTransactionReceipt(transactionHash).parseJSON()["result"] result = status_wallet.getTransactionReceipt(transactionHash).parseJSON()["result"]
@ -110,7 +109,7 @@ proc checkPendingTransactions*(self: WalletModel) =
proc checkPendingTransactions*(self: WalletModel, address: string, blockNumber: int) = proc checkPendingTransactions*(self: WalletModel, address: string, blockNumber: int) =
self.confirmTransactionStatus(status_wallet.getPendingOutboundTransactionsByAddress(address).parseJson["result"], blockNumber) self.confirmTransactionStatus(status_wallet.getPendingOutboundTransactionsByAddress(address).parseJson["result"], blockNumber)
proc estimateTokenGas*(self: WalletModel, source, to, assetAddress, value: string, success: var bool): int = proc estimateTokenGas*(self: WalletModel, source, to, assetAddress, value: string, success: var bool): string =
var var
transfer: Transfer transfer: Transfer
contract: Erc20Contract contract: Erc20Contract
@ -123,8 +122,7 @@ proc estimateTokenGas*(self: WalletModel, source, to, assetAddress, value: strin
contract contract
) )
let response = contract.methods["transfer"].estimateGas(tx, transfer, success) result = contract.methods["transfer"].estimateGas(tx, transfer, success)
result = fromHex[int](response)
proc sendTransaction*(self: WalletModel, source, to, value, gas, gasPrice, password: string, success: var bool, data = ""): string = proc sendTransaction*(self: WalletModel, source, to, value, gas, gasPrice, password: string, success: var bool, data = ""): string =
var tx = transactions.buildTransaction( var tx = transactions.buildTransaction(

View File

@ -31,10 +31,6 @@ ModalPopup {
root.close() root.close()
} }
function estimateGas(){
gasSelector.estimateGas()
}
id: root id: root
//% "Send" //% "Send"
@ -139,7 +135,10 @@ ModalPopup {
if (!gasEstimate.success) { if (!gasEstimate.success) {
//% "Error estimating gas: %1" //% "Error estimating gas: %1"
console.warn(qsTrId("error-estimating-gas---1").arg(gasEstimate.error.message)) let message = qsTrId("error-estimating-gas---1").arg(gasEstimate.error.message)
console.warn(message)
gasEstimateErrorPopup.confirmationText = message + qsTr(". The transaction will probably fail.")
gasEstimateErrorPopup.open()
return return
} }
selectedGasLimit = gasEstimate.result selectedGasLimit = gasEstimate.result

View File

@ -77,6 +77,14 @@ Item {
} }
} }
ConfirmationDialog {
id: gasEstimateErrorPopup
height: 220
onConfirmButtonClicked: {
gasEstimateErrorPopup.close();
}
}
Loader { Loader {
id: signTransactionModal id: signTransactionModal
function open() { function open() {