aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorkumavis <aaron@kumavis.me>2016-11-23 06:28:31 +0800
committerkumavis <aaron@kumavis.me>2016-11-23 06:28:31 +0800
commitbc39cd7b894ddf0f3724d4af3cfc30c2638e0939 (patch)
treefc1dc8af22a012a10bf8e506c68d5d5b729c27e1 /app
parent4669f262e2bad5052aac804c3cff8a8c5ee825e3 (diff)
downloadtangerine-wallet-browser-bc39cd7b894ddf0f3724d4af3cfc30c2638e0939.tar
tangerine-wallet-browser-bc39cd7b894ddf0f3724d4af3cfc30c2638e0939.tar.gz
tangerine-wallet-browser-bc39cd7b894ddf0f3724d4af3cfc30c2638e0939.tar.bz2
tangerine-wallet-browser-bc39cd7b894ddf0f3724d4af3cfc30c2638e0939.tar.lz
tangerine-wallet-browser-bc39cd7b894ddf0f3724d4af3cfc30c2638e0939.tar.xz
tangerine-wallet-browser-bc39cd7b894ddf0f3724d4af3cfc30c2638e0939.tar.zst
tangerine-wallet-browser-bc39cd7b894ddf0f3724d4af3cfc30c2638e0939.zip
KeyringController - estimateGas->analyzeGasUsage fix gasLimit + detect OOG
Diffstat (limited to 'app')
-rw-r--r--app/scripts/keyring-controller.js66
1 files changed, 61 insertions, 5 deletions
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js
index bf6280016..5432322ac 100644
--- a/app/scripts/keyring-controller.js
+++ b/app/scripts/keyring-controller.js
@@ -1,4 +1,5 @@
const async = require('async')
+const bind = require('ap').partial
const ethUtil = require('ethereumjs-util')
const ethBinToOps = require('eth-bin-to-ops')
const EthQuery = require('eth-query')
@@ -362,7 +363,7 @@ module.exports = class KeyringController extends EventEmitter {
// calculate metadata for tx
async.parallel([
analyzeForDelegateCall,
- estimateGas,
+ analyzeGasUsage,
], didComplete)
// perform static analyis on the target contract code
@@ -385,14 +386,69 @@ module.exports = class KeyringController extends EventEmitter {
}
}
- function estimateGas (cb) {
- query.estimateGas(txParams, function (err, result) {
+ function analyzeGasUsage (cb) {
+ query.getBlockByNumber('latest', true, function (err, block) {
if (err) return cb(err)
- txData.estimatedGas = self.addGasBuffer(result)
- cb()
+ async.waterfall([
+ bind(estimateGas, txData, block.gasLimit),
+ bind(checkForGasError, txData),
+ bind(setTxGas, txData, block.gasLimit),
+ ], cb)
})
}
+ function estimateGas(txData, blockGasLimitHex, cb) {
+ const txParams = txData.txParams
+ // check if gasLimit is already specified
+ txData.gasLimitSpecified = Boolean(txParams.gas)
+ // if not, fallback to block gasLimit
+ if (!txData.gasLimitSpecified) {
+ txParams.gas = blockGasLimitHex
+ }
+ // run tx, see if it will OOG
+ query.estimateGas(txParams, cb)
+ }
+
+ function checkForGasError(txData, estimatedGasHex) {
+ txData.estimatedGas = estimatedGasHex
+ // all gas used - must be an error
+ if (estimatedGasHex === txData.txParams.gas) {
+ txData.simulationFails = true
+ }
+ cb()
+ }
+
+ function setTxGas(txData, blockGasLimitHex) {
+ const txParams = txData.txParams
+ // if OOG, nothing more to do
+ if (txData.simulationFails) {
+ cb()
+ return
+ }
+ // if gasLimit was specified and doesnt OOG,
+ // use original specified amount
+ if (txData.gasLimitSpecified) {
+ txData.estimatedGas = txParams.gas
+ cb()
+ return
+ }
+ // if gasLimit not originally specified,
+ // try adding an additional gas buffer to our estimation for safety
+ const estimatedGasBn = new BN(ethUtil.stripHexPrefix(txData.estimatedGas), 16)
+ const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16)
+ const estimationWithBuffer = self.addGasBuffer(estimatedGasBn)
+ // added gas buffer is too high
+ if (estimationWithBuffer.gt(blockGasLimitBn)) {
+ txParams.gas = txData.estimatedGas
+ // added gas buffer is safe
+ } else {
+ const gasWithBufferHex = ethUtil.intToHex(estimationWithBuffer)
+ txParams.gas = gasWithBufferHex
+ }
+ cb()
+ return
+ }
+
function didComplete (err) {
if (err) return cb(err)
configManager.addTx(txData)