ttrezor: don't let bridge transport failing block all other transports - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit dace2e5495165a1a6ff186442966dde1934b69c0 DIR parent 47b6d3c52c863e9f677731920817f1237527a028 HTML Author: SomberNight <somber.night@protonmail.com> Date: Thu, 8 Nov 2018 17:07:05 +0100 ttrezor: don't let bridge transport failing block all other transports t[trezor] connecting to device at bridge:hid... t[trezor] connected to device at bridge:hid... Traceback (most recent call last): File "...\electrum\electrum\base_wizard.py", line 255, in choose_hw_device u = devmgr.unpaired_device_infos(None, plugin, devices=scanned_devices) File "...\electrum\electrum\plugin.py", line 501, in unpaired_device_infos client = self.create_client(device, handler, plugin) File "...\electrum\electrum\plugin.py", line 374, in create_client client = plugin.create_client(device, handler) File "...\electrum\electrum\plugins\trezor\trezor.py", line 124, in create_client client = self.client_class(transport, handler, self) File "...\electrum\electrum\plugins\trezor\client.py", line 7, in __init__ ProtocolMixin.__init__(self, transport=transport) File "...\Python36-32\lib\site-packages\trezorlib\client.py", line 444, in __init__ self.init_device() File "...\Python36-32\lib\site-packages\trezorlib\client.py", line 454, in init_device self.features = expect(proto.Features)(self.call)(init_msg) File "...\Python36-32\lib\site-packages\trezorlib\client.py", line 115, in wrapped_f ret = f(*args, **kwargs) File "...\Python36-32\lib\site-packages\trezorlib\client.py", line 129, in wrapped_f client.transport.session_begin() File "...\Python36-32\lib\site-packages\trezorlib\transport\__init__.py", line 42, in session_begin self.open() File "...\Python36-32\lib\site-packages\trezorlib\transport\bridge.py", line 69, in open raise TransportException('trezord: Could not acquire session' + get_error(r)) ttrezorlib.transport.TransportException: trezord: Could not acquire session (error=400 str=wrong previous session) t[DeviceMgr] error getting device infos for trezor: trezord: Could not acquire session (error=400 str=wrong previous session) Diffstat: M electrum/base_wizard.py | 10 ++++++++-- M electrum/plugin.py | 8 ++++++-- M electrum/plugins/trezor/trezor.py | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) --- DIR diff --git a/electrum/base_wizard.py b/electrum/base_wizard.py t@@ -27,6 +27,7 @@ import os import sys import traceback from functools import partial +from typing import List, TYPE_CHECKING, Tuple from . import bitcoin from . import keystore t@@ -41,6 +42,9 @@ from .util import UserCancelled, InvalidPassword, WalletFileException from .simple_config import SimpleConfig from .plugin import Plugins +if TYPE_CHECKING: + from .plugin import DeviceInfo + # hardware device setup purpose HWD_SETUP_NEW_WALLET, HWD_SETUP_DECRYPT_WALLET = range(0, 2) t@@ -230,7 +234,7 @@ class BaseWizard(object): # check available plugins supported_plugins = self.plugins.get_hardware_support() # scan devices - devices = [] + devices = [] # type: List[Tuple[str, DeviceInfo]] devmgr = self.plugins.device_manager try: scanned_devices = devmgr.scan_devices() t@@ -254,6 +258,7 @@ class BaseWizard(object): # FIXME: side-effect: unpaired_device_info sets client.handler u = devmgr.unpaired_device_infos(None, plugin, devices=scanned_devices) except BaseException as e: + traceback.print_exc() devmgr.print_error(f'error getting device infos for {name}: {e}') indented_error_msg = ' '.join([''] + str(e).splitlines(keepends=True)) debug_msg += f' {name}: (error getting device infos)\n{indented_error_msg}\n' t@@ -278,7 +283,8 @@ class BaseWizard(object): for name, info in devices: state = _("initialized") if info.initialized else _("wiped") label = info.label or _("An unnamed {}").format(name) - descr = "%s [%s, %s]" % (label, name, state) + descr = f"{label} [{name}, {state}]" + # TODO maybe expose info.device.path (mainly for transport type) choices.append(((name, info), descr)) msg = _('Select a device') + ':' self.choice_dialog(title=title, message=msg, choices=choices, run_next= lambda *args: self.on_device(*args, purpose=purpose)) DIR diff --git a/electrum/plugin.py b/electrum/plugin.py t@@ -485,7 +485,7 @@ class DeviceMgr(ThreadJob, PrintError): 'its seed (and passphrase, if any). Otherwise all bitcoins you ' 'receive will be unspendable.').format(plugin.device)) - def unpaired_device_infos(self, handler, plugin, devices=None): + def unpaired_device_infos(self, handler, plugin: 'HW_PluginBase', devices=None): '''Returns a list of DeviceInfo objects: one for each connected, unpaired device accepted by the plugin.''' if not plugin.libraries_available: t@@ -498,7 +498,11 @@ class DeviceMgr(ThreadJob, PrintError): for device in devices: if device.product_key not in plugin.DEVICE_IDS: continue - client = self.create_client(device, handler, plugin) + try: + client = self.create_client(device, handler, plugin) + except BaseException as e: + self.print_error(f'failed to create client for {plugin.name} at {device.path}: {repr(e)}') + continue if not client: continue infos.append(DeviceInfo(device, client.label(), client.is_initialized())) DIR diff --git a/electrum/plugins/trezor/trezor.py b/electrum/plugins/trezor/trezor.py t@@ -121,6 +121,7 @@ class TrezorPlugin(HW_PluginBase): return self.print_error("connected to device at", device.path) + # note that this call can still raise! client = self.client_class(transport, handler, self) # Try a ping for device sanity