When checking pending txs, check for successful txs with same nonce.

If a successful tx with the same nonce exists, transition tx to the failed state.

Fixes #2294
feature/default_network_editable
Dan Finlay 7 years ago
parent 94513cae7b
commit a417fab0eb
  1. 20
      app/scripts/lib/pending-tx-tracker.js

@ -25,6 +25,7 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
// default is one day // default is one day
this.retryTimePeriod = config.retryTimePeriod || 86400000 this.retryTimePeriod = config.retryTimePeriod || 86400000
this.getPendingTransactions = config.getPendingTransactions this.getPendingTransactions = config.getPendingTransactions
this.getCompletedTransactions = config.getCompletedTransactions
this.publishTransaction = config.publishTransaction this.publishTransaction = config.publishTransaction
} }
@ -120,6 +121,7 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
async _checkPendingTx (txMeta) { async _checkPendingTx (txMeta) {
const txHash = txMeta.hash const txHash = txMeta.hash
const txId = txMeta.id const txId = txMeta.id
// extra check in case there was an uncaught error during the // extra check in case there was an uncaught error during the
// signature and submission process // signature and submission process
if (!txHash) { if (!txHash) {
@ -128,6 +130,15 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
this.emit('tx:failed', txId, noTxHashErr) this.emit('tx:failed', txId, noTxHashErr)
return return
} }
// If another tx with the same nonce is mined, set as failed.
const taken = await this._checkIfNonceIsTaken(txMeta)
if (taken) {
const nonceTakenErr = new Error('Another transaction with this nonce has been mined.')
nonceTakenErr.name = 'NonceTakenErr'
return this.emit('tx:failed', txId, nonceTakenErr)
}
// get latest transaction status // get latest transaction status
let txParams let txParams
try { try {
@ -159,4 +170,13 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
} }
nonceGlobalLock.releaseLock() nonceGlobalLock.releaseLock()
} }
async _checkIfNonceIsTaken (txMeta) {
const completed = this.getCompletedTransactions()
const sameNonce = completed.filter((otherMeta) => {
return otherMeta.txParams.nonce === txMeta.txParams.nonce
})
return sameNonce.length > 0
}
} }

Loading…
Cancel
Save