diff options
author | kumavis <kumavis@users.noreply.github.com> | 2017-07-08 05:21:43 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-08 05:21:43 +0800 |
commit | d228f46254783885e9762a2f96ecb9c3077c5fb3 (patch) | |
tree | b0e0fde9f209c3728f7a1e36d3c4417ea7a3852d /app/scripts | |
parent | 51ff6d74e884b599f78b5454b33f2bc1a046f0b2 (diff) | |
parent | 678cfd21755bab430d28a8f0d0fb44a81ecefade (diff) | |
download | tangerine-wallet-browser-d228f46254783885e9762a2f96ecb9c3077c5fb3.tar tangerine-wallet-browser-d228f46254783885e9762a2f96ecb9c3077c5fb3.tar.gz tangerine-wallet-browser-d228f46254783885e9762a2f96ecb9c3077c5fb3.tar.bz2 tangerine-wallet-browser-d228f46254783885e9762a2f96ecb9c3077c5fb3.tar.lz tangerine-wallet-browser-d228f46254783885e9762a2f96ecb9c3077c5fb3.tar.xz tangerine-wallet-browser-d228f46254783885e9762a2f96ecb9c3077c5fb3.tar.zst tangerine-wallet-browser-d228f46254783885e9762a2f96ecb9c3077c5fb3.zip |
Merge branch 'master' into nonce-tracker
Diffstat (limited to 'app/scripts')
-rw-r--r-- | app/scripts/controllers/preferences.js | 29 | ||||
-rw-r--r-- | app/scripts/controllers/transactions.js | 65 | ||||
-rw-r--r-- | app/scripts/metamask-controller.js | 12 | ||||
-rw-r--r-- | app/scripts/migrations/015.js | 38 | ||||
-rw-r--r-- | app/scripts/migrations/index.js | 1 |
5 files changed, 120 insertions, 25 deletions
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index aa8e05fcc..e45224593 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -8,13 +8,11 @@ class PreferencesController { const initState = extend({ frequentRpcList: [], currentAccountTab: 'history', + tokens: [], }, opts.initState) this.store = new ObservableStore(initState) } - - // - // PUBLIC METHODS - // +// PUBLIC METHODS setSelectedAddress (_address) { return new Promise((resolve, reject) => { @@ -28,6 +26,29 @@ class PreferencesController { return this.store.getState().selectedAddress } + addToken (rawAddress, symbol, decimals) { + const address = normalizeAddress(rawAddress) + const newEntry = { address, symbol, decimals } + + const tokens = this.store.getState().tokens + const previousIndex = tokens.find((token, index) => { + return token.address === address + }) + + if (previousIndex) { + tokens[previousIndex] = newEntry + } else { + tokens.push(newEntry) + } + + this.store.updateState({ tokens }) + return Promise.resolve() + } + + getTokens () { + return this.store.getState().tokens + } + updateFrequentRpcList (_url) { return this.addToFrequentRpcList(_url) .then((rpcList) => { diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 2b40f9456..6bf980a22 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -8,8 +8,6 @@ const TxProviderUtil = require('../lib/tx-utils') const createId = require('../lib/random-id') const NonceTracker = require('../lib/nonce-tracker') -const RETRY_LIMIT = 200 - module.exports = class TransactionController extends EventEmitter { constructor (opts) { super() @@ -37,7 +35,10 @@ module.exports = class TransactionController extends EventEmitter { this.query = opts.ethQuery this.txProviderUtils = new TxProviderUtil(this.query) this.blockTracker.on('rawBlock', this.checkForTxInBlock.bind(this)) - this.blockTracker.on('latest', this.resubmitPendingTxs.bind(this)) + // this is a little messy but until ethstore has been either + // removed or redone this is to guard against the race condition + // where ethStore hasent been populated by the results yet + this.blockTracker.once('latest', () => this.blockTracker.on('latest', this.resubmitPendingTxs.bind(this))) this.blockTracker.on('sync', this.queryPendingTxs.bind(this)) this.signEthTx = opts.signTransaction this.ethStore = opts.ethStore @@ -163,13 +164,15 @@ module.exports = class TransactionController extends EventEmitter { const txParams = txMeta.txParams // ensure value txParams.value = txParams.value || '0x0' - this.query.gasPrice((err, gasPrice) => { - if (err) return cb(err) - // set gasPrice - txParams.gasPrice = gasPrice - // set gasLimit - this.txProviderUtils.analyzeGasUsage(txMeta, cb) - }) + if (!txParams.gasPrice) { + this.query.gasPrice((err, gasPrice) => { + if (err) return cb(err) + // set gasPrice + txParams.gasPrice = gasPrice + }) + } + // set gasLimit + this.txProviderUtils.analyzeGasUsage(txMeta, cb) } getUnapprovedTxList () { @@ -430,10 +433,24 @@ module.exports = class TransactionController extends EventEmitter { // only try resubmitting if their are transactions to resubmit if (!pending.length) return const resubmit = denodeify(this._resubmitTx.bind(this)) - Promise.all(pending.map(txMeta => resubmit(txMeta))) + pending.forEach((txMeta) => resubmit(txMeta) .catch((reason) => { - log.info('Problem resubmitting tx', reason) - }) + /* + Dont marked as failed if the error is a "known" transaction warning + "there is already a transaction with the same sender-nonce + but higher/same gas price" + */ + const errorMessage = reason.message.toLowerCase() + const isKnownTx = ( + // geth + errorMessage === 'replacement transaction underpriced' + || errorMessage.startsWith('known transaction') + // parity + || errorMessage === 'gas price too low to replace' + ) + // ignore resubmit warnings, return early + if (!isKnownTx) this.setTxStatusFailed(txMeta.id, reason.message) + })) } _resubmitTx (txMeta, cb) { @@ -444,15 +461,25 @@ module.exports = class TransactionController extends EventEmitter { const gtBalance = Number.parseInt(txMeta.txParams.value) > Number.parseInt(balance) if (!('retryCount' in txMeta)) txMeta.retryCount = 0 - // if the value of the transaction is greater then the balance - // or the nonce of the transaction is lower then the accounts nonce - // dont resubmit the tx - if (gtBalance || txNonce < nonce) return cb() + // if the value of the transaction is greater then the balance, fail. + if (gtBalance) { + const message = 'Insufficient balance.' + this.setTxStatusFailed(txMeta.id, message) + cb() + return log.error(message) + } + + // if the nonce of the transaction is lower then the accounts nonce, fail. + if (txNonce < nonce) { + const message = 'Invalid nonce.' + this.setTxStatusFailed(txMeta.id, message) + cb() + return log.error(message) + } + // Only auto-submit already-signed txs: if (!('rawTx' in txMeta)) return cb() - if (txMeta.retryCount > RETRY_LIMIT) return - // Increment a try counter. txMeta.retryCount++ const rawTx = txMeta.rawTx diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index be64a45c7..573594b39 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -184,7 +184,9 @@ module.exports = class MetamaskController extends EventEmitter { eth_syncing: false, web3_clientVersion: `MetaMask/v${version}`, }, + // rpc data source rpcUrl: this.networkController.getCurrentRpcAddress(), + originHttpHeaderKey: 'X-Metamask-Origin', // account mgmt getAccounts: (cb) => { const isUnlocked = this.keyringController.memStore.getState().isUnlocked @@ -293,6 +295,7 @@ module.exports = class MetamaskController extends EventEmitter { // 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), @@ -355,8 +358,13 @@ module.exports = class MetamaskController extends EventEmitter { } setupProviderConnection (outStream, originDomain) { - streamIntoProvider(outStream, this.provider, logger) - function logger (err, request, response) { + streamIntoProvider(outStream, this.provider, onRequest, onResponse) + // append dapp origin domain to request + function onRequest (request) { + request.origin = originDomain + } + // log rpc activity + function onResponse (err, request, response) { if (err) return console.error(err) if (response.error) { console.error('Error in RPC response:\n', response.error) diff --git a/app/scripts/migrations/015.js b/app/scripts/migrations/015.js new file mode 100644 index 000000000..4b839580b --- /dev/null +++ b/app/scripts/migrations/015.js @@ -0,0 +1,38 @@ +const version = 15 + +/* + +This migration sets transactions with the 'Gave up submitting tx.' err message +to a 'failed' stated + +*/ + +const clone = require('clone') + +module.exports = { + version, + + migrate: function (originalVersionedData) { + const versionedData = clone(originalVersionedData) + versionedData.meta.version = version + try { + const state = versionedData.data + const newState = transformState(state) + versionedData.data = newState + } catch (err) { + console.warn(`MetaMask Migration #${version}` + err.stack) + } + return Promise.resolve(versionedData) + }, +} + +function transformState (state) { + const newState = state + const transactions = newState.TransactionController.transactions + newState.TransactionController.transactions = transactions.map((txMeta) => { + if (!txMeta.err) return txMeta + else if (txMeta.err.message === 'Gave up submitting tx.') txMeta.status = 'failed' + return txMeta + }) + return newState +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index fb1ad7863..651ee6a9c 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -25,4 +25,5 @@ module.exports = [ require('./012'), require('./013'), require('./014'), + require('./015'), ] |