Browse Source

wizard hww: scan devices fewer times and move away from GUI thread

hard-fail-on-bad-server-string
SomberNight 5 years ago
parent
commit
4b1d835304
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 7
      electrum/base_wizard.py
  2. 17
      electrum/plugin.py
  3. 1
      electrum/plugins/coldcard/coldcard.py
  4. 1
      electrum/plugins/digitalbitbox/digitalbitbox.py
  5. 6
      electrum/plugins/hw_wallet/plugin.py
  6. 1
      electrum/plugins/keepkey/keepkey.py
  7. 1
      electrum/plugins/ledger/ledger.py
  8. 1
      electrum/plugins/safe_t/safe_t.py
  9. 1
      electrum/plugins/trezor/trezor.py

7
electrum/base_wizard.py

@ -348,7 +348,7 @@ class BaseWizard(Logger):
assert isinstance(self.plugin, HW_PluginBase)
devmgr = self.plugins.device_manager
try:
self.plugin.setup_device(device_info, self, purpose)
client = self.plugin.setup_device(device_info, self, purpose)
except OSError as e:
self.show_error(_('We encountered an error while connecting to your device:')
+ '\n' + str(e) + '\n'
@ -376,19 +376,18 @@ class BaseWizard(Logger):
self.show_error(str(e))
self.choose_hw_device(purpose, storage=storage)
return
if purpose == HWD_SETUP_NEW_WALLET:
def f(derivation, script_type):
derivation = normalize_bip32_derivation(derivation)
self.run('on_hw_derivation', name, device_info, derivation, script_type)
self.derivation_and_script_type_dialog(f)
elif purpose == HWD_SETUP_DECRYPT_WALLET:
client = devmgr.client_by_id(device_info.device.id_)
password = client.get_password_for_storage_encryption()
try:
storage.decrypt(password)
except InvalidPassword:
# try to clear session so that user can type another passphrase
client = devmgr.client_by_id(device_info.device.id_)
if hasattr(client, 'clear_session'): # FIXME not all hw wallet plugins have this
client.clear_session()
raise
@ -435,7 +434,7 @@ class BaseWizard(Logger):
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_)
client = devmgr.client_by_id(device_info.device.id_, scan_now=False)
if not client: raise Exception("failed to find client for device id")
root_fingerprint = client.request_root_fingerprint_from_device()
label = client.label() # use this as device_info.label might be outdated!

17
electrum/plugin.py

@ -401,7 +401,7 @@ class DeviceMgr(ThreadJob):
def create_client(self, device: 'Device', handler: Optional['HardwareHandlerBase'],
plugin: 'HW_PluginBase') -> Optional['HardwareClientBase']:
# Get from cache first
client = self.client_lookup(device.id_)
client = self._client_by_id(device.id_)
if client:
return client
client = plugin.create_client(device, handler)
@ -437,7 +437,7 @@ class DeviceMgr(ThreadJob):
self._close_client(id_)
def _close_client(self, id_):
client = self.client_lookup(id_)
client = self._client_by_id(id_)
self.clients.pop(client, None)
if client:
client.close()
@ -446,19 +446,20 @@ class DeviceMgr(ThreadJob):
with self.lock:
self.xpub_ids[xpub] = id_
def client_lookup(self, id_) -> Optional['HardwareClientBase']:
def _client_by_id(self, id_) -> Optional['HardwareClientBase']:
with self.lock:
for client, (path, client_id) in self.clients.items():
if client_id == id_:
return client
return None
def client_by_id(self, id_) -> Optional['HardwareClientBase']:
def client_by_id(self, id_, *, scan_now: bool = True) -> Optional['HardwareClientBase']:
'''Returns a client for the device ID if one is registered. If
a device is wiped or in bootloader mode pairing is impossible;
in such cases we communicate by device ID and not wallet.'''
self.scan_devices()
return self.client_lookup(id_)
if scan_now:
self.scan_devices()
return self._client_by_id(id_)
@with_scan_lock
def client_for_keystore(self, plugin: 'HW_PluginBase', handler: Optional['HardwareHandlerBase'],
@ -495,7 +496,7 @@ class DeviceMgr(ThreadJob):
def client_by_xpub(self, plugin: 'HW_PluginBase', xpub, handler: 'HardwareHandlerBase',
devices: Sequence['Device']) -> Optional['HardwareClientBase']:
_id = self.xpub_id(xpub)
client = self.client_lookup(_id)
client = self._client_by_id(_id)
if client:
# An unpaired client might have another wallet's handler
# from a prior scan. Replace to fix dialog parenting.
@ -511,7 +512,7 @@ class DeviceMgr(ThreadJob):
# The wallet has not been previously paired, so let the user
# choose an unpaired device and compare its first address.
xtype = bip32.xpub_type(xpub)
client = self.client_lookup(info.device.id_)
client = self._client_by_id(info.device.id_)
if client and client.is_pairable():
# See comment above for same code
client.handler = handler

1
electrum/plugins/coldcard/coldcard.py

@ -524,6 +524,7 @@ class ColdcardPlugin(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)
return client
def get_xpub(self, device_id, derivation, xtype, wizard):
# this seems to be part of the pairing process only, not during normal ops?

1
electrum/plugins/digitalbitbox/digitalbitbox.py

@ -705,6 +705,7 @@ class DigitalBitboxPlugin(HW_PluginBase):
client.setupRunning = True
wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub("m/44'/0'", 'standard'))
return client
def is_mobile_paired(self):

