mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
KeyringController - estimateGas->analyzeGasUsage fix gasLimit + detect OOG
This commit is contained in:
parent
4669f262e2
commit
bc39cd7b89
@ -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)
|
||||
|
@ -33,6 +33,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"ap": "^0.2.0",
|
||||
"async": "^1.5.2",
|
||||
"bip39": "^2.2.0",
|
||||
"browserify-derequire": "^0.9.4",
|
||||
|
Loading…
Reference in New Issue
Block a user