diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/lib/nonce-tracker.js index ba05fd124..7a450cb78 100644 --- a/app/scripts/lib/nonce-tracker.js +++ b/app/scripts/lib/nonce-tracker.js @@ -1,5 +1,6 @@ const EthQuery = require('eth-query') const assert = require('assert') +const Mutex = require('await-semaphore').Mutex class NonceTracker { @@ -13,10 +14,8 @@ class NonceTracker { // releaseLock must be called // releaseLock must be called after adding signed tx to pending transactions (or discarding) async getNonceLock (address) { - // await lock free - await this.lockMap[address] - // take lock - const releaseLock = this._takeLock(address) + // await lock free, then take lock + const releaseLock = await this._takeMutex(address) // calculate next nonce // we need to make sure our base count // and pending count are from the same block @@ -41,13 +40,18 @@ class NonceTracker { }) } - _takeLock (lockId) { - let releaseLock = null - // create and store lock - const lock = new Promise((resolve, reject) => { releaseLock = resolve }) - this.lockMap[lockId] = lock - // setup lock teardown - lock.then(() => delete this.lockMap[lockId]) + _lookupMutex (lockId) { + let mutex = this.lockMap[lockId] + if (!mutex) { + mutex = new Mutex() + this.lockMap[lockId] = mutex + } + return mutex + } + + async _takeMutex (lockId) { + const mutex = this._lookupMutex(lockId) + const releaseLock = await mutex.acquire() return releaseLock } diff --git a/package.json b/package.json index e0bb303bf..d40ad068b 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ }, "dependencies": { "async": "^1.5.2", + "await-semaphore": "^0.1.1", "babel-runtime": "^6.23.0", "bip39": "^2.2.0", "bluebird": "^3.5.0",