hww: fix some threading issues in wizard

fixes #3377
related: #6064  (passphrase dialog not rendered correctly)
This commit is contained in:
SomberNight 2020-04-01 21:05:19 +02:00
parent 81fc3fcce2
commit 371f55a0f9
No known key found for this signature in database
GPG key ID: B33B5F232C6271E9
8 changed files with 40 additions and 5 deletions

View file

@ -158,6 +158,13 @@ class BaseWizard(Logger):
exc = e exc = e
self.waiting_dialog(do_upgrade, _('Upgrading wallet format...'), on_finished=on_finished) self.waiting_dialog(do_upgrade, _('Upgrading wallet format...'), on_finished=on_finished)
def run_task_without_blocking_gui(self, task, *, msg: str = None) -> Any:
"""Perform a task in a thread without blocking the GUI.
Returns the result of 'task', or raises the same exception.
This method blocks until 'task' is finished.
"""
raise NotImplementedError()
def load_2fa(self): def load_2fa(self):
self.data['wallet_type'] = '2fa' self.data['wallet_type'] = '2fa'
self.data['use_trustedcoin'] = True self.data['use_trustedcoin'] = True
@ -421,6 +428,7 @@ class BaseWizard(Logger):
def on_hw_derivation(self, name, device_info: 'DeviceInfo', derivation, xtype): def on_hw_derivation(self, name, device_info: 'DeviceInfo', derivation, xtype):
from .keystore import hardware_keystore from .keystore import hardware_keystore
devmgr = self.plugins.device_manager devmgr = self.plugins.device_manager
assert isinstance(self.plugin, HW_PluginBase)
try: try:
xpub = self.plugin.get_xpub(device_info.device.id_, derivation, xtype, self) xpub = self.plugin.get_xpub(device_info.device.id_, derivation, xtype, self)
client = devmgr.client_by_id(device_info.device.id_) client = devmgr.client_by_id(device_info.device.id_)

View file

@ -529,6 +529,26 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
if on_finished: if on_finished:
on_finished() on_finished()
def run_task_without_blocking_gui(self, task, *, msg=None):
assert self.gui_thread == threading.current_thread(), 'must be called from GUI thread'
if msg is None:
msg = _("Please wait...")
exc = None # type: Optional[Exception]
res = None
def task_wrapper():
nonlocal exc
nonlocal res
try:
task()
except Exception as e:
exc = e
self.waiting_dialog(task_wrapper, msg=msg)
if exc is None:
return res
else:
raise exc
@wizard_dialog @wizard_dialog
def choice_dialog(self, title, message, choices, run_next): def choice_dialog(self, title, message, choices, run_next):
c_values = [x[0] for x in choices] c_values = [x[0] for x in choices]

View file

@ -707,7 +707,8 @@ class DigitalBitboxPlugin(HW_PluginBase):
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard) client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
if purpose == HWD_SETUP_NEW_WALLET: if purpose == HWD_SETUP_NEW_WALLET:
client.setupRunning = True client.setupRunning = True
client.get_xpub("m/44'/0'", 'standard') wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub("m/44'/0'", 'standard'))
def is_mobile_paired(self): def is_mobile_paired(self):

View file

@ -78,6 +78,8 @@ class HW_PluginBase(BasePlugin):
"""Called when creating a new wallet or when using the device to decrypt """Called when creating a new wallet or when using the device to decrypt
an existing wallet. Select the device to use. If the device is an existing wallet. Select the device to use. If the device is
uninitialized, go through the initialization process. uninitialized, go through the initialization process.
Runs in GUI thread.
""" """
raise NotImplementedError() raise NotImplementedError()

View file

@ -279,7 +279,8 @@ class KeepKeyPlugin(HW_PluginBase):
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard) client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
if not device_info.initialized: if not device_info.initialized:
self.initialize_device(device_id, wizard, client.handler) self.initialize_device(device_id, wizard, client.handler)
client.get_xpub('m', 'standard') wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub("m", 'standard'))
client.used() client.used()
def get_xpub(self, device_id, derivation, xtype, wizard): def get_xpub(self, device_id, derivation, xtype, wizard):

View file

@ -591,7 +591,8 @@ class LedgerPlugin(HW_PluginBase):
def setup_device(self, device_info, wizard, purpose): def setup_device(self, device_info, wizard, purpose):
device_id = device_info.device.id_ device_id = device_info.device.id_
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard) client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
client.get_xpub("m/44'/0'", 'standard') # TODO replace by direct derivation once Nano S > 1.1 wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub("m/44'/0'", 'standard')) # TODO replace by direct derivation once Nano S > 1.1
def get_xpub(self, device_id, derivation, xtype, wizard): def get_xpub(self, device_id, derivation, xtype, wizard):
if xtype not in self.SUPPORTED_XTYPES: if xtype not in self.SUPPORTED_XTYPES:

View file

@ -253,7 +253,8 @@ class SafeTPlugin(HW_PluginBase):
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard) client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
if not device_info.initialized: if not device_info.initialized:
self.initialize_device(device_id, wizard, client.handler) self.initialize_device(device_id, wizard, client.handler)
client.get_xpub('m', 'standard') wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub("m", 'standard'))
client.used() client.used()
def get_xpub(self, device_id, derivation, xtype, wizard): def get_xpub(self, device_id, derivation, xtype, wizard):

View file

@ -280,7 +280,8 @@ class TrezorPlugin(HW_PluginBase):
if not device_info.initialized: if not device_info.initialized:
self.initialize_device(device_id, wizard, client.handler) self.initialize_device(device_id, wizard, client.handler)
is_creating_wallet = purpose == HWD_SETUP_NEW_WALLET is_creating_wallet = purpose == HWD_SETUP_NEW_WALLET
client.get_xpub('m', 'standard', creating=is_creating_wallet) wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub('m', 'standard', creating=is_creating_wallet))
client.used() client.used()
def get_xpub(self, device_id, derivation, xtype, wizard): def get_xpub(self, device_id, derivation, xtype, wizard):