diff options
author | frankiebee <frankie.diamond@gmail.com> | 2017-07-12 03:18:44 +0800 |
---|---|---|
committer | frankiebee <frankie.diamond@gmail.com> | 2017-07-12 03:18:44 +0800 |
commit | a670e54973ed1bae20455507a4b3c44e231ba822 (patch) | |
tree | 00300ea3362b7b48be26d6547f89ed4c5bfac597 /app | |
parent | c121ac21ec3bed0381e36de7ead1b583a3da148c (diff) | |
parent | f5de16c91174fbbf208e5aef8f542d3bbbb3cb93 (diff) | |
download | tangerine-wallet-browser-a670e54973ed1bae20455507a4b3c44e231ba822.tar tangerine-wallet-browser-a670e54973ed1bae20455507a4b3c44e231ba822.tar.gz tangerine-wallet-browser-a670e54973ed1bae20455507a4b3c44e231ba822.tar.bz2 tangerine-wallet-browser-a670e54973ed1bae20455507a4b3c44e231ba822.tar.lz tangerine-wallet-browser-a670e54973ed1bae20455507a4b3c44e231ba822.tar.xz tangerine-wallet-browser-a670e54973ed1bae20455507a4b3c44e231ba822.tar.zst tangerine-wallet-browser-a670e54973ed1bae20455507a4b3c44e231ba822.zip |
Merge branch 'nonce-tracker' of https://github.com/MetaMask/metamask-plugin into nonce-tracker
Diffstat (limited to 'app')
-rw-r--r-- | app/manifest.json | 2 | ||||
-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 |
6 files changed, 121 insertions, 26 deletions
diff --git a/app/manifest.json b/app/manifest.json index 7ae20158c..aafc33e66 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "MetaMask", "short_name": "Metamask", - "version": "3.7.8", + "version": "3.8.3", "manifest_version": 2, "author": "https://metamask.io", "description": "Ethereum Browser Extension", 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 14b423d5d..fb0219fc3 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() @@ -36,7 +34,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 @@ -162,13 +163,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 () { @@ -429,10 +432,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) { @@ -443,15 +460,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'), ] |