1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-30 16:18:07 +01:00

Merge pull request #1478 from MetaMask/i1409-StalledTxs

Continually resubmit pending txs
This commit is contained in:
Thomas Huang 2017-05-23 17:14:42 -04:00 committed by GitHub
commit f4158d26f6
2 changed files with 53 additions and 2 deletions

View File

@ -5,6 +5,7 @@
- Add Transaction Number (nonce) to transaction list. - Add Transaction Number (nonce) to transaction list.
- Label the pending tx icon with a tooltip. - Label the pending tx icon with a tooltip.
- Fix bug where website filters would pile up and not deallocate when leaving a site. - Fix bug where website filters would pile up and not deallocate when leaving a site.
- Continually resubmit pending txs for a period of time to ensure successful broadcast.
- ENS names will no longer resolve to their owner if no resolver is set. Resolvers must be explicitly set and configured. - ENS names will no longer resolve to their owner if no resolver is set. Resolvers must be explicitly set and configured.
## 3.6.5 2017-5-17 ## 3.6.5 2017-5-17

View File

@ -7,6 +7,10 @@ const ethUtil = require('ethereumjs-util')
const EthQuery = require('eth-query') const EthQuery = require('eth-query')
const TxProviderUtil = require('../lib/tx-utils') const TxProviderUtil = require('../lib/tx-utils')
const createId = require('../lib/random-id') const createId = require('../lib/random-id')
const denodeify = require('denodeify')
const RETRY_LIMIT = 200
const RESUBMIT_INTERVAL = 10000 // Ten seconds
module.exports = class TransactionManager extends EventEmitter { module.exports = class TransactionManager extends EventEmitter {
constructor (opts) { constructor (opts) {
@ -31,6 +35,8 @@ module.exports = class TransactionManager extends EventEmitter {
this.store.subscribe(() => this._updateMemstore()) this.store.subscribe(() => this._updateMemstore())
this.networkStore.subscribe(() => this._updateMemstore()) this.networkStore.subscribe(() => this._updateMemstore())
this.preferencesStore.subscribe(() => this._updateMemstore()) this.preferencesStore.subscribe(() => this._updateMemstore())
this.continuallyResubmitPendingTxs()
} }
getState () { getState () {
@ -230,7 +236,11 @@ module.exports = class TransactionManager extends EventEmitter {
}) })
} }
publishTransaction (txId, rawTx, cb) { publishTransaction (txId, rawTx, cb = warn) {
const txMeta = this.getTx(txId)
txMeta.rawTx = rawTx
this.updateTx(txMeta)
this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => { this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => {
if (err) return cb(err) if (err) return cb(err)
this.setTxHash(txId, txHash) this.setTxHash(txId, txHash)
@ -353,7 +363,7 @@ module.exports = class TransactionManager extends EventEmitter {
message: 'There was a problem loading this transaction.', message: 'There was a problem loading this transaction.',
} }
this.updateTx(txMeta) this.updateTx(txMeta)
return console.error(err) return log.error(err)
} }
if (txParams.blockNumber) { if (txParams.blockNumber) {
this.setTxStatusConfirmed(txId) this.setTxStatusConfirmed(txId)
@ -379,6 +389,7 @@ module.exports = class TransactionManager extends EventEmitter {
this.emit(`${txMeta.id}:${status}`, txId) this.emit(`${txMeta.id}:${status}`, txId)
if (status === 'submitted' || status === 'rejected') { if (status === 'submitted' || status === 'rejected') {
this.emit(`${txMeta.id}:finished`, txMeta) this.emit(`${txMeta.id}:finished`, txMeta)
} }
this.updateTx(txMeta) this.updateTx(txMeta)
this.emit('updateBadge') this.emit('updateBadge')
@ -398,6 +409,45 @@ module.exports = class TransactionManager extends EventEmitter {
}) })
this.memStore.updateState({ unapprovedTxs, selectedAddressTxList }) this.memStore.updateState({ unapprovedTxs, selectedAddressTxList })
} }
continuallyResubmitPendingTxs () {
const pending = this.getTxsByMetaData('status', 'submitted')
const resubmit = denodeify(this.resubmitTx.bind(this))
Promise.all(pending.map(txMeta => resubmit(txMeta)))
.catch((reason) => {
log.info('Problem resubmitting tx', reason)
})
.then(() => {
global.setTimeout(() => {
this.continuallyResubmitPendingTxs()
}, RESUBMIT_INTERVAL)
})
}
resubmitTx (txMeta, cb) {
// Increment a try counter.
if (!('retryCount' in txMeta)) {
txMeta.retryCount = 0
}
// Only auto-submit already-signed txs:
if (!('rawTx' in txMeta)) {
return cb()
}
if (txMeta.retryCount > RETRY_LIMIT) {
txMeta.err = {
isWarning: true,
message: 'Gave up submitting tx.',
}
this.updateTx(txMeta)
return log.error(txMeta.err.message)
}
txMeta.retryCount++
const rawTx = txMeta.rawTx
this.txProviderUtils.publishTransaction(rawTx, cb)
}
} }