aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md3
-rw-r--r--app/scripts/controllers/transactions/index.js9
-rw-r--r--app/scripts/controllers/transactions/nonce-tracker.js54
-rw-r--r--app/scripts/controllers/transactions/pending-tx-tracker.js4
-rw-r--r--app/scripts/inpage.js21
-rw-r--r--app/scripts/lib/auto-reload.js61
-rw-r--r--app/scripts/metamask-controller.js20
-rw-r--r--package-lock.json92
-rw-r--r--package.json1
-rw-r--r--test/e2e/func.js2
-rw-r--r--ui/app/components/pending-tx/confirm-send-ether.js2
-rw-r--r--ui/app/components/pending-tx/confirm-send-token.js2
12 files changed, 146 insertions, 125 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9fef15109..3f9413c8a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,8 @@
## Current Master
-- Fix bug where account reset did not work with custom RPC providers.
+- Fix bug where account reset did not work with custom RPC providers
+- Stop reloading browser page on Ethereum network change
## 4.7.4 Tue Jun 05 2018
diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js
index b53947e27..8e2288aed 100644
--- a/app/scripts/controllers/transactions/index.js
+++ b/app/scripts/controllers/transactions/index.js
@@ -165,7 +165,7 @@ class TransactionController extends EventEmitter {
// add default tx params
txMeta = await this.addTxGasDefaults(txMeta)
} catch (error) {
- console.log(error)
+ log.warn(error)
this.txStateManager.setTxStatusFailed(txMeta.id, error)
throw error
}
@@ -264,7 +264,12 @@ class TransactionController extends EventEmitter {
// must set transaction to submitted/failed before releasing lock
nonceLock.releaseLock()
} catch (err) {
- this.txStateManager.setTxStatusFailed(txId, err)
+ // this is try-catch wrapped so that we can guarantee that the nonceLock is released
+ try {
+ this.txStateManager.setTxStatusFailed(txId, err)
+ } catch (err) {
+ log.error(err)
+ }
// must set transaction to submitted/failed before releasing lock
if (nonceLock) nonceLock.releaseLock()
// continue with error chain
diff --git a/app/scripts/controllers/transactions/nonce-tracker.js b/app/scripts/controllers/transactions/nonce-tracker.js
index f8cdc5523..35ca08d6c 100644
--- a/app/scripts/controllers/transactions/nonce-tracker.js
+++ b/app/scripts/controllers/transactions/nonce-tracker.js
@@ -49,29 +49,35 @@ class NonceTracker {
await this._globalMutexFree()
// await lock free, then take lock
const releaseLock = await this._takeMutex(address)
- // evaluate multiple nextNonce strategies
- const nonceDetails = {}
- const networkNonceResult = await this._getNetworkNextNonce(address)
- const highestLocallyConfirmed = this._getHighestLocallyConfirmed(address)
- const nextNetworkNonce = networkNonceResult.nonce
- const highestSuggested = Math.max(nextNetworkNonce, highestLocallyConfirmed)
-
- const pendingTxs = this.getPendingTransactions(address)
- const localNonceResult = this._getHighestContinuousFrom(pendingTxs, highestSuggested) || 0
-
- nonceDetails.params = {
- highestLocallyConfirmed,
- highestSuggested,
- nextNetworkNonce,
+ try {
+ // evaluate multiple nextNonce strategies
+ const nonceDetails = {}
+ const networkNonceResult = await this._getNetworkNextNonce(address)
+ const highestLocallyConfirmed = this._getHighestLocallyConfirmed(address)
+ const nextNetworkNonce = networkNonceResult.nonce
+ const highestSuggested = Math.max(nextNetworkNonce, highestLocallyConfirmed)
+
+ const pendingTxs = this.getPendingTransactions(address)
+ const localNonceResult = this._getHighestContinuousFrom(pendingTxs, highestSuggested) || 0
+
+ nonceDetails.params = {
+ highestLocallyConfirmed,
+ highestSuggested,
+ nextNetworkNonce,
+ }
+ nonceDetails.local = localNonceResult
+ nonceDetails.network = networkNonceResult
+
+ const nextNonce = Math.max(networkNonceResult.nonce, localNonceResult.nonce)
+ assert(Number.isInteger(nextNonce), `nonce-tracker - nextNonce is not an integer - got: (${typeof nextNonce}) "${nextNonce}"`)
+
+ // return nonce and release cb
+ return { nextNonce, nonceDetails, releaseLock }
+ } catch (err) {
+ // release lock if we encounter an error
+ releaseLock()
+ throw err
}
- nonceDetails.local = localNonceResult
- nonceDetails.network = networkNonceResult
-
- const nextNonce = Math.max(networkNonceResult.nonce, localNonceResult.nonce)
- assert(Number.isInteger(nextNonce), `nonce-tracker - nextNonce is not an integer - got: (${typeof nextNonce}) "${nextNonce}"`)
-
- // return nonce and release cb
- return { nextNonce, nonceDetails, releaseLock }
}
async _getCurrentBlock () {
@@ -85,8 +91,8 @@ class NonceTracker {
async _globalMutexFree () {
const globalMutex = this._lookupMutex('global')
- const release = await globalMutex.acquire()
- release()
+ const releaseLock = await globalMutex.acquire()
+ releaseLock()
}
async _takeMutex (lockId) {
diff --git a/app/scripts/controllers/transactions/pending-tx-tracker.js b/app/scripts/controllers/transactions/pending-tx-tracker.js
index 6e2fcb40b..4e41cdaf8 100644
--- a/app/scripts/controllers/transactions/pending-tx-tracker.js
+++ b/app/scripts/controllers/transactions/pending-tx-tracker.js
@@ -196,14 +196,14 @@ class PendingTransactionTracker extends EventEmitter {
async _checkPendingTxs () {
const signedTxList = this.getPendingTransactions()
// in order to keep the nonceTracker accurate we block it while updating pending transactions
- const nonceGlobalLock = await this.nonceTracker.getGlobalLock()
+ const { releaseLock } = await this.nonceTracker.getGlobalLock()
try {
await Promise.all(signedTxList.map((txMeta) => this._checkPendingTx(txMeta)))
} catch (err) {
log.error('PendingTransactionWatcher - Error updating pending transactions')
log.error(err)
}
- nonceGlobalLock.releaseLock()
+ releaseLock()
}
/**
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index 6d16eebd4..070f5d247 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -3,7 +3,6 @@ cleanContextForImports()
require('web3/dist/web3.min.js')
const log = require('loglevel')
const LocalMessageDuplexStream = require('post-message-stream')
-const setupDappAutoReload = require('./lib/auto-reload.js')
const MetamaskInpageProvider = require('./lib/inpage-provider.js')
restoreContextAfterImports()
@@ -38,8 +37,24 @@ web3.setProvider = function () {
log.debug('MetaMask - overrode web3.setProvider')
}
log.debug('MetaMask - injected web3')
-// export global web3, with usage-detection
-setupDappAutoReload(web3, inpageProvider.publicConfigStore)
+
+// export global web3, with usage-detection and deprecation warning
+let hasBeenWarned = false
+global.web3 = new Proxy(web3, {
+ get: (_web3, key) => {
+ // show warning once on web3 access
+ if (!hasBeenWarned && key !== 'currentProvider') {
+ console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation')
+ hasBeenWarned = true
+ }
+ // return value normally
+ return _web3[key]
+ },
+ set: (_web3, key, value) => {
+ // set value normally
+ _web3[key] = value
+ },
+})
// set web3 defaultAccount
inpageProvider.publicConfigStore.subscribe(function (state) {
diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js
deleted file mode 100644
index cce31c3d2..000000000
--- a/app/scripts/lib/auto-reload.js
+++ /dev/null
@@ -1,61 +0,0 @@
-module.exports = setupDappAutoReload
-
-function setupDappAutoReload (web3, observable) {
- // export web3 as a global, checking for usage
- let hasBeenWarned = false
- let reloadInProgress = false
- let lastTimeUsed
- let lastSeenNetwork
-
- global.web3 = new Proxy(web3, {
- get: (_web3, key) => {
- // show warning once on web3 access
- if (!hasBeenWarned && key !== 'currentProvider') {
- console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation')
- hasBeenWarned = true
- }
- // get the time of use
- lastTimeUsed = Date.now()
- // return value normally
- return _web3[key]
- },
- set: (_web3, key, value) => {
- // set value normally
- _web3[key] = value
- },
- })
-
- observable.subscribe(function (state) {
- // if reload in progress, no need to check reload logic
- if (reloadInProgress) return
-
- const currentNetwork = state.networkVersion
-
- // set the initial network
- if (!lastSeenNetwork) {
- lastSeenNetwork = currentNetwork
- return
- }
-
- // skip reload logic if web3 not used
- if (!lastTimeUsed) return
-
- // if network did not change, exit
- if (currentNetwork === lastSeenNetwork) return
-
- // initiate page reload
- reloadInProgress = true
- const timeSinceUse = Date.now() - lastTimeUsed
- // if web3 was recently used then delay the reloading of the page
- if (timeSinceUse > 500) {
- triggerReset()
- } else {
- setTimeout(triggerReset, 500)
- }
- })
-}
-
-// reload the page
-function triggerReset () {
- global.location.reload()
-}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index abe7ff8a2..6c380fd71 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -443,28 +443,24 @@ module.exports = class MetamaskController extends EventEmitter {
* @returns {Object} vault
*/
async createNewVaultAndKeychain (password) {
- const release = await this.createVaultMutex.acquire()
- let vault
-
+ const releaseLock = await this.createVaultMutex.acquire()
try {
+ let vault
const accounts = await this.keyringController.getAccounts()
-
if (accounts.length > 0) {
vault = await this.keyringController.fullUpdate()
-
} else {
vault = await this.keyringController.createNewVaultAndKeychain(password)
const accounts = await this.keyringController.getAccounts()
this.preferencesController.setAddresses(accounts)
this.selectFirstIdentity()
}
- release()
+ releaseLock()
+ return vault
} catch (err) {
- release()
+ releaseLock()
throw err
}
-
- return vault
}
/**
@@ -473,7 +469,7 @@ module.exports = class MetamaskController extends EventEmitter {
* @param {} seed
*/
async createNewVaultAndRestore (password, seed) {
- const release = await this.createVaultMutex.acquire()
+ const releaseLock = await this.createVaultMutex.acquire()
try {
// clear known identities
this.preferencesController.setAddresses([])
@@ -483,10 +479,10 @@ module.exports = class MetamaskController extends EventEmitter {
const accounts = await this.keyringController.getAccounts()
this.preferencesController.setAddresses(accounts)
this.selectFirstIdentity()
- release()
+ releaseLock()
return vault
} catch (err) {
- release()
+ releaseLock()
throw err
}
}
diff --git a/package-lock.json b/package-lock.json
index 0fdbc02d6..4d2bee8bb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8267,7 +8267,7 @@
"dependencies": {
"ethereumjs-abi": {
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#4ea2fdfed09e8f99117d9362d17c6b01b64a2bcf",
- "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
+ "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#4ea2fdfed09e8f99117d9362d17c6b01b64a2bcf",
"requires": {
"bn.js": "^4.10.0",
"ethereumjs-util": "^5.0.0"
@@ -8489,8 +8489,8 @@
}
},
"eth-trezor-keyring": {
- "version": "github:brunobar79/eth-trezor-keyring#c138d26c36a01f15be5e12a81e4fcbf56b044fa4",
- "from": "github:brunobar79/eth-trezor-keyring#c138d26c36a01f15be5e12a81e4fcbf56b044fa4",
+ "version": "github:brunobar79/eth-trezor-keyring#34fec28417c9203dc6ad7d7c53fa46a7f422aa4e",
+ "from": "github:brunobar79/eth-trezor-keyring#34fec28417c9203dc6ad7d7c53fa46a7f422aa4e",
"requires": {
"eth-sig-util": "^1.4.2",
"ethereumjs-tx": "^1.3.4",
@@ -8531,6 +8531,16 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
"integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg=="
+ },
+ "hdkey": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.8.0.tgz",
+ "integrity": "sha512-oYsdlK22eobT68N5faWI3776f6tOLyqxLLYwxMx+TP0rkWzuCs0oiOm2VbLWcxdpHFP4LtiRR8udaIX8VkEaZQ==",
+ "requires": {
+ "coinstring": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
}
}
},
@@ -8554,6 +8564,20 @@
"web3-provider-engine": "^13.3.2"
},
"dependencies": {
+ "ethereumjs-util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
+ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "^0.1.3",
+ "keccak": "^1.0.2",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
+ },
"ethereumjs-vm": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz",
@@ -8698,6 +8722,22 @@
"ethereumjs-tx": "^1.2.2",
"ethereumjs-util": "^5.0.0",
"merkle-patricia-tree": "^2.1.2"
+ },
+ "dependencies": {
+ "ethereumjs-util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
+ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "^0.1.3",
+ "keccak": "^1.0.2",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
+ }
}
},
"ethereumjs-tx": {
@@ -8713,6 +8753,20 @@
"version": "0.0.18",
"resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz",
"integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8="
+ },
+ "ethereumjs-util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
+ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "^0.1.3",
+ "keccak": "^1.0.2",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
}
}
},
@@ -8784,15 +8838,6 @@
"rlp": "^2.0.0",
"secp256k1": "^3.0.1"
}
- },
- "hdkey": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz",
- "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=",
- "requires": {
- "coinstring": "^2.0.0",
- "secp256k1": "^3.0.1"
- }
}
}
},
@@ -13623,12 +13668,11 @@
}
},
"hdkey": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.8.0.tgz",
- "integrity": "sha512-oYsdlK22eobT68N5faWI3776f6tOLyqxLLYwxMx+TP0rkWzuCs0oiOm2VbLWcxdpHFP4LtiRR8udaIX8VkEaZQ==",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz",
+ "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=",
"requires": {
"coinstring": "^2.0.0",
- "safe-buffer": "^5.1.1",
"secp256k1": "^3.0.1"
}
},
@@ -18288,6 +18332,20 @@
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ },
+ "ethereumjs-util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
+ "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
+ "requires": {
+ "bn.js": "^4.11.0",
+ "create-hash": "^1.1.2",
+ "ethjs-util": "^0.1.3",
+ "keccak": "^1.0.2",
+ "rlp": "^2.0.0",
+ "safe-buffer": "^5.1.1",
+ "secp256k1": "^3.0.1"
+ }
}
}
},
@@ -31338,7 +31396,7 @@
"dependencies": {
"bignumber.js": {
"version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934",
- "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git"
+ "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934"
}
}
},
diff --git a/package.json b/package.json
index 198f45cf1..ce28d484a 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"dist": "gulp dist",
"doc": "jsdoc -c development/tools/.jsdoc.json",
"test": "npm run test:unit && npm run test:integration && npm run lint",
+ "watch:test:unit": "nodemon --exec \"npm run test:unit\" ./test ./app ./ui",
"test:unit": "cross-env METAMASK_ENV=test mocha --exit --require test/setup.js --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\" && dot-only-hunter",
"test:single": "cross-env METAMASK_ENV=test mocha --require test/helper.js",
"test:integration": "npm run test:integration:build && npm run test:flat && npm run test:mascara",
diff --git a/test/e2e/func.js b/test/e2e/func.js
index 9f06e7f37..7b1730959 100644
--- a/test/e2e/func.js
+++ b/test/e2e/func.js
@@ -21,7 +21,7 @@ function delay (time) {
}
function buildChromeWebDriver (extPath) {
- const tmpProfile = path.join(os.tmpdir(), fs.mkdtempSync('mm-chrome-profile'));
+ const tmpProfile = fs.mkdtempSync(path.join(os.tmpdir(), 'mm-chrome-profile'))
return new webdriver.Builder()
.withCapabilities({
chromeOptions: {
diff --git a/ui/app/components/pending-tx/confirm-send-ether.js b/ui/app/components/pending-tx/confirm-send-ether.js
index 97d0318ea..bbf5683f0 100644
--- a/ui/app/components/pending-tx/confirm-send-ether.js
+++ b/ui/app/components/pending-tx/confirm-send-ether.js
@@ -647,7 +647,7 @@ ConfirmSendEther.prototype.gatherTxMeta = function () {
const state = this.state
const txData = clone(state.txData) || clone(props.txData)
- const { gasPrice: sendGasPrice, gas: sendGasLimit } = props.send
+ const { gasPrice: sendGasPrice, gasLimit: sendGasLimit } = props.send
const {
lastGasPrice,
txParams: {
diff --git a/ui/app/components/pending-tx/confirm-send-token.js b/ui/app/components/pending-tx/confirm-send-token.js
index 1802d3143..ee066b8f4 100644
--- a/ui/app/components/pending-tx/confirm-send-token.js
+++ b/ui/app/components/pending-tx/confirm-send-token.js
@@ -651,7 +651,7 @@ ConfirmSendToken.prototype.gatherTxMeta = function () {
const state = this.state
const txData = clone(state.txData) || clone(props.txData)
- const { gasPrice: sendGasPrice, gas: sendGasLimit } = props.send
+ const { gasPrice: sendGasPrice, gasLimit: sendGasLimit } = props.send
const {
lastGasPrice,
txParams: {