transactions - block nonce-tracker while updating pending transactions

feature/default_network_editable
kumavis 7 years ago
parent aa48ed34c4
commit 12d6f21627
  1. 3
      app/scripts/controllers/transactions.js
  2. 41
      app/scripts/lib/nonce-tracker.js

@ -484,12 +484,15 @@ module.exports = class TransactionController extends EventEmitter {
// if confirmed sets the tx status as 'confirmed' // if confirmed sets the tx status as 'confirmed'
async _checkPendingTxs () { async _checkPendingTxs () {
const signedTxList = this.getFilteredTxList({status: 'submitted'}) const signedTxList = this.getFilteredTxList({status: 'submitted'})
// in order to keep the nonceTracker accurate we block it while updating pending transactions
const nonceGlobalLock = await this.nonceTracker.getGlobalLock()
try { try {
await Promise.all(signedTxList.map((txMeta) => this._checkPendingTx(txMeta))) await Promise.all(signedTxList.map((txMeta) => this._checkPendingTx(txMeta)))
} catch (err) { } catch (err) {
console.error('TransactionController - Error updating pending transactions') console.error('TransactionController - Error updating pending transactions')
console.error(err) console.error(err)
} }
nonceGlobalLock.releaseLock()
} }
async _checkPendingTx (txMeta) { async _checkPendingTx (txMeta) {

@ -11,9 +11,18 @@ class NonceTracker {
this.lockMap = {} this.lockMap = {}
} }
async getGlobalLock () {
const globalMutex = this._lookupMutex('global')
// await global mutex free
const releaseLock = await globalMutex.acquire()
return { releaseLock }
}
// releaseLock must be called // releaseLock must be called
// releaseLock must be called after adding signed tx to pending transactions (or discarding) // releaseLock must be called after adding signed tx to pending transactions (or discarding)
async getNonceLock (address) { async getNonceLock (address) {
// await global mutex free
await this._globalMutexFree()
// await lock free, then take lock // await lock free, then take lock
const releaseLock = await this._takeMutex(address) const releaseLock = await this._takeMutex(address)
// calculate next nonce // calculate next nonce
@ -40,13 +49,19 @@ class NonceTracker {
}) })
} }
_lookupMutex (lockId) { async _getTxCount (address, currentBlock) {
let mutex = this.lockMap[lockId] const blockNumber = currentBlock.number
if (!mutex) { return new Promise((resolve, reject) => {
mutex = new Mutex() this.ethQuery.getTransactionCount(address, blockNumber, (err, result) => {
this.lockMap[lockId] = mutex err ? reject(err) : resolve(result)
})
})
} }
return mutex
async _globalMutexFree () {
const globalMutex = this._lookupMutex('global')
const release = await globalMutex.acquire()
release()
} }
async _takeMutex (lockId) { async _takeMutex (lockId) {
@ -55,13 +70,13 @@ class NonceTracker {
return releaseLock return releaseLock
} }
async _getTxCount (address, currentBlock) { _lookupMutex (lockId) {
const blockNumber = currentBlock.number let mutex = this.lockMap[lockId]
return new Promise((resolve, reject) => { if (!mutex) {
this.ethQuery.getTransactionCount(address, blockNumber, (err, result) => { mutex = new Mutex()
err ? reject(err) : resolve(result) this.lockMap[lockId] = mutex
}) }
}) return mutex
} }
} }

Loading…
Cancel
Save