6
electrum/plugins/hw_wallet/plugin.py

@ -25,6 +25,7 @@
# SOFTWARE.
from typing import TYPE_CHECKING, Dict, List, Union, Tuple, Sequence, Optional, Type
from functools import partial
from electrum.plugin import BasePlugin, hook, Device, DeviceMgr, DeviceInfo
from electrum.i18n import _
@ -67,14 +68,15 @@ class HW_PluginBase(BasePlugin):
def scan_and_create_client_for_device(self, *, device_id: str, wizard: 'BaseWizard') -> 'HardwareClientBase':
devmgr = self.device_manager()
client = devmgr.client_by_id(device_id)
client = wizard.run_task_without_blocking_gui(
task=partial(devmgr.client_by_id, device_id))
if client is None:
raise UserFacingException(_('Failed to create a client for this device.') + '\n' +
_('Make sure it is in the correct state.'))
client.handler = self.create_handler(wizard)
return client
def setup_device(self, device_info: DeviceInfo, wizard: 'BaseWizard', purpose):
def setup_device(self, device_info: DeviceInfo, wizard: 'BaseWizard', purpose) -> 'HardwareClientBase':
"""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.

1
electrum/plugins/keepkey/keepkey.py

@ -283,6 +283,7 @@ class KeepKeyPlugin(HW_PluginBase):
wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub("m", 'standard'))
client.used()
return client
def get_xpub(self, device_id, derivation, xtype, wizard):
if xtype not in self.SUPPORTED_XTYPES:

1
electrum/plugins/ledger/ledger.py

@ -610,6 +610,7 @@ class LedgerPlugin(HW_PluginBase):
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
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
return client
def get_xpub(self, device_id, derivation, xtype, wizard):
if xtype not in self.SUPPORTED_XTYPES:

1
electrum/plugins/safe_t/safe_t.py

@ -257,6 +257,7 @@ class SafeTPlugin(HW_PluginBase):
wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub("m", 'standard'))
client.used()
return client
def get_xpub(self, device_id, derivation, xtype, wizard):
if xtype not in self.SUPPORTED_XTYPES:

1
electrum/plugins/trezor/trezor.py

@ -288,6 +288,7 @@ class TrezorPlugin(HW_PluginBase):
wizard.run_task_without_blocking_gui(
task=lambda: client.get_xpub('m', 'standard', creating=is_creating_wallet))
client.used()
return client
def get_xpub(self, device_id, derivation, xtype, wizard):
if xtype not in self.SUPPORTED_XTYPES:

Loading…
Cancel
Save