diff options
Diffstat (limited to 'app/scripts/controllers/transactions.js')
-rw-r--r-- | app/scripts/controllers/transactions.js | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 5f3d84ebe..f71659042 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -1,10 +1,12 @@ const EventEmitter = require('events') const async = require('async') const extend = require('xtend') +const clone = require('clone') const ObservableStore = require('obs-store') const ethUtil = require('ethereumjs-util') const pify = require('pify') const TxProviderUtil = require('../lib/tx-utils') +const getStack = require('../lib/util').getStack const createId = require('../lib/random-id') const NonceTracker = require('../lib/nonce-tracker') @@ -22,7 +24,6 @@ module.exports = class TransactionController extends EventEmitter { this.blockTracker = opts.blockTracker this.nonceTracker = new NonceTracker({ provider: this.provider, - blockTracker: this.provider._blockTracker, getPendingTransactions: (address) => { return this.getFilteredTxList({ from: address, @@ -117,6 +118,17 @@ module.exports = class TransactionController extends EventEmitter { // updateTx (txMeta) { + // create txMeta snapshot for history + const txMetaForHistory = clone(txMeta) + // dont include previous history in this snapshot + delete txMetaForHistory.history + // add stack to help understand why tx was updated + txMetaForHistory.stack = getStack() + // add snapshot to tx history + if (!txMeta.history) txMeta.history = [] + txMeta.history.push(txMetaForHistory) + + // update the tx var txId = txMeta.id var txList = this.getFullTxList() var index = txList.findIndex(txData => txData.id === txId) @@ -134,7 +146,7 @@ module.exports = class TransactionController extends EventEmitter { } addUnapprovedTransaction (txParams, done) { - let txMeta + let txMeta = {} async.waterfall([ // validate (cb) => this.txProviderUtils.validateTxParams(txParams, cb), @@ -146,6 +158,7 @@ module.exports = class TransactionController extends EventEmitter { status: 'unapproved', metamaskNetworkId: this.getNetwork(), txParams: txParams, + history: [], } cb() }, @@ -165,6 +178,7 @@ module.exports = class TransactionController extends EventEmitter { txParams.value = txParams.value || '0x0' if (!txParams.gasPrice) { this.query.gasPrice((err, gasPrice) => { + if (err) return cb(err) // set gasPrice txParams.gasPrice = gasPrice @@ -191,8 +205,12 @@ module.exports = class TransactionController extends EventEmitter { // get next nonce const txMeta = this.getTx(txId) const fromAddress = txMeta.txParams.from + // wait for a nonce nonceLock = await this.nonceTracker.getNonceLock(fromAddress) + // add nonce to txParams txMeta.txParams.nonce = nonceLock.nextNonce + // add nonce debugging information to txMeta + txMeta.nonceDetails = nonceLock.nonceDetails this.updateTx(txMeta) // sign transaction const rawTx = await this.signTransaction(txId) @@ -201,6 +219,7 @@ module.exports = class TransactionController extends EventEmitter { nonceLock.releaseLock() } catch (err) { this.setTxStatusFailed(txId, { + stack: err.stack || err.message, errCode: err.errCode || err, message: err.message || 'Transaction failed during approval', }) @@ -364,11 +383,11 @@ module.exports = class TransactionController extends EventEmitter { var txId = txMeta.id if (!txHash) { - const errReason = { + return this.setTxStatusFailed(txId, { + stack: 'checkForTxInBlock: custom tx-controller error message', errCode: 'No hash was provided', message: 'We had an error while submitting this transaction, please try again.', - } - return this.setTxStatusFailed(txId, errReason) + }) } block.transactions.forEach((tx) => { @@ -452,13 +471,14 @@ module.exports = class TransactionController extends EventEmitter { if (isKnownTx) return // encountered real error - transition to error state this.setTxStatusFailed(txMeta.id, { + stack: err.stack || err.message, errCode: err.errCode || err, message: err.message, }) })) } - async _resubmitTx (txMeta, cb) { + async _resubmitTx (txMeta) { const address = txMeta.txParams.from const balance = this.ethStore.getState().accounts[address].balance if (!('retryCount' in txMeta)) txMeta.retryCount = 0 @@ -466,18 +486,21 @@ module.exports = class TransactionController extends EventEmitter { // if the value of the transaction is greater then the balance, fail. if (!this.txProviderUtils.sufficientBalance(txMeta.txParams, balance)) { const message = 'Insufficient balance.' - this.setTxStatusFailed(txMeta.id, { message }) - cb() - return log.error(message) + this.setTxStatusFailed(txMeta.id, { + stack: '_resubmitTx: custom tx-controller error', + message, + }) + log.error(message) + return } // Only auto-submit already-signed txs: - if (!('rawTx' in txMeta)) return cb() + if (!('rawTx' in txMeta)) return // Increment a try counter. txMeta.retryCount++ const rawTx = txMeta.rawTx - return await this.txProviderUtils.publishTransaction(rawTx, cb) + return await this.txProviderUtils.publishTransaction(rawTx) } // checks the network for signed txs and @@ -501,11 +524,11 @@ module.exports = class TransactionController extends EventEmitter { // extra check in case there was an uncaught error during the // signature and submission process if (!txHash) { - const errReason = { + this.setTxStatusFailed(txId, { + stack: '_checkPendingTxs: custom tx-controller error message', errCode: 'No hash was provided', message: 'We had an error while submitting this transaction, please try again.', - } - this.setTxStatusFailed(txId, errReason) + }) return } // get latest transaction status |