aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/manifest.json2
-rw-r--r--app/scripts/controllers/transactions.js13
-rw-r--r--app/scripts/lib/pending-tx-tracker.js18
-rw-r--r--app/scripts/lib/tx-state-manager.js4
-rw-r--r--app/scripts/metamask-controller.js9
5 files changed, 42 insertions, 4 deletions
diff --git a/app/manifest.json b/app/manifest.json
index 4219f3298..aa23f85ff 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
- "version": "3.12.1",
+ "version": "3.13.0",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index a861c0342..685db6269 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -72,6 +72,12 @@ module.exports = class TransactionController extends EventEmitter {
})
this.pendingTxTracker.on('tx:failed', this.txStateManager.setTxStatusFailed.bind(this.txStateManager))
this.pendingTxTracker.on('tx:confirmed', this.txStateManager.setTxStatusConfirmed.bind(this.txStateManager))
+ this.pendingTxTracker.on('tx:block-update', (txMeta, latestBlockNumber) => {
+ if (!txMeta.firstRetryBlockNumber) {
+ txMeta.firstRetryBlockNumber = latestBlockNumber
+ this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:block-update')
+ }
+ })
this.pendingTxTracker.on('tx:retry', (txMeta) => {
if (!('retryCount' in txMeta)) txMeta.retryCount = 0
txMeta.retryCount++
@@ -178,6 +184,13 @@ module.exports = class TransactionController extends EventEmitter {
return await this.txGasUtil.analyzeGasUsage(txMeta)
}
+ async retryTransaction (txId) {
+ this.txStateManager.setTxStatusUnapproved(txId)
+ const txMeta = this.txStateManager.getTx(txId)
+ txMeta.lastGasPrice = txMeta.txParams.gasPrice
+ this.txStateManager.updateTx(txMeta, 'retryTransaction: manual retry')
+ }
+
async updateAndApproveTransaction (txMeta) {
this.txStateManager.updateTx(txMeta, 'confTx: user approved transaction')
await this.approveTransaction(txMeta.id)
diff --git a/app/scripts/lib/pending-tx-tracker.js b/app/scripts/lib/pending-tx-tracker.js
index 0d7c6a92c..dc6e526fd 100644
--- a/app/scripts/lib/pending-tx-tracker.js
+++ b/app/scripts/lib/pending-tx-tracker.js
@@ -65,11 +65,11 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
}
- resubmitPendingTxs () {
+ resubmitPendingTxs (block) {
const pending = this.getPendingTransactions()
// only try resubmitting if their are transactions to resubmit
if (!pending.length) return
- pending.forEach((txMeta) => this._resubmitTx(txMeta).catch((err) => {
+ pending.forEach((txMeta) => this._resubmitTx(txMeta, block.number).catch((err) => {
/*
Dont marked as failed if the error is a "known" transaction warning
"there is already a transaction with the same sender-nonce
@@ -101,13 +101,25 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
}))
}
- async _resubmitTx (txMeta) {
+ async _resubmitTx (txMeta, latestBlockNumber) {
+ if (!txMeta.firstRetryBlockNumber) {
+ this.emit('tx:block-update', txMeta, latestBlockNumber)
+ }
+
if (Date.now() > txMeta.time + this.retryTimePeriod) {
const hours = (this.retryTimePeriod / 3.6e+6).toFixed(1)
const err = new Error(`Gave up submitting after ${hours} hours.`)
return this.emit('tx:failed', txMeta.id, err)
}
+ const firstRetryBlockNumber = txMeta.firstRetryBlockNumber || latestBlockNumber
+ const txBlockDistance = Number.parseInt(latestBlockNumber, 16) - Number.parseInt(firstRetryBlockNumber, 16)
+
+ const retryCount = txMeta.retryCount || 0
+
+ // Exponential backoff to limit retries at publishing
+ if (txBlockDistance <= Math.pow(2, retryCount) - 1) return
+
// Only auto-submit already-signed txs:
if (!('rawTx' in txMeta)) return
diff --git a/app/scripts/lib/tx-state-manager.js b/app/scripts/lib/tx-state-manager.js
index 0fd6bed4b..cc441c584 100644
--- a/app/scripts/lib/tx-state-manager.js
+++ b/app/scripts/lib/tx-state-manager.js
@@ -187,6 +187,10 @@ module.exports = class TransactionStateManger extends EventEmitter {
this._setTxStatus(txId, 'rejected')
}
+ // should update the status of the tx to 'unapproved'.
+ setTxStatusUnapproved (txId) {
+ this._setTxStatus(txId, 'unapproved')
+ }
// should update the status of the tx to 'approved'.
setTxStatusApproved (txId) {
this._setTxStatus(txId, 'approved')
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 130ad1471..9d126b416 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -363,6 +363,7 @@ module.exports = class MetamaskController extends EventEmitter {
// txController
cancelTransaction: nodeify(txController.cancelTransaction, txController),
updateAndApproveTransaction: nodeify(txController.updateAndApproveTransaction, txController),
+ retryTransaction: nodeify(this.retryTransaction, this),
// messageManager
signMessage: nodeify(this.signMessage, this),
@@ -573,6 +574,14 @@ module.exports = class MetamaskController extends EventEmitter {
//
// Identity Management
//
+ //
+
+ async retryTransaction (txId, cb) {
+ await this.txController.retryTransaction(txId)
+ const state = await this.getState()
+ return state
+ }
+
newUnsignedMessage (msgParams, cb) {
const msgId = this.messageManager.addUnapprovedMessage(msgParams)