From 85b36e027f8cada43aa755fdcef9291ab45a5e06 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Sun, 18 Mar 2018 03:54:28 +0100 Subject: [PATCH] fix a bug with hw devices. if a device is unplugged and then replugged before we notice (via scan_devices) then it will get into an unusable state, throwing all kinds of low level exceptions when we don't expect it. affects ledger, keepkey, dbb, but for some reason not trezor. --- lib/plugins.py | 2 +- plugins/digitalbitbox/digitalbitbox.py | 7 +++++++ plugins/keepkey/clientbase.py | 8 ++++++++ plugins/ledger/ledger.py | 14 +++++++------- plugins/trezor/clientbase.py | 8 ++++++++ 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/plugins.py b/lib/plugins.py index 4a8a2b882..4942899e7 100644 --- a/lib/plugins.py +++ b/lib/plugins.py @@ -552,7 +552,7 @@ class DeviceMgr(ThreadJob, PrintError): with self.lock: connected = {} for client, pair in self.clients.items(): - if pair in pairs: + if pair in pairs and client.has_usable_connection_with_device(): connected[client] = pair else: disconnected_ids.append(pair[1]) diff --git a/plugins/digitalbitbox/digitalbitbox.py b/plugins/digitalbitbox/digitalbitbox.py index e40a53fee..334c2f679 100644 --- a/plugins/digitalbitbox/digitalbitbox.py +++ b/plugins/digitalbitbox/digitalbitbox.py @@ -82,6 +82,13 @@ class DigitalBitbox_Client(): def is_paired(self): return self.password is not None + def has_usable_connection_with_device(self): + try: + self.dbb_has_password() + except BaseException: + return False + return True + def _get_xpub(self, bip32_path): if self.check_device_dialog(): return self.hid_send_encrypt(b'{"xpub": "%s"}' % bip32_path.encode('utf8')) diff --git a/plugins/keepkey/clientbase.py b/plugins/keepkey/clientbase.py index b354798a2..acbdb200a 100644 --- a/plugins/keepkey/clientbase.py +++ b/plugins/keepkey/clientbase.py @@ -113,6 +113,14 @@ class KeepKeyClientBase(GuiMixin, PrintError): def is_pairable(self): return not self.features.bootloader_mode + def has_usable_connection_with_device(self): + try: + res = self.ping("electrum pinging device") + assert res == "electrum pinging device" + except BaseException: + return False + return True + def used(self): self.last_operation = time.time() diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py index f95d70091..1fbd4ebb0 100644 --- a/plugins/ledger/ledger.py +++ b/plugins/ledger/ledger.py @@ -57,6 +57,13 @@ class Ledger_Client(): def i4b(self, x): return pack('>I', x) + def has_usable_connection_with_device(self): + try: + self.dongleObject.getFirmwareVersion() + except BaseException: + return False + return True + def test_pin_unlocked(func): """Function decorator to test the Ledger for being unlocked, and if not, raise a human-readable exception. @@ -513,13 +520,6 @@ class LedgerPlugin(HW_PluginBase): if self.libraries_available: self.device_manager().register_devices(self.DEVICE_IDS) - def btchip_is_connected(self, keystore): - try: - self.get_client(keystore).getFirmwareVersion() - except Exception as e: - return False - return True - def get_btchip_device(self, device): ledger = False if (device.product_key[0] == 0x2581 and device.product_key[1] == 0x3b7c) or (device.product_key[0] == 0x2581 and device.product_key[1] == 0x4b7c) or (device.product_key[0] == 0x2c97): diff --git a/plugins/trezor/clientbase.py b/plugins/trezor/clientbase.py index e7f0d43c8..d1126e071 100644 --- a/plugins/trezor/clientbase.py +++ b/plugins/trezor/clientbase.py @@ -119,6 +119,14 @@ class TrezorClientBase(GuiMixin, PrintError): def is_pairable(self): return not self.features.bootloader_mode + def has_usable_connection_with_device(self): + try: + res = self.ping("electrum pinging device") + assert res == "electrum pinging device" + except BaseException: + return False + return True + def used(self): self.last_operation = time.time()