aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--app/scripts/controllers/transactions.js54
2 files changed, 53 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 265c239b2..e84413bd0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
- Add Transaction Number (nonce) to transaction list.
- Label the pending tx icon with a tooltip.
- 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.
## 3.6.5 2017-5-17
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 21dd25b30..3d86a171e 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -7,6 +7,10 @@ const ethUtil = require('ethereumjs-util')
const EthQuery = require('eth-query')
const TxProviderUtil = require('../lib/tx-utils')
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 {
constructor (opts) {
@@ -31,6 +35,8 @@ module.exports = class TransactionManager extends EventEmitter {
this.store.subscribe(() => this._updateMemstore())
this.networkStore.subscribe(() => this._updateMemstore())
this.preferencesStore.subscribe(() => this._updateMemstore())
+
+ this.continuallyResubmitPendingTxs()
}
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) => {
if (err) return cb(err)
this.setTxHash(txId, txHash)
@@ -353,7 +363,7 @@ module.exports = class TransactionManager extends EventEmitter {
message: 'There was a problem loading this transaction.',
}
this.updateTx(txMeta)
- return console.error(err)
+ return log.error(err)
}
if (txParams.blockNumber) {
this.setTxStatusConfirmed(txId)
@@ -379,6 +389,7 @@ module.exports = class TransactionManager extends EventEmitter {
this.emit(`${txMeta.id}:${status}`, txId)
if (status === 'submitted' || status === 'rejected') {
this.emit(`${txMeta.id}:finished`, txMeta)
+
}
this.updateTx(txMeta)
this.emit('updateBadge')
@@ -398,6 +409,45 @@ module.exports = class TransactionManager extends EventEmitter {
})
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)
+ }
}