1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 19:26:13 +02:00

Mark PendingTransactionTracker#resubmitPendingTxs as async (#8399)

This commit is contained in:
Whymarrh Whitby 2020-04-27 13:24:39 -02:30 committed by GitHub
parent 40cd976e8c
commit 7439cd1662
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 36 deletions

View File

@ -52,45 +52,41 @@ export default class PendingTransactionTracker extends EventEmitter {
* Resubmits each pending transaction
* @param {string} blockNumber - the latest block number in hex
* @emits tx:warning
* @returns {Promise<void>}
*/
resubmitPendingTxs (blockNumber) {
async resubmitPendingTxs (blockNumber) {
const pending = this.getPendingTransactions()
// only try resubmitting if their are transactions to resubmit
if (!pending.length) {
return
}
pending.forEach((txMeta) => this._resubmitTx(txMeta, blockNumber).catch((err) => {
/*
Dont marked as failed if the error is a "known" transaction warning
"there is already a transaction with the same sender-nonce
but higher/same gas price"
Also don't mark as failed if it has ever been broadcast successfully.
A successful broadcast means it may still be mined.
*/
const errorMessage = err.message.toLowerCase()
const isKnownTx = (
// geth
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') ||
// other
errorMessage.includes('gateway timeout') ||
errorMessage.includes('nonce too low')
)
// ignore resubmit warnings, return early
if (isKnownTx) {
return
for (const txMeta of pending) {
try {
await this._resubmitTx(txMeta, blockNumber)
} catch (err) {
const errorMessage = err.message.toLowerCase()
const isKnownTx = (
// geth
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') ||
// other
errorMessage.includes('gateway timeout') ||
errorMessage.includes('nonce too low')
)
// ignore resubmit warnings, return early
if (isKnownTx) {
return
}
// encountered real error - transition to error state
txMeta.warning = {
error: errorMessage,
message: 'There was an error when resubmitting this transaction.',
}
this.emit('tx:warning', txMeta, err)
}
// encountered real error - transition to error state
txMeta.warning = {
error: errorMessage,
message: 'There was an error when resubmitting this transaction.',
}
this.emit('tx:warning', txMeta, err)
}))
}
}
/**

View File

@ -25,7 +25,7 @@ describe('PendingTransactionTracker', function () {
const warningListener = sinon.spy()
pendingTxTracker.on('tx:warning', warningListener)
pendingTxTracker.resubmitPendingTxs('0x1')
await pendingTxTracker.resubmitPendingTxs('0x1')
assert.ok(getPendingTransactions.calledOnceWithExactly(), 'should call getPendingTransaction')
assert.ok(resubmitTx.notCalled, 'should NOT call _resubmitTx')
@ -57,7 +57,7 @@ describe('PendingTransactionTracker', function () {
const warningListener = sinon.spy()
pendingTxTracker.on('tx:warning', warningListener)
pendingTxTracker.resubmitPendingTxs('0x1')
await pendingTxTracker.resubmitPendingTxs('0x1')
assert.ok(getPendingTransactions.calledOnceWithExactly(), 'should call getPendingTransaction')
assert.ok(resubmitTx.calledTwice, 'should call _resubmitTx')
@ -87,12 +87,42 @@ describe('PendingTransactionTracker', function () {
const warningListener = sinon.spy()
pendingTxTracker.on('tx:warning', warningListener)
pendingTxTracker.resubmitPendingTxs('0x1')
await pendingTxTracker.resubmitPendingTxs('0x1')
assert.ok(getPendingTransactions.calledOnceWithExactly(), 'should call getPendingTransaction')
assert.ok(resubmitTx.calledOnce, 'should call _resubmitTx')
assert.ok(warningListener.notCalled, "should NOT emit 'tx:warning'")
})
it("should emit 'tx:warning' for unknown failed resubmission", async function () {
const getPendingTransactions = sinon.stub().returns([{
id: 1,
}])
const pendingTxTracker = new PendingTransactionTracker({
query: {
getTransactionReceipt: sinon.stub(),
},
nonceTracker: {
getGlobalLock: sinon.stub().resolves({
releaseLock: sinon.spy(),
}),
},
getPendingTransactions,
getCompletedTransactions: sinon.stub().returns([]),
approveTransaction: sinon.spy(),
publishTransaction: sinon.spy(),
confirmTransaction: sinon.spy(),
})
const resubmitTx = sinon.stub(pendingTxTracker, '_resubmitTx').rejects({ message: 'who dis' })
const warningListener = sinon.spy()
pendingTxTracker.on('tx:warning', warningListener)
await pendingTxTracker.resubmitPendingTxs('0x1')
assert.ok(getPendingTransactions.calledOnceWithExactly(), 'should call getPendingTransaction')
assert.ok(resubmitTx.calledOnce, 'should call _resubmitTx')
assert.ok(warningListener.calledOnce, "should emit 'tx:warning'")
})
})
describe('#updatePendingTxs', function () {