From dab2fccc78ad76095cc12ce0a1056d9b7a9d6001 Mon Sep 17 00:00:00 2001 From: kumavis Date: Wed, 14 Jun 2017 22:16:14 -0700 Subject: introduce nonce-tracker --- app/scripts/lib/nonce-tracker.js | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 app/scripts/lib/nonce-tracker.js (limited to 'app') diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/lib/nonce-tracker.js new file mode 100644 index 000000000..6e9d094bc --- /dev/null +++ b/app/scripts/lib/nonce-tracker.js @@ -0,0 +1,49 @@ +const EthQuery = require('ethjs-query') + +class NonceTracker { + + constructor({ blockTracker, provider, getPendingTransactions }) { + this.blockTracker = blockTracker + this.ethQuery = new EthQuery(provider) + this.getPendingTransactions = getPendingTransactions + this.lockMap = {} + } + + // 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) + // calculate next nonce + const currentBlock = await this._getCurrentBlock() + const blockNumber = currentBlock.number + const pendingTransactions = this.getPendingTransactions(address) + const baseCount = await this.ethQuery.getTransactionCount(address, blockNumber) + const nextNonce = baseCount + pendingTransactions + // return next nonce and release cb + return { nextNonce, releaseLock } + } + + async _getCurrentBlock() { + const currentBlock = this.blockTracker.getCurrentBlock() + if (currentBlock) return currentBlock + return await Promise((reject, resolve) => { + this.blockTracker.once('latest', resolve) + }) + } + + _takeLock(lockId) { + let releaseLock = null + // create and store lock + const lock = new Promise((reject, resolve) => { releaseLock = resolve }) + this.lockMap[lockId] = lock + // setup lock teardown + lock.then(() => delete this.lockMap[lockId]) + return releaseLock + } + +} + +module.exports = NonceTracker -- cgit v1.2.3 From b3492d9c17e62332c17bb082c23db30512e2b881 Mon Sep 17 00:00:00 2001 From: kumavis Date: Wed, 14 Jun 2017 23:44:02 -0700 Subject: transaction controller - use nonce-tracker --- app/scripts/controllers/transactions.js | 90 +++++++++++++++++++++------------ app/scripts/metamask-controller.js | 2 +- 2 files changed, 59 insertions(+), 33 deletions(-) (limited to 'app') diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 2db8041eb..e7fe9927e 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -4,9 +4,10 @@ const extend = require('xtend') const Semaphore = require('semaphore') const ObservableStore = require('obs-store') const ethUtil = require('ethereumjs-util') +const denodeify = require('denodeify') const TxProviderUtil = require('../lib/tx-utils') const createId = require('../lib/random-id') -const denodeify = require('denodeify') +const NonceTracker = require('../lib/nonce-tracker') const RETRY_LIMIT = 200 @@ -22,6 +23,11 @@ module.exports = class TransactionController extends EventEmitter { this.txHistoryLimit = opts.txHistoryLimit this.provider = opts.provider this.blockTracker = opts.blockTracker + this.nonceTracker = new NonceTracker({ + provider: this.provider, + blockTracker: this.blockTracker, + getPendingTransactions: (address) => this.getFilteredTxList({ from: address, status: 'submitted' }), + }) this.query = opts.ethQuery this.txProviderUtils = new TxProviderUtil(this.query) this.blockTracker.on('block', this.checkForTxInBlock.bind(this)) @@ -169,29 +175,58 @@ module.exports = class TransactionController extends EventEmitter { }, {}) } - approveTransaction (txId, cb = warn) { - const self = this - // approve - self.setTxStatusApproved(txId) - // only allow one tx at a time for atomic nonce usage - self.nonceLock.take(() => { - // begin signature process - async.waterfall([ - (cb) => self.fillInTxParams(txId, cb), - (cb) => self.signTransaction(txId, cb), - (rawTx, cb) => self.publishTransaction(txId, rawTx, cb), - ], (err) => { - self.nonceLock.leave() - if (err) { - this.setTxStatusFailed(txId, { - errCode: err.errCode || err, - message: err.message || 'Transaction failed during approval', - }) - return cb(err) - } - cb() + // 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 + try { + // approve + this.setTxStatusApproved(txId) + // get next nonce + const txMeta = this.getTx(txId) + const fromAddress = txMeta.txParams.from + nonceLock = await this.nonceTracker.getNonceLock(fromAddress) + txMeta.txParams.nonce = nonceLock.nextNonce + this.updateTx(txMeta) + // sign transaction + const rawTx = await denodeify(this.signTransaction.bind(this))(txId) + await denodeify(this.publishTransaction.bind(this))(txId, rawTx) + // must set transaction to submitted/failed before releasing lock + nonceLock.releaseLock() + } catch (err) { + this.setTxStatusFailed(txId, { + errCode: err.errCode || err, + message: err.message || 'Transaction failed during approval', }) - }) + // must set transaction to submitted/failed before releasing lock + if (nonceLock) nonceLock.releaseLock() + // continue with error chain + throw err + } } cancelTransaction (txId, cb = warn) { @@ -199,15 +234,6 @@ module.exports = class TransactionController extends EventEmitter { cb() } - fillInTxParams (txId, cb) { - const txMeta = this.getTx(txId) - this.txProviderUtils.fillInTxParams(txMeta.txParams, (err) => { - if (err) return cb(err) - this.updateTx(txMeta) - cb() - }) - } - getChainId () { const networkState = this.networkStore.getState() const getChainId = parseInt(networkState) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index a7eb3d056..006a32eac 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -290,7 +290,7 @@ module.exports = class MetamaskController extends EventEmitter { exportAccount: nodeify(keyringController.exportAccount).bind(keyringController), // txController - approveTransaction: txController.approveTransaction.bind(txController), + approveTransaction: nodeify(txController.approveTransaction).bind(txController), cancelTransaction: txController.cancelTransaction.bind(txController), updateAndApproveTransaction: this.updateAndApproveTx.bind(this), -- cgit v1.2.3 From fa8c74fe9b19229580224815cc131611ee29027c Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 21 Jun 2017 17:28:19 -0700 Subject: add a test for #getNonceLock --- app/scripts/lib/nonce-tracker.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'app') diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/lib/nonce-tracker.js index 6e9d094bc..ff2317a91 100644 --- a/app/scripts/lib/nonce-tracker.js +++ b/app/scripts/lib/nonce-tracker.js @@ -1,4 +1,4 @@ -const EthQuery = require('ethjs-query') +const EthQuery = require('eth-query') class NonceTracker { @@ -20,10 +20,10 @@ class NonceTracker { const currentBlock = await this._getCurrentBlock() const blockNumber = currentBlock.number const pendingTransactions = this.getPendingTransactions(address) - const baseCount = await this.ethQuery.getTransactionCount(address, blockNumber) - const nextNonce = baseCount + pendingTransactions + const baseCount = await this._getTxCount(address, blockNumber) + const nextNonce = parseInt(baseCount) + pendingTransactions.length + 1 // return next nonce and release cb - return { nextNonce, releaseLock } + return { nextNonce: nextNonce.toString(16), releaseLock } } async _getCurrentBlock() { @@ -37,13 +37,23 @@ class NonceTracker { _takeLock(lockId) { let releaseLock = null // create and store lock - const lock = new Promise((reject, resolve) => { releaseLock = resolve }) + const lock = new Promise((resolve, reject) => { releaseLock = resolve }) this.lockMap[lockId] = lock // setup lock teardown - lock.then(() => delete this.lockMap[lockId]) + lock.then(() => { + delete this.lockMap[lockId] + }) return releaseLock } + _getTxCount (address, blockNumber) { + return new Promise((resolve, reject) => { + this.ethQuery.getTransactionCount(address, blockNumber, (err, result) => { + err ? reject(err) : resolve(result) + }) + }) + } + } module.exports = NonceTracker -- cgit v1.2.3 From 92df9965ebd4a833817c32fd32f7e4533ec7fe19 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 21 Jun 2017 19:51:00 -0700 Subject: fix nonceTracker --- app/scripts/controllers/transactions.js | 51 +++++++++------------------------ app/scripts/lib/nonce-tracker.js | 14 ++++----- 2 files changed, 19 insertions(+), 46 deletions(-) (limited to 'app') diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index c2f98e66a..59c8be8b7 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -25,7 +25,7 @@ module.exports = class TransactionController extends EventEmitter { this.blockTracker = opts.blockTracker this.nonceTracker = new NonceTracker({ provider: this.provider, - blockTracker: this.blockTracker, + blockTracker: this.provider._blockTracker, getPendingTransactions: (address) => this.getFilteredTxList({ from: address, status: 'submitted' }), }) this.query = opts.ethQuery @@ -176,33 +176,7 @@ module.exports = class TransactionController extends EventEmitter { }, {}) } - // 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) { + async approveTransaction (txId, cb = warn) { let nonceLock try { // approve @@ -215,9 +189,10 @@ module.exports = class TransactionController extends EventEmitter { this.updateTx(txMeta) // sign transaction 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 nonceLock.releaseLock() + cb() } catch (err) { this.setTxStatusFailed(txId, { errCode: err.errCode || err, @@ -226,7 +201,7 @@ module.exports = class TransactionController extends EventEmitter { // must set transaction to submitted/failed before releasing lock if (nonceLock) nonceLock.releaseLock() // 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) txMeta.rawTx = rawTx this.updateTx(txMeta) - - this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => { - if (err) return cb(err) - this.setTxHash(txId, txHash) - this.setTxStatusSubmitted(txId) - cb() + return new Promise((resolve, reject) => { + this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => { + if (err) reject(err) + this.setTxHash(txId, txHash) + this.setTxStatusSubmitted(txId) + resolve() + }) }) } @@ -414,7 +390,6 @@ module.exports = class TransactionController extends EventEmitter { this.emit(`${txMeta.id}:${status}`, txId) if (status === 'submitted' || status === 'rejected') { this.emit(`${txMeta.id}:finished`, txMeta) - } this.updateTx(txMeta) this.emit('updateBadge') diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/lib/nonce-tracker.js index ff2317a91..4ea511dec 100644 --- a/app/scripts/lib/nonce-tracker.js +++ b/app/scripts/lib/nonce-tracker.js @@ -2,7 +2,7 @@ const EthQuery = require('eth-query') class NonceTracker { - constructor({ blockTracker, provider, getPendingTransactions }) { + constructor ({ blockTracker, provider, getPendingTransactions }) { this.blockTracker = blockTracker this.ethQuery = new EthQuery(provider) this.getPendingTransactions = getPendingTransactions @@ -11,7 +11,7 @@ class NonceTracker { // releaseLock must be called // releaseLock must be called after adding signed tx to pending transactions (or discarding) - async getNonceLock(address) { + async getNonceLock (address) { // await lock free await this.lockMap[address] // take lock @@ -21,12 +21,12 @@ class NonceTracker { const blockNumber = currentBlock.number const pendingTransactions = this.getPendingTransactions(address) 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 { nextNonce: nextNonce.toString(16), releaseLock } } - async _getCurrentBlock() { + async _getCurrentBlock () { const currentBlock = this.blockTracker.getCurrentBlock() if (currentBlock) return currentBlock return await Promise((reject, resolve) => { @@ -34,15 +34,13 @@ class NonceTracker { }) } - _takeLock(lockId) { + _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] - }) + lock.then(() => delete this.lockMap[lockId]) return releaseLock } -- cgit v1.2.3 From 0ee4502d716ebe28fa426a05c454a75c7f82d965 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 27 Jun 2017 15:26:04 -0700 Subject: calculate nonce based on local pending txs w/o error state. --- app/scripts/controllers/transactions.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 651565519..460280578 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -26,7 +26,7 @@ module.exports = class TransactionController extends EventEmitter { this.nonceTracker = new NonceTracker({ provider: this.provider, blockTracker: this.provider._blockTracker, - getPendingTransactions: (address) => this.getFilteredTxList({ from: address, status: 'submitted' }), + getPendingTransactions: (address) => this.getFilteredTxList({ from: address, status: 'submitted', err: undefined }), }) this.query = opts.ethQuery this.txProviderUtils = new TxProviderUtil(this.query) @@ -263,10 +263,19 @@ module.exports = class TransactionController extends EventEmitter { to: '0x0..', from: '0x0..', status: 'signed', + err: undefined, } and returns a list of tx with all options matching + ****************HINT**************** + | `err: undefined` is like looking | + | for a tx with no err | + | so you can also search txs that | + | dont have something as well by | + | setting the value as undefined | + ************************************ + this is for things like filtering a the tx list for only tx's from 1 account or for filltering for all txs from one account -- cgit v1.2.3 From 690685d20de310b4c4589e92a5053afd9c56e85a Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 27 Jun 2017 16:46:14 -0700 Subject: nonce-tracker: only check transactions that are not supposed to be ignored --- app/scripts/controllers/transactions.js | 9 ++++++++- app/scripts/lib/nonce-tracker.js | 13 +++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'app') diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 460280578..c74427cd5 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -26,7 +26,14 @@ module.exports = class TransactionController extends EventEmitter { this.nonceTracker = new NonceTracker({ provider: this.provider, blockTracker: this.provider._blockTracker, - getPendingTransactions: (address) => this.getFilteredTxList({ from: address, status: 'submitted', err: undefined }), + getPendingTransactions: (address) => { + return this.getFilteredTxList({ + from: address, + status: 'submitted', + err: undefined, + ignore: undefined, + }) + }, }) this.query = opts.ethQuery this.txProviderUtils = new TxProviderUtil(this.query) diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/lib/nonce-tracker.js index 4ea511dec..9ef7706f9 100644 --- a/app/scripts/lib/nonce-tracker.js +++ b/app/scripts/lib/nonce-tracker.js @@ -12,15 +12,14 @@ class NonceTracker { // releaseLock must be called // releaseLock must be called after adding signed tx to pending transactions (or discarding) async getNonceLock (address) { + const pendingTransactions = this.getPendingTransactions(address) // await lock free - await this.lockMap[address] + if (pendingTransactions.length) await this.lockMap[address] + else if (this.lockMap[address]) await this.lockMap[address]() // take lock const releaseLock = this._takeLock(address) // calculate next nonce - const currentBlock = await this._getCurrentBlock() - const blockNumber = currentBlock.number - const pendingTransactions = this.getPendingTransactions(address) - const baseCount = await this._getTxCount(address, blockNumber) + const baseCount = await this._getTxCount(address) const nextNonce = parseInt(baseCount) + pendingTransactions.length // return next nonce and release cb return { nextNonce: nextNonce.toString(16), releaseLock } @@ -44,7 +43,9 @@ class NonceTracker { return releaseLock } - _getTxCount (address, blockNumber) { + async _getTxCount (address) { + const currentBlock = await this._getCurrentBlock() + const blockNumber = currentBlock.number return new Promise((resolve, reject) => { this.ethQuery.getTransactionCount(address, blockNumber, (err, result) => { err ? reject(err) : resolve(result) -- cgit v1.2.3 From 6d2cddaac9348b0e9c8a6cc4a6621927765e7c17 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 5 Jul 2017 12:00:42 -0700 Subject: fix nonce calculation order --- app/scripts/lib/nonce-tracker.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'app') diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/lib/nonce-tracker.js index 9ef7706f9..ab2893b10 100644 --- a/app/scripts/lib/nonce-tracker.js +++ b/app/scripts/lib/nonce-tracker.js @@ -12,14 +12,16 @@ class NonceTracker { // releaseLock must be called // releaseLock must be called after adding signed tx to pending transactions (or discarding) async getNonceLock (address) { - const pendingTransactions = this.getPendingTransactions(address) // await lock free - if (pendingTransactions.length) await this.lockMap[address] - else if (this.lockMap[address]) await this.lockMap[address]() + await this.lockMap[address] // take lock const releaseLock = this._takeLock(address) // calculate next nonce - const baseCount = await this._getTxCount(address) + // we need to make sure our base count + // and pending count are from the same block + const currentBlock = await this._getCurrentBlock() + const pendingTransactions = this.getPendingTransactions(address) + const baseCount = await this._getTxCount(address, currentBlock) const nextNonce = parseInt(baseCount) + pendingTransactions.length // return next nonce and release cb return { nextNonce: nextNonce.toString(16), releaseLock } @@ -43,8 +45,7 @@ class NonceTracker { return releaseLock } - async _getTxCount (address) { - const currentBlock = await this._getCurrentBlock() + async _getTxCount (address, currentBlock) { const blockNumber = currentBlock.number return new Promise((resolve, reject) => { this.ethQuery.getTransactionCount(address, blockNumber, (err, result) => { -- cgit v1.2.3 From 51ff6d74e884b599f78b5454b33f2bc1a046f0b2 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 5 Jul 2017 12:07:34 -0700 Subject: clean up unused code from old noncelock --- app/scripts/controllers/transactions.js | 2 -- 1 file changed, 2 deletions(-) (limited to 'app') diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index c74427cd5..2b40f9456 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -1,7 +1,6 @@ const EventEmitter = require('events') const async = require('async') const extend = require('xtend') -const Semaphore = require('semaphore') const ObservableStore = require('obs-store') const ethUtil = require('ethereumjs-util') const denodeify = require('denodeify') @@ -41,7 +40,6 @@ module.exports = class TransactionController extends EventEmitter { this.blockTracker.on('latest', this.resubmitPendingTxs.bind(this)) this.blockTracker.on('sync', this.queryPendingTxs.bind(this)) this.signEthTx = opts.signTransaction - this.nonceLock = Semaphore(1) this.ethStore = opts.ethStore // memstore is computed from a few different stores this._updateMemstore() -- cgit v1.2.3 From c121ac21ec3bed0381e36de7ead1b583a3da148c Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 11 Jul 2017 12:16:08 -0700 Subject: remove irrelevan code --- app/scripts/controllers/transactions.js | 1 - 1 file changed, 1 deletion(-) (limited to 'app') diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 2b40f9456..14b423d5d 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -30,7 +30,6 @@ module.exports = class TransactionController extends EventEmitter { from: address, status: 'submitted', err: undefined, - ignore: undefined, }) }, }) -- cgit v1.2.3 From 231ad48564758895bace7b0e750cdfa5577128f8 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Tue, 11 Jul 2017 12:52:56 -0700 Subject: Use txParams --- app/scripts/lib/tx-utils.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index 4e780fcc0..aa0cb624f 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -118,11 +118,11 @@ module.exports = class txProviderUtils { } } - sufficientBalance (tx, hexBalance) { + sufficientBalance (txParams, hexBalance) { const balance = hexToBn(hexBalance) - const value = hexToBn(tx.value) - const gasLimit = hexToBn(tx.gas) - const gasPrice = hexToBn(tx.gasPrice) + const value = hexToBn(txParams.value) + const gasLimit = hexToBn(txParams.gas) + const gasPrice = hexToBn(txParams.gasPrice) const maxCost = value.add(gasLimit.mul(gasPrice)) return balance.gte(maxCost) -- cgit v1.2.3 From da35f6744e3201bb75b896d3127d4f30d7e4d789 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 12 Jul 2017 15:06:49 -0700 Subject: use new nodeify --- app/scripts/lib/nodeify.js | 27 ++++++--------------------- app/scripts/metamask-controller.js | 38 +++++++++++++++----------------------- 2 files changed, 21 insertions(+), 44 deletions(-) (limited to 'app') diff --git a/app/scripts/lib/nodeify.js b/app/scripts/lib/nodeify.js index 51d89a8fb..4e111c8b2 100644 --- a/app/scripts/lib/nodeify.js +++ b/app/scripts/lib/nodeify.js @@ -1,24 +1,9 @@ -module.exports = function (promiseFn) { - return function () { - var args = [] - for (var i = 0; i < arguments.length - 1; i++) { - args.push(arguments[i]) - } - var cb = arguments[arguments.length - 1] +const promiseToCallback = require('promise-to-callback'); - const nodeified = promiseFn.apply(this, args) - - if (!nodeified) { - const methodName = String(promiseFn).split('(')[0] - throw new Error(`The ${methodName} did not return a Promise, but was nodeified.`) - } - nodeified.then(function (result) { - cb(null, result) - }) - .catch(function (reason) { - cb(reason) - }) - - return nodeified +module.exports = function(fn, context) { + return function(){ + const args = [].slice.call(arguments) + const callback = args.pop() + promiseToCallback(fn.apply(context, args))(callback) } } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 573594b39..f1f21b29b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -294,34 +294,33 @@ module.exports = class MetamaskController extends EventEmitter { submitPassword: this.submitPassword.bind(this), // PreferencesController - setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController), - addToken: nodeify(preferencesController.addToken).bind(preferencesController), - setCurrentAccountTab: nodeify(preferencesController.setCurrentAccountTab).bind(preferencesController), - setDefaultRpc: nodeify(this.setDefaultRpc).bind(this), - setCustomRpc: nodeify(this.setCustomRpc).bind(this), + setSelectedAddress: nodeify(preferencesController.setSelectedAddress, preferencesController), + addToken: nodeify(preferencesController.addToken, preferencesController), + setCurrentAccountTab: nodeify(preferencesController.setCurrentAccountTab, preferencesController), + setDefaultRpc: nodeify(this.setDefaultRpc, this), + setCustomRpc: nodeify(this.setCustomRpc, this), // AddressController - setAddressBook: nodeify(addressBookController.setAddressBook).bind(addressBookController), + setAddressBook: nodeify(addressBookController.setAddressBook, addressBookController), // KeyringController - setLocked: nodeify(keyringController.setLocked).bind(keyringController), - createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain).bind(keyringController), - createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore).bind(keyringController), - addNewKeyring: nodeify(keyringController.addNewKeyring).bind(keyringController), - saveAccountLabel: nodeify(keyringController.saveAccountLabel).bind(keyringController), - exportAccount: nodeify(keyringController.exportAccount).bind(keyringController), + setLocked: nodeify(keyringController.setLocked, keyringController), + createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain, keyringController), + createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore, keyringController), + addNewKeyring: nodeify(keyringController.addNewKeyring, keyringController), + saveAccountLabel: nodeify(keyringController.saveAccountLabel, keyringController), + exportAccount: nodeify(keyringController.exportAccount, keyringController), // txController - approveTransaction: nodeify(txController.approveTransaction).bind(txController), cancelTransaction: txController.cancelTransaction.bind(txController), - updateAndApproveTransaction: this.updateAndApproveTx.bind(this), + updateAndApproveTransaction: nodeify(txController.updateAndApproveTransaction, txController), // messageManager - signMessage: nodeify(this.signMessage).bind(this), + signMessage: nodeify(this.signMessage, this), cancelMessage: this.cancelMessage.bind(this), // personalMessageManager - signPersonalMessage: nodeify(this.signPersonalMessage).bind(this), + signPersonalMessage: nodeify(this.signPersonalMessage, this), cancelPersonalMessage: this.cancelPersonalMessage.bind(this), // notices @@ -502,13 +501,6 @@ module.exports = class MetamaskController extends EventEmitter { }) } - updateAndApproveTx (txMeta, cb) { - log.debug(`MetaMaskController - updateAndApproveTx: ${JSON.stringify(txMeta)}`) - const txController = this.txController - txController.updateTx(txMeta) - txController.approveTransaction(txMeta.id, cb) - } - signMessage (msgParams, cb) { log.info('MetaMaskController - signMessage') const msgId = msgParams.metamaskId -- cgit v1.2.3 From bd26ec46aa8f2d144939573a8c427e2a7743d25c Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 12 Jul 2017 15:07:56 -0700 Subject: mv updateAndApproveTx to txController --- app/scripts/controllers/transactions.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 45c6fb25a..a2842ae44 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -183,7 +183,7 @@ module.exports = class TransactionController extends EventEmitter { }, {}) } - async approveTransaction (txId, cb = warn) { + async approveTransaction (txId) { let nonceLock try { // approve @@ -199,7 +199,6 @@ module.exports = class TransactionController extends EventEmitter { await this.publishTransaction(txId, rawTx) // must set transaction to submitted/failed before releasing lock nonceLock.releaseLock() - cb() } catch (err) { this.setTxStatusFailed(txId, { errCode: err.errCode || err, @@ -208,7 +207,7 @@ module.exports = class TransactionController extends EventEmitter { // must set transaction to submitted/failed before releasing lock if (nonceLock) nonceLock.releaseLock() // continue with error chain - cb(err) + throw err } } @@ -217,6 +216,11 @@ module.exports = class TransactionController extends EventEmitter { cb() } + async updateAndApproveTransaction (txMeta) { + this.updateTx(txMeta) + await this.approveTransaction(txMeta.id) + } + getChainId () { const networkState = this.networkStore.getState() const getChainId = parseInt(networkState) -- cgit v1.2.3 From aeefcbd75bcf419833b9cc5b734e2d86f47ba6d1 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Wed, 12 Jul 2017 15:10:52 -0700 Subject: Fix test to match behavior --- app/scripts/lib/nodeify.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/scripts/lib/nodeify.js b/app/scripts/lib/nodeify.js index 4e111c8b2..299bfe624 100644 --- a/app/scripts/lib/nodeify.js +++ b/app/scripts/lib/nodeify.js @@ -1,4 +1,4 @@ -const promiseToCallback = require('promise-to-callback'); +const promiseToCallback = require('promise-to-callback') module.exports = function(fn, context) { return function(){ -- cgit v1.2.3 From 7eccf5905a830853bbb1932dde9a7f4536d43f55 Mon Sep 17 00:00:00 2001 From: frankiebee Date: Thu, 13 Jul 2017 15:25:43 -0400 Subject: make publishTransaction and signTransaction async methods --- app/scripts/controllers/transactions.js | 31 ++++++++++++------------------- app/scripts/lib/tx-utils.js | 9 +++++++-- 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'app') diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index a2842ae44..707543c87 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -3,7 +3,6 @@ const async = require('async') const extend = require('xtend') const ObservableStore = require('obs-store') const ethUtil = require('ethereumjs-util') -const denodeify = require('denodeify') const TxProviderUtil = require('../lib/tx-utils') const createId = require('../lib/random-id') const NonceTracker = require('../lib/nonce-tracker') @@ -195,7 +194,7 @@ module.exports = class TransactionController extends EventEmitter { txMeta.txParams.nonce = nonceLock.nextNonce this.updateTx(txMeta) // sign transaction - const rawTx = await denodeify(this.signTransaction.bind(this))(txId) + const rawTx = await this.signTransaction(txId) await this.publishTransaction(txId, rawTx) // must set transaction to submitted/failed before releasing lock nonceLock.releaseLock() @@ -231,32 +230,27 @@ module.exports = class TransactionController extends EventEmitter { } } - signTransaction (txId, cb) { + async signTransaction (txId) { const txMeta = this.getTx(txId) const txParams = txMeta.txParams const fromAddress = txParams.from // add network/chain id txParams.chainId = this.getChainId() const ethTx = this.txProviderUtils.buildEthTxFromParams(txParams) - this.signEthTx(ethTx, fromAddress).then(() => { + const rawTx = await this.signEthTx(ethTx, fromAddress).then(() => { this.setTxStatusSigned(txMeta.id) - cb(null, ethUtil.bufferToHex(ethTx.serialize())) - }).catch((err) => { - cb(err) + return ethUtil.bufferToHex(ethTx.serialize()) }) + return rawTx } - publishTransaction (txId, rawTx) { + async publishTransaction (txId, rawTx) { const txMeta = this.getTx(txId) txMeta.rawTx = rawTx this.updateTx(txMeta) - return new Promise((resolve, reject) => { - this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => { - if (err) reject(err) - this.setTxHash(txId, txHash) - this.setTxStatusSubmitted(txId) - resolve() - }) + await this.txProviderUtils.publishTransaction(rawTx).then((txHash) => { + this.setTxHash(txId, txHash) + this.setTxStatusSubmitted(txId) }) } @@ -435,8 +429,7 @@ module.exports = class TransactionController extends EventEmitter { const pending = this.getTxsByMetaData('status', 'submitted') // only try resubmitting if their are transactions to resubmit if (!pending.length) return - const resubmit = denodeify(this._resubmitTx.bind(this)) - pending.forEach((txMeta) => resubmit(txMeta).catch((err) => { + pending.forEach((txMeta) => this._resubmitTx(txMeta).catch((err) => { /* Dont marked as failed if the error is a "known" transaction warning "there is already a transaction with the same sender-nonce @@ -463,7 +456,7 @@ module.exports = class TransactionController extends EventEmitter { })) } - _resubmitTx (txMeta, cb) { + async _resubmitTx (txMeta, cb) { const address = txMeta.txParams.from const balance = this.ethStore.getState().accounts[address].balance if (!('retryCount' in txMeta)) txMeta.retryCount = 0 @@ -482,7 +475,7 @@ module.exports = class TransactionController extends EventEmitter { // Increment a try counter. txMeta.retryCount++ const rawTx = txMeta.rawTx - this.txProviderUtils.publishTransaction(rawTx, cb) + return await this.txProviderUtils.publishTransaction(rawTx, cb) } // checks the network for signed txs and diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js index aa0cb624f..8f6943937 100644 --- a/app/scripts/lib/tx-utils.js +++ b/app/scripts/lib/tx-utils.js @@ -106,8 +106,13 @@ module.exports = class txProviderUtils { return ethTx } - publishTransaction (rawTx, cb) { - this.query.sendRawTransaction(rawTx, cb) + publishTransaction (rawTx) { + return new Promise((resolve, reject) => { + this.query.sendRawTransaction(rawTx, (err, ress) => { + if (err) reject(err) + else resolve(ress) + }) + }) } validateTxParams (txParams, cb) { -- cgit v1.2.3