mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
fix nonceTracker
This commit is contained in:
parent
fa8c74fe9b
commit
92df9965eb
@ -25,7 +25,7 @@ module.exports = class TransactionController extends EventEmitter {
|
|||||||
this.blockTracker = opts.blockTracker
|
this.blockTracker = opts.blockTracker
|
||||||
this.nonceTracker = new NonceTracker({
|
this.nonceTracker = new NonceTracker({
|
||||||
provider: this.provider,
|
provider: this.provider,
|
||||||
blockTracker: this.blockTracker,
|
blockTracker: this.provider._blockTracker,
|
||||||
getPendingTransactions: (address) => this.getFilteredTxList({ from: address, status: 'submitted' }),
|
getPendingTransactions: (address) => this.getFilteredTxList({ from: address, status: 'submitted' }),
|
||||||
})
|
})
|
||||||
this.query = opts.ethQuery
|
this.query = opts.ethQuery
|
||||||
@ -176,33 +176,7 @@ module.exports = class TransactionController extends EventEmitter {
|
|||||||
}, {})
|
}, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
// approveTransaction (txId, cb = warn) {
|
async approveTransaction (txId, cb = warn) {
|
||||||
// promiseToCallback((async () => {
|
|
||||||
// // approve
|
|
||||||
// self.setTxStatusApproved(txId)
|
|
||||||
// // get next nonce
|
|
||||||
// const txMeta = this.getTx(txId)
|
|
||||||
// const fromAddress = txMeta.txParams.from
|
|
||||||
// const { nextNonce, releaseLock } = await this.nonceTracker.getNonceLock(fromAddress)
|
|
||||||
// txMeta.txParams.nonce = nonce
|
|
||||||
// this.updateTx(txMeta)
|
|
||||||
// // sign transaction
|
|
||||||
// const rawTx = await denodeify(self.signTransaction.bind(self))(txId)
|
|
||||||
// await denodeify(self.publishTransaction.bind(self))(txId, rawTx)
|
|
||||||
// })())((err) => {
|
|
||||||
// if (err) {
|
|
||||||
// this.setTxStatusFailed(txId, {
|
|
||||||
// errCode: err.errCode || err,
|
|
||||||
// message: err.message || 'Transaction failed during approval',
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// // must set transaction to submitted/failed before releasing lock
|
|
||||||
// releaseLock()
|
|
||||||
// cb(err)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
async approveTransaction (txId) {
|
|
||||||
let nonceLock
|
let nonceLock
|
||||||
try {
|
try {
|
||||||
// approve
|
// approve
|
||||||
@ -215,9 +189,10 @@ module.exports = class TransactionController extends EventEmitter {
|
|||||||
this.updateTx(txMeta)
|
this.updateTx(txMeta)
|
||||||
// sign transaction
|
// sign transaction
|
||||||
const rawTx = await denodeify(this.signTransaction.bind(this))(txId)
|
const rawTx = await denodeify(this.signTransaction.bind(this))(txId)
|
||||||
await denodeify(this.publishTransaction.bind(this))(txId, rawTx)
|
await this.publishTransaction(txId, rawTx)
|
||||||
// must set transaction to submitted/failed before releasing lock
|
// must set transaction to submitted/failed before releasing lock
|
||||||
nonceLock.releaseLock()
|
nonceLock.releaseLock()
|
||||||
|
cb()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.setTxStatusFailed(txId, {
|
this.setTxStatusFailed(txId, {
|
||||||
errCode: err.errCode || err,
|
errCode: err.errCode || err,
|
||||||
@ -226,7 +201,7 @@ module.exports = class TransactionController extends EventEmitter {
|
|||||||
// must set transaction to submitted/failed before releasing lock
|
// must set transaction to submitted/failed before releasing lock
|
||||||
if (nonceLock) nonceLock.releaseLock()
|
if (nonceLock) nonceLock.releaseLock()
|
||||||
// continue with error chain
|
// continue with error chain
|
||||||
throw err
|
cb(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,16 +235,17 @@ module.exports = class TransactionController extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
publishTransaction (txId, rawTx, cb = warn) {
|
publishTransaction (txId, rawTx) {
|
||||||
const txMeta = this.getTx(txId)
|
const txMeta = this.getTx(txId)
|
||||||
txMeta.rawTx = rawTx
|
txMeta.rawTx = rawTx
|
||||||
this.updateTx(txMeta)
|
this.updateTx(txMeta)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => {
|
this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => {
|
||||||
if (err) return cb(err)
|
if (err) reject(err)
|
||||||
this.setTxHash(txId, txHash)
|
this.setTxHash(txId, txHash)
|
||||||
this.setTxStatusSubmitted(txId)
|
this.setTxStatusSubmitted(txId)
|
||||||
cb()
|
resolve()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +390,6 @@ module.exports = class TransactionController extends EventEmitter {
|
|||||||
this.emit(`${txMeta.id}:${status}`, txId)
|
this.emit(`${txMeta.id}:${status}`, txId)
|
||||||
if (status === 'submitted' || status === 'rejected') {
|
if (status === 'submitted' || status === 'rejected') {
|
||||||
this.emit(`${txMeta.id}:finished`, txMeta)
|
this.emit(`${txMeta.id}:finished`, txMeta)
|
||||||
|
|
||||||
}
|
}
|
||||||
this.updateTx(txMeta)
|
this.updateTx(txMeta)
|
||||||
this.emit('updateBadge')
|
this.emit('updateBadge')
|
||||||
|
@ -2,7 +2,7 @@ const EthQuery = require('eth-query')
|
|||||||
|
|
||||||
class NonceTracker {
|
class NonceTracker {
|
||||||
|
|
||||||
constructor({ blockTracker, provider, getPendingTransactions }) {
|
constructor ({ blockTracker, provider, getPendingTransactions }) {
|
||||||
this.blockTracker = blockTracker
|
this.blockTracker = blockTracker
|
||||||
this.ethQuery = new EthQuery(provider)
|
this.ethQuery = new EthQuery(provider)
|
||||||
this.getPendingTransactions = getPendingTransactions
|
this.getPendingTransactions = getPendingTransactions
|
||||||
@ -11,7 +11,7 @@ class NonceTracker {
|
|||||||
|
|
||||||
// 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 lock free
|
// await lock free
|
||||||
await this.lockMap[address]
|
await this.lockMap[address]
|
||||||
// take lock
|
// take lock
|
||||||
@ -21,12 +21,12 @@ class NonceTracker {
|
|||||||
const blockNumber = currentBlock.number
|
const blockNumber = currentBlock.number
|
||||||
const pendingTransactions = this.getPendingTransactions(address)
|
const pendingTransactions = this.getPendingTransactions(address)
|
||||||
const baseCount = await this._getTxCount(address, blockNumber)
|
const baseCount = await this._getTxCount(address, blockNumber)
|
||||||
const nextNonce = parseInt(baseCount) + pendingTransactions.length + 1
|
const nextNonce = parseInt(baseCount) + pendingTransactions.length
|
||||||
// return next nonce and release cb
|
// return next nonce and release cb
|
||||||
return { nextNonce: nextNonce.toString(16), releaseLock }
|
return { nextNonce: nextNonce.toString(16), releaseLock }
|
||||||
}
|
}
|
||||||
|
|
||||||
async _getCurrentBlock() {
|
async _getCurrentBlock () {
|
||||||
const currentBlock = this.blockTracker.getCurrentBlock()
|
const currentBlock = this.blockTracker.getCurrentBlock()
|
||||||
if (currentBlock) return currentBlock
|
if (currentBlock) return currentBlock
|
||||||
return await Promise((reject, resolve) => {
|
return await Promise((reject, resolve) => {
|
||||||
@ -34,15 +34,13 @@ class NonceTracker {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_takeLock(lockId) {
|
_takeLock (lockId) {
|
||||||
let releaseLock = null
|
let releaseLock = null
|
||||||
// create and store lock
|
// create and store lock
|
||||||
const lock = new Promise((resolve, reject) => { releaseLock = resolve })
|
const lock = new Promise((resolve, reject) => { releaseLock = resolve })
|
||||||
this.lockMap[lockId] = lock
|
this.lockMap[lockId] = lock
|
||||||
// setup lock teardown
|
// setup lock teardown
|
||||||
lock.then(() => {
|
lock.then(() => delete this.lockMap[lockId])
|
||||||
delete this.lockMap[lockId]
|
|
||||||
})
|
|
||||||
return releaseLock
|
return releaseLock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,31 +3,25 @@ const NonceTracker = require('../../app/scripts/lib/nonce-tracker')
|
|||||||
|
|
||||||
describe('Nonce Tracker', function () {
|
describe('Nonce Tracker', function () {
|
||||||
let nonceTracker, provider, getPendingTransactions, pendingTxs
|
let nonceTracker, provider, getPendingTransactions, pendingTxs
|
||||||
const noop = () => {}
|
|
||||||
|
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
pendingTxs =[{
|
pendingTxs = [{
|
||||||
'status': 'submitted',
|
'status': 'submitted',
|
||||||
'txParams': {
|
'txParams': {
|
||||||
'from': '0x7d3517b0d011698406d6e0aed8453f0be2697926',
|
'from': '0x7d3517b0d011698406d6e0aed8453f0be2697926',
|
||||||
'gas': '0x30d40',
|
'gas': '0x30d40',
|
||||||
'value': '0x0',
|
'value': '0x0',
|
||||||
'nonce': '0x1',
|
'nonce': '0x0',
|
||||||
},
|
},
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
|
||||||
getPendingTransactions = () => pendingTxs
|
getPendingTransactions = () => pendingTxs
|
||||||
provider = { sendAsync: (_, cb) => { cb(undefined , {result: '0x0'}) }, }
|
provider = { sendAsync: (_, cb) => { cb(undefined, {result: '0x0'}) } }
|
||||||
nonceTracker = new NonceTracker({
|
nonceTracker = new NonceTracker({
|
||||||
blockTracker: {
|
blockTracker: {
|
||||||
getCurrentBlock: () => '0x11b568',
|
getCurrentBlock: () => '0x11b568',
|
||||||
once: (...args) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
args.pop()()
|
|
||||||
}, 5000)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
provider,
|
provider,
|
||||||
getPendingTransactions,
|
getPendingTransactions,
|
||||||
@ -38,8 +32,8 @@ describe('Nonce Tracker', function () {
|
|||||||
it('should work', async function (done) {
|
it('should work', async function (done) {
|
||||||
this.timeout(15000)
|
this.timeout(15000)
|
||||||
const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
|
const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
|
||||||
assert.equal(nonceLock.nextNonce, '2', 'nonce should be 2')
|
assert.equal(nonceLock.nextNonce, '1', 'nonce should be 1')
|
||||||
nonceLock.releaseLock()
|
await nonceLock.releaseLock()
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user