From 6e78494846c9032fbf1264a0225c0df4df0867cb Mon Sep 17 00:00:00 2001 From: Frances Pangilinan Date: Fri, 16 Dec 2016 10:33:36 -0800 Subject: First pass at revision requests --- app/scripts/lib/tx-utils.js | 87 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 app/scripts/lib/tx-utils.js (limited to 'app/scripts/lib/tx-utils.js') diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js new file mode 100644 index 000000000..a976173f5 --- /dev/null +++ b/app/scripts/lib/tx-utils.js @@ -0,0 +1,87 @@ +const async = require('async') +const EthQuery = require('eth-query') +const ethUtil = require('ethereumjs-util') +const BN = ethUtil.BN + +/* +tx-utils are utility methods for Transaction manager +its passed a provider and that is passed to ethquery +and used to do things like calculate gas of a tx. +*/ + +module.exports = class txProviderUtils { + constructor (provider) { + this.provider = provider + this.query = new EthQuery(provider) + } + analyzeGasUsage (txData, cb) { + var self = this + this.query.getBlockByNumber('latest', true, (err, block) => { + if (err) return cb(err) + async.waterfall([ + self.estimateTxGas.bind(self, txData, block.gasLimit), + self.checkForTxGasError.bind(self, txData), + self.setTxGas.bind(self, txData, block.gasLimit), + ], cb) + }) + } + + estimateTxGas (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 + this.query.estimateGas(txParams, cb) + } + + checkForTxGasError (txData, estimatedGasHex, cb) { + txData.estimatedGas = estimatedGasHex + // all gas used - must be an error + if (estimatedGasHex === txData.txParams.gas) { + txData.simulationFails = true + } + cb() + } + + setTxGas (txData, blockGasLimitHex, cb) { + 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 = new BN(this.addGasBuffer(estimatedGasBn), 16) + // 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 + } + + addGasBuffer (gas) { + const gasBuffer = new BN('100000', 10) + const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16) + const correct = bnGas.add(gasBuffer) + return ethUtil.addHexPrefix(correct.toString(16)) + } +} -- cgit v1.2.3 From 21e2e4efd803c8c904cecf039ee73fead0e6c4c1 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Tue, 10 Jan 2017 14:20:46 -0800 Subject: Remove erroneous OOG estimation logic. --- app/scripts/lib/tx-utils.js | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'app/scripts/lib/tx-utils.js') diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index a976173f5..d1fb98f42 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -20,7 +20,6 @@ module.exports = class txProviderUtils { if (err) return cb(err) async.waterfall([ self.estimateTxGas.bind(self, txData, block.gasLimit), - self.checkForTxGasError.bind(self, txData), self.setTxGas.bind(self, txData, block.gasLimit), ], cb) }) @@ -38,22 +37,10 @@ module.exports = class txProviderUtils { this.query.estimateGas(txParams, cb) } - checkForTxGasError (txData, estimatedGasHex, cb) { + setTxGas (txData, blockGasLimitHex, estimatedGasHex, cb) { txData.estimatedGas = estimatedGasHex - // all gas used - must be an error - if (estimatedGasHex === txData.txParams.gas) { - txData.simulationFails = true - } - cb() - } - - setTxGas (txData, blockGasLimitHex, cb) { 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) { -- cgit v1.2.3 From 29e83d71a82bfdbeadc9fbecfa97d73ef11fecfb Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 13 Jan 2017 02:00:11 -0800 Subject: background - handle tx finalization in controllers instead of provider-engine --- app/scripts/lib/tx-utils.js | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'app/scripts/lib/tx-utils.js') diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index d1fb98f42..eba537d0a 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -1,6 +1,8 @@ const async = require('async') const EthQuery = require('eth-query') const ethUtil = require('ethereumjs-util') +const Transaction = require('ethereumjs-tx') +const normalize = require('./sig-util').normalize const BN = ethUtil.BN /* @@ -14,6 +16,7 @@ module.exports = class txProviderUtils { this.provider = provider this.query = new EthQuery(provider) } + analyzeGasUsage (txData, cb) { var self = this this.query.getBlockByNumber('latest', true, (err, block) => { @@ -71,4 +74,49 @@ module.exports = class txProviderUtils { const correct = bnGas.add(gasBuffer) return ethUtil.addHexPrefix(correct.toString(16)) } + + fillInTxParams (txParams, cb) { + let fromAddress = txParams.from + let reqs = {} + + if (isUndef(txParams.gas)) reqs.gas = (cb) => this.query.estimateGas(txParams, cb) + if (isUndef(txParams.gasPrice)) reqs.gasPrice = (cb) => this.query.gasPrice(cb) + if (isUndef(txParams.nonce)) reqs.nonce = (cb) => this.query.getTransactionCount(fromAddress, 'pending', cb) + + async.parallel(reqs, function(err, result) { + if (err) return cb(err) + // write results to txParams obj + Object.assign(txParams, result) + cb() + }) + } + + // builds ethTx from txParams object + buildEthTxFromParams (txParams, gasMultiplier = 1) { + // apply gas multiplyer + let gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice), 16) + // multiply and divide by 100 so as to add percision to integer mul + gasPrice = gasPrice.mul(new BN(gasMultiplier * 100, 10)).div(new BN(100, 10)) + txParams.gasPrice = ethUtil.intToHex(gasPrice.toNumber()) + // normalize values + txParams.to = normalize(txParams.to) + txParams.from = normalize(txParams.from) + txParams.value = normalize(txParams.value) + txParams.data = normalize(txParams.data) + txParams.gasLimit = normalize(txParams.gasLimit || txParams.gas) + txParams.nonce = normalize(txParams.nonce) + // build ethTx + const ethTx = new Transaction(txParams) + return ethTx + } + + publishTransaction (rawTx, cb) { + this.query.sendRawTransaction(rawTx, cb) + } } + +// util + +function isUndef(value) { + return value === undefined +} \ No newline at end of file -- cgit v1.2.3 From 580d93188cb77cb4d4ce809b46dade8525efc380 Mon Sep 17 00:00:00 2001 From: Frankie Date: Fri, 13 Jan 2017 17:47:20 -0800 Subject: Satisfy review needs: removed unnecessary this.query = opts.query from constructor Created a tx error state for errors in approveTransaction validateTxParams has been moved to tx-utils removed "value" arg from _setTxStatus --- app/scripts/lib/tx-utils.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'app/scripts/lib/tx-utils.js') diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index eba537d0a..5116cb93b 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -16,7 +16,7 @@ module.exports = class txProviderUtils { this.provider = provider this.query = new EthQuery(provider) } - + analyzeGasUsage (txData, cb) { var self = this this.query.getBlockByNumber('latest', true, (err, block) => { @@ -113,10 +113,20 @@ module.exports = class txProviderUtils { publishTransaction (rawTx, cb) { this.query.sendRawTransaction(rawTx, cb) } + + validateTxParams (txParams, cb) { + if (('value' in txParams) && txParams.value.indexOf('-') === 0) { + cb(new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)) + } else { + cb() + } + } + + } // util function isUndef(value) { return value === undefined -} \ No newline at end of file +} -- cgit v1.2.3