diff options
Diffstat (limited to 'app/scripts/lib/pending-tx-tracker.js')
-rw-r--r-- | app/scripts/lib/pending-tx-tracker.js | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/app/scripts/lib/pending-tx-tracker.js b/app/scripts/lib/pending-tx-tracker.js index df504c126..e8869e6b8 100644 --- a/app/scripts/lib/pending-tx-tracker.js +++ b/app/scripts/lib/pending-tx-tracker.js @@ -23,7 +23,6 @@ module.exports = class PendingTransactionTracker extends EventEmitter { this.query = new EthQuery(config.provider) this.nonceTracker = config.nonceTracker // default is one day - this.retryTimePeriod = config.retryTimePeriod || 86400000 this.getPendingTransactions = config.getPendingTransactions this.getCompletedTransactions = config.getCompletedTransactions this.publishTransaction = config.publishTransaction @@ -65,11 +64,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 @@ -81,14 +80,14 @@ module.exports = class PendingTransactionTracker extends EventEmitter { const errorMessage = err.message.toLowerCase() const isKnownTx = ( // geth - errorMessage.includes('replacement transaction underpriced') - || errorMessage.includes('known transaction') + errorMessage.includes('replacement transaction underpriced') || + errorMessage.includes('known transaction') || // parity - || errorMessage.includes('gas price too low to replace') - || errorMessage.includes('transaction with the same hash was already imported') + errorMessage.includes('gas price too low to replace') || + errorMessage.includes('transaction with the same hash was already imported') || // other - || errorMessage.includes('gateway timeout') - || errorMessage.includes('nonce too low') + errorMessage.includes('gateway timeout') || + errorMessage.includes('nonce too low') ) // ignore resubmit warnings, return early if (isKnownTx) return @@ -101,13 +100,19 @@ module.exports = class PendingTransactionTracker extends EventEmitter { })) } - async _resubmitTx (txMeta) { - 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) + async _resubmitTx (txMeta, latestBlockNumber) { + if (!txMeta.firstRetryBlockNumber) { + this.emit('tx:block-update', txMeta, latestBlockNumber) } + 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 @@ -173,7 +178,8 @@ module.exports = class PendingTransactionTracker extends EventEmitter { } async _checkIfNonceIsTaken (txMeta) { - const completed = this.getCompletedTransactions() + const address = txMeta.txParams.from + const completed = this.getCompletedTransactions(address) const sameNonce = completed.filter((otherMeta) => { return otherMeta.txParams.nonce === txMeta.txParams.nonce }) |