@@ -260,24 +260,51 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone
260260
261261 function estimateGas ( cb ) {
262262 var estimationParams = extend ( txParams )
263- // 1 billion gas for estimation
264- var gasLimit = '0x3b9aca00'
265- estimationParams . gas = gasLimit
266- query . estimateGas ( estimationParams , function ( err , result ) {
267- if ( err ) return cb ( err . message || err )
268- if ( result === estimationParams . gas ) {
269- txData . simulationFails = true
270- query . getBlockByNumber ( 'latest' , true , function ( err , block ) {
271- if ( err ) return cb ( err )
272- txData . estimatedGas = block . gasLimit
273- txData . txParams . gas = block . gasLimit
263+ query . getBlockByNumber ( 'latest' , true , function ( err , block ) {
264+ if ( err ) return cb ( err )
265+ // check if gasLimit is already specified
266+ const gasLimitSpecified = Boolean ( txParams . gas )
267+ // if not, fallback to block gasLimit
268+ if ( ! gasLimitSpecified ) {
269+ estimationParams . gas = block . gasLimit
270+ }
271+ // run tx, see if it will OOG
272+ query . estimateGas ( estimationParams , function ( err , estimatedGasHex ) {
273+ if ( err ) return cb ( err . message || err )
274+ // all gas used - must be an error
275+ if ( estimatedGasHex === estimationParams . gas ) {
276+ txData . simulationFails = true
277+ txData . estimatedGas = estimatedGasHex
278+ txData . txParams . gas = estimatedGasHex
279+ cb ( )
280+ return
281+ }
282+ // otherwise, did not use all gas, must be ok
283+
284+ // if specified gasLimit and no error, we're done
285+ if ( gasLimitSpecified ) {
286+ txData . estimatedGas = txParams . gas
274287 cb ( )
275- } )
288+ return
289+ }
290+
291+ // try adding an additional gas buffer to our estimation for safety
292+ const estimatedGasBn = new BN ( ethUtil . stripHexPrefix ( estimatedGasHex ) , 16 )
293+ const blockGasLimitBn = new BN ( ethUtil . stripHexPrefix ( block . gasLimit ) , 16 )
294+ const estimationWithBuffer = self . addGasBuffer ( estimatedGasBn )
295+ // added gas buffer is too high
296+ if ( estimationWithBuffer . gt ( blockGasLimitBn ) ) {
297+ txData . estimatedGas = estimatedGasHex
298+ txData . txParams . gas = estimatedGasHex
299+ // added gas buffer is safe
300+ } else {
301+ const gasWithBufferHex = ethUtil . intToHex ( estimationWithBuffer )
302+ txData . estimatedGas = gasWithBufferHex
303+ txData . txParams . gas = gasWithBufferHex
304+ }
305+ cb ( )
276306 return
277- }
278- txData . estimatedGas = self . addGasBuffer ( result )
279- txData . txParams . gas = txData . estimatedGas
280- cb ( )
307+ } )
281308 } )
282309 }
283310
@@ -302,12 +329,11 @@ IdentityStore.prototype.checkForDelegateCall = function (codeHex) {
302329 }
303330}
304331
305- IdentityStore . prototype . addGasBuffer = function ( gas ) {
306- const bnGas = new BN ( ethUtil . stripHexPrefix ( gas ) , 16 )
307- const five = new BN ( '5' , 10 )
308- const gasBuffer = bnGas . div ( five )
309- const correct = bnGas . add ( gasBuffer )
310- return ethUtil . addHexPrefix ( correct . toString ( 16 ) )
332+ IdentityStore . prototype . addGasBuffer = function ( gasBn ) {
333+ // add 20% to specified gas
334+ const gasBuffer = gasBn . div ( new BN ( '5' , 10 ) )
335+ const gasWithBuffer = gasBn . add ( gasBuffer )
336+ return gasWithBuffer
311337}
312338
313339// comes from metamask ui
0 commit comments