From c0aa7ce8574c6a88c348d86c71678fcd24ac168d Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 20 Nov 2017 13:27:29 -0800 Subject: Add reproduction and mutex code --- app/scripts/metamask-controller.js | 39 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 968589f6e..69cf65554 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -31,6 +31,7 @@ const ConfigManager = require('./lib/config-manager') const nodeify = require('./lib/nodeify') const accountImporter = require('./account-import-strategies') const getBuyEthUrl = require('./lib/buy-eth-url') +const Mutex = require('await-semaphore').Mutex const version = require('../manifest.json').version module.exports = class MetamaskController extends EventEmitter { @@ -38,6 +39,10 @@ module.exports = class MetamaskController extends EventEmitter { constructor (opts) { super() + this.createVaultRequestStart = [] + this.createVaultRequestEnd = [] + this.createVaultMutex = new Mutex() + this.sendUpdate = debounce(this.privateSendUpdate.bind(this), 200) this.opts = opts @@ -467,15 +472,45 @@ module.exports = class MetamaskController extends EventEmitter { // Vault Management // - async createNewVaultAndKeychain (password, cb) { + async createNewVaultAndKeychain (password) { + const release = await this.createVaultMutex.acquire() + this.createVaultRequestStart.push(performance.now()) + this.createVaultRequestEnd.push(0); + const idx = this.createVaultRequestStart.length - 1; + if(idx === 1) { + await this.sleep(8000) + } const vault = await this.keyringController.createNewVaultAndKeychain(password) + if(idx === 0) { + //await this.sleep(3000) + } + console.log({ + "idx": idx, + "when": "before", + "obj": vault + }); this.selectFirstIdentity(vault) + console.log({ + "idx": idx, + "when": "after", + "obj": vault + }); + this.createVaultRequestEnd[idx] = performance.now() + console.log(this.createVaultRequestStart) + console.log(this.createVaultRequestEnd) + release() return vault } - async createNewVaultAndRestore (password, seed, cb) { + sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + async createNewVaultAndRestore (password, seed) { + const release = await this.createVaultMutex.acquire() const vault = await this.keyringController.createNewVaultAndRestore(password, seed) this.selectFirstIdentity(vault) + release() return vault } -- cgit From 65cb9704872fe7730285f4185ea6bc1a2d28c149 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 20 Nov 2017 13:47:35 -0800 Subject: Prevent creation of multiple vaults Fixes #2577 by ensuring only one seed phrase can be set for a new vault. Also cleans up logs and reproduction logic. --- app/scripts/metamask-controller.js | 51 +++++++++++++++----------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 69cf65554..a4c77e468 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -39,9 +39,6 @@ module.exports = class MetamaskController extends EventEmitter { constructor (opts) { super() - this.createVaultRequestStart = [] - this.createVaultRequestEnd = [] - this.createVaultMutex = new Mutex() this.sendUpdate = debounce(this.privateSendUpdate.bind(this), 200) @@ -54,6 +51,9 @@ module.exports = class MetamaskController extends EventEmitter { // observable state store this.store = new ObservableStore(initState) + // lock to ensure only one vault created at once + this.createVaultMutex = new Mutex() + // network store this.networkController = new NetworkController(initState.NetworkController) @@ -474,36 +474,25 @@ module.exports = class MetamaskController extends EventEmitter { async createNewVaultAndKeychain (password) { const release = await this.createVaultMutex.acquire() - this.createVaultRequestStart.push(performance.now()) - this.createVaultRequestEnd.push(0); - const idx = this.createVaultRequestStart.length - 1; - if(idx === 1) { - await this.sleep(8000) - } - const vault = await this.keyringController.createNewVaultAndKeychain(password) - if(idx === 0) { - //await this.sleep(3000) + let vault + + try { + const accounts = await this.keyringController.getAccounts() + + if (accounts.length > 0) { + vault = await this.keyringController.fullUpdate() + + } else { + let vault = await this.keyringController.createNewVaultAndKeychain(password) + this.selectFirstIdentity(vault) + } + release() + } catch (err) { + release() + throw err } - console.log({ - "idx": idx, - "when": "before", - "obj": vault - }); - this.selectFirstIdentity(vault) - console.log({ - "idx": idx, - "when": "after", - "obj": vault - }); - this.createVaultRequestEnd[idx] = performance.now() - console.log(this.createVaultRequestStart) - console.log(this.createVaultRequestEnd) - release() - return vault - } - sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); + return vault } async createNewVaultAndRestore (password, seed) { -- cgit From 597af980dd68c0252625e7cc5b6a6a223406fbc2 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 20 Nov 2017 14:03:47 -0800 Subject: Prevent multiple submissions of first time form --- ui/app/first-time/init-menu.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js index cc7c51bd3..b4587f1ee 100644 --- a/ui/app/first-time/init-menu.js +++ b/ui/app/first-time/init-menu.js @@ -8,6 +8,8 @@ const actions = require('../actions') const Tooltip = require('../components/tooltip') const getCaretCoordinates = require('textarea-caret') +let isSubmitting = false + module.exports = connect(mapStateToProps)(InitializeMenuScreen) inherits(InitializeMenuScreen, Component) @@ -164,7 +166,10 @@ InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () { return } - this.props.dispatch(actions.createNewVaultAndKeychain(password)) + if (!isSubmitting) { + isSubmitting = true + this.props.dispatch(actions.createNewVaultAndKeychain(password)) + } } InitializeMenuScreen.prototype.inputChanged = function (event) { -- cgit