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
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):
self.data['wallet_type'] = '2fa'
self.data['use_trustedcoin'] = True
@ -421,6 +428,7 @@ class BaseWizard(Logger):
def on_hw_derivation(self, name, device_info: 'DeviceInfo', derivation, xtype):
from .keystore import hardware_keystore
devmgr = self.plugins.device_manager
assert isinstance(self.plugin, HW_PluginBase)
try:
xpub = self.plugin.get_xpub(device_info.device.id_, derivation, xtype, self)
client = devmgr.client_by_id(device_info.device.id_)

View file

@ -529,6 +529,26 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
if 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
def choice_dialog(self, title, message, choices, run_next):
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)
if purpose == HWD_SETUP_NEW_WALLET:
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):

View file

@ -78,6 +78,8 @@ class HW_PluginBase(BasePlugin):
"""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
uninitialized, go through the initialization process.
Runs in GUI thread.
"""
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)
if not device_info.initialized:
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()
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):
device_id = device_info.device.id_
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):
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)
if not device_info.initialized:
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()
def get_xpub(self, device_id, derivation, xtype, wizard):

View file

@ -280,7 +280,8 @@ class TrezorPlugin(HW_PluginBase):
if not device_info.initialized:
self.initialize_device(device_id, wizard, client.handler)
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()
def get_xpub(self, device_id, derivation, xtype, wizard):