Skip to content

Commit

Permalink
transactions/pending - clean up dropped event
Browse files Browse the repository at this point in the history
  • Loading branch information
frankiebee committed Apr 8, 2019
1 parent c271857 commit bfd2d2c
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 27 deletions.
10 changes: 1 addition & 9 deletions app/scripts/controllers/transactions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -542,15 +542,7 @@ class TransactionController extends EventEmitter {
})
this.pendingTxTracker.on('tx:failed', this.txStateManager.setTxStatusFailed.bind(this.txStateManager))
this.pendingTxTracker.on('tx:confirmed', (txId) => this.confirmTransaction(txId))
this.pendingTxTracker.on('tx:dropped', (txId) => {
const txMeta = this.txStateManager.getTx(txId)
if (!txMeta.dropBlockBuffer) {
txMeta.dropBlockBuffer = 1
this.txStateManager.updateTx(txMeta, 'transactions/pending-tx-tracker#event: tx:drop-update')
return
}
this.setTxStatusDropped(txId)
})
this.pendingTxTracker.on('tx:dropped', this.txStateManager.setTxStatusDropped.bind(this.txStateManager))
this.pendingTxTracker.on('tx:block-update', (txMeta, latestBlockNumber) => {
if (!txMeta.firstRetryBlockNumber) {
txMeta.firstRetryBlockNumber = latestBlockNumber
Expand Down
36 changes: 28 additions & 8 deletions app/scripts/controllers/transactions/pending-tx-tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const EthQuery = require('ethjs-query')
class PendingTransactionTracker extends EventEmitter {
constructor (config) {
super()
this.droppedBuffer = {}
this.query = new EthQuery(config.provider)
this.nonceTracker = config.nonceTracker
this.getPendingTransactions = config.getPendingTransactions
Expand Down Expand Up @@ -139,18 +140,38 @@ class PendingTransactionTracker extends EventEmitter {
const noTxHashErr = new Error('We had an error while submitting this transaction, please try again.')
noTxHashErr.name = 'NoTxHashError'
this.emit('tx:failed', txId, noTxHashErr)

return
}

// If another tx with the same nonce is mined, set as dropped.
const taken = await this._checkIfNonceIsTaken(txMeta)
if (taken) {
let dropped
try {
// check the network if the nonce is ahead the tx
// and the tx has not been mined into a block

dropped = await this._checkIftxWasDropped(txMeta)
// the dropped buffer is encase we ask a node for the tx
// that is behind the node we asked for tx count
// IS A SECURITY FOR HITTING NODES IN INFURA THAT COULD GO OUT
// OF SYNC.
// on the next block event it will return fire as dropped
if (dropped && !this.droppedBuffer[txHash]) {
this.droppedBuffer[txHash] = true
dropped = false
} else if (dropped && this.droppedBuffer[txHash]) {
// clean up
delete this.droppedBuffer[txHash]
}

} catch (e) {
log.error(e)
}
if (taken || dropped) {
return this.emit('tx:dropped', txId)
}

const dropped = await this._checkIftxWasDropped(txMeta)
if (dropped) return

// get latest transaction status
try {
const { blockNumber } = await this.query.getTransactionByHash(txHash) || {}
Expand All @@ -173,12 +194,11 @@ class PendingTransactionTracker extends EventEmitter {
*/

async _checkIftxWasDropped (txMeta) {
const { txParams: { nonce, from }, hash, id } = txMeta
const { txParams: { nonce, from }, hash } = txMeta
const nextNonce = await this.query.getTransactionCount(from)
const { blockNumber } = await this.query.getTransactionByHash(hash) || {}
if (!blockNumber && parseInt(nextNonce) > nonce) {
this.emit('tx:dropped', id)
return true
if (!blockNumber && parseInt(nextNonce) > parseInt(nonce)) {
return true
}
return false
}
Expand Down
41 changes: 31 additions & 10 deletions test/unit/app/controllers/transactions/pending-tx-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,36 @@ describe('PendingTransactionTracker', function () {
pendingTxTracker._checkPendingTx(txMetaNoHash)
})

it('should emit tx:dropped with the txMetas id only after the second call', function (done) {
txMeta = {
id: 1,
hash: '0x0593ee121b92e10d63150ad08b4b8f9c7857d1bd160195ee648fb9a0f8d00eeb',
status: 'submitted',
txParams: {
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
nonce: '0x1',
value: '0xfffff',
},
history: [{}],
rawTx: '0xf86c808504a817c800827b0d940c62bb85faa3311a998d3aba8098c1235c564966880de0b6b3a7640000802aa08ff665feb887a25d4099e40e11f0fef93ee9608f404bd3f853dd9e84ed3317a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d',
}

providerResultStub['eth_getTransactionCount'] = '0x02'
providerResultStub['eth_getTransactionByHash'] = {}
pendingTxTracker.once('tx:dropped', (id) => {
if (id === txMeta.id) {
delete providerResultStub['eth_getTransactionCount']
delete providerResultStub['eth_getTransactionByHash']
return done()
} else done(new Error('wrong tx Id'))
})

pendingTxTracker._checkPendingTx(txMeta).then(() => {
pendingTxTracker._checkPendingTx(txMeta).catch(done)
}).catch(done)
})


it('should should return if query does not return txParams', function () {
providerResultStub.eth_getTransactionByHash = null
pendingTxTracker._checkPendingTx(txMeta)
Expand Down Expand Up @@ -286,7 +316,7 @@ describe('PendingTransactionTracker', function () {
const txMeta = {
id: 1,
hash: '0x0593ee121b92e10d63150ad08b4b8f9c7857d1bd160195ee648fb9a0f8d00eeb',
status: 'confirmed',
status: 'submitted',
txParams: {
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
nonce: '0x1',
Expand All @@ -311,15 +341,6 @@ describe('PendingTransactionTracker', function () {
done()
}).catch(done)
})
it('should emit tx:dropped with th txMetas id', function (done) {
providerResultStub['eth_getTransactionCount'] = '0x02'
providerResultStub['eth_getTransactionByHash'] = {}
pendingTxTracker.once('tx:dropped', (id) => {
if (id === txMeta.id) return done()
else done(new Error('wrong tx Id'))
})
pendingTxTracker._checkIftxWasDropped(txMeta).catch(done)
})
})

describe('#_checkIfNonceIsTaken', function () {
Expand Down

0 comments on commit bfd2d2c

Please sign in to comment.