From 610dd7ce83f8e2acbf3d961287cfcc1f96257427 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Thu, 28 Apr 2022 19:37:20 +0200 Subject: [PATCH] hardware wallets: redefine "id_" for hid devices to avoid collisions I had a ledger nano S and a ledger nano S plus connected at the same time, and the "id_"s were colliding resulting in weird behaviour. Multisig was pretty much not usable with both devices connected simultaneously. Example dicts returned by `hid.enumerate(0, 0)`: {'path': b'\\\\?\\hid#vid_2c97&pid_1015&mi_00#a&2a30{REDACTED}&0&0000#{REDACTED_UUID}', 'vendor_id': 11415, 'product_id': 4117, 'serial_number': '0001', 'release_number': 513, 'manufacturer_string': 'Ledger', 'product_string': 'Nano S', 'usage_page': 65440, 'usage': 1, 'interface_number': 0}, {'path': b'\\\\?\\hid#vid_2c97&pid_5011&mi_00#a&28d{REDACTED}&0&0000#{REDACTED_UUID}', 'vendor_id': 11415, 'product_id': 20497, 'serial_number': '0001', 'release_number': 513, 'manufacturer_string': 'Ledger', 'product_string': 'Nano S Plus', 'usage_page': 65440, 'usage': 1, 'interface_number': 0} --- electrum/plugins/hw_wallet/plugin.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/electrum/plugins/hw_wallet/plugin.py b/electrum/plugins/hw_wallet/plugin.py index 192912b97..debfb60ec 100644 --- a/electrum/plugins/hw_wallet/plugin.py +++ b/electrum/plugins/hw_wallet/plugin.py @@ -66,13 +66,14 @@ class HW_PluginBase(BasePlugin): return self.parent.device_manager def create_device_from_hid_enumeration(self, d: dict, *, product_key) -> Optional['Device']: + # note: id_ needs to be unique between simultaneously connected devices, + # and ideally unchanged while a device is connected. # Older versions of hid don't provide interface_number interface_number = d.get('interface_number', -1) usage_page = d['usage_page'] - id_ = d['serial_number'] - if len(id_) == 0: - id_ = str(d['path']) - id_ += str(interface_number) + str(usage_page) + # id_=str(d['path']) in itself might be sufficient, but this had to be touched + # a number of times already, so let's just go for the overkill approach: + id_ = f"{d['path']},{d['serial_number']},{interface_number},{usage_page}" device = Device(path=d['path'], interface_number=interface_number, id_=id_,