URI: 
       ttrezor: cache whether TrezorBridge is available to speedup scan_devices - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit f36cc5b6e02bf34105e6129296decc29e105cf4f
   DIR parent c313c702fda3d6859d3b1a94a7e2cbccf5289df7
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Sat, 29 Aug 2020 04:22:55 +0200
       
       ttrezor: cache whether TrezorBridge is available to speedup scan_devices
       
       If the Bridge is unavailable, on my machine it takes 2 seconds to timeout.
       i.e. call_bridge("enumerate") and BridgeTransport.enumerate() both take 2 seconds each.
       With this change, if the Bridge is unavailable, DeviceMgr.scan_devices() takes 4 seconds less.
       In below log, with 6 different hw devices connected, scan time was originally ~7.5 seconds;
       with this change it became ~3.5 seconds.
       
       Now the time is dominated by WebUsbTransport.enumerate(), called by Trezor,
       KeepKey, SafeT, ~1.1 seconds each.
       
       -----
       
       I | plugin.DeviceMgr | scan_devices() entered. 1598666278.6756
       I | plugin.DeviceMgr | scan_devices(). _scan_devices_with_hid() DONE. 1598666278.7583
       I | plugin.DeviceMgr | scan_devices(). starting custom enumeration loop. 1598666278.7593
       I | plugin.DeviceMgr | scan_devices(). custom enumeration iter DONE, for <bound method SafeTPlugin.enumerate of <electrum.plugins.safe_t.qt.Plugin object at 0x000001F60060A730>>. 1598666279.9345
       I | plugins.trezor.qt.Plugin | trezor custom enumeration entered. 1598666279.9345
       I | plugins.trezor.qt.Plugin | trezor custom enumeration. call_bridge('enumerate') DONE. 1598666281.9385
       >> trezorlib enumerating <class 'trezorlib.transport.bridge.BridgeTransport'> DONE at 1598666283.9500.
       >> trezorlib enumerating <class 'trezorlib.transport.webusb.WebUsbTransport'> DONE at 1598666285.0427.
       >> trezorlib enumerating <class 'trezorlib.transport.hid.HidTransport'> DONE at 1598666285.1198.
       >> trezorlib enumerating <class 'trezorlib.transport.udp.UdpTransport'> DONE at 1598666285.1237.
       I | plugins.trezor.qt.Plugin | trezor custom enumeration. trezorlib.transport.enumerate_devices() DONE. 1598666285.1257
       I | plugin.DeviceMgr | scan_devices(). custom enumeration iter DONE, for <bound method TrezorPlugin.enumerate of <electrum.plugins.trezor.qt.Plugin object at 0x000001F60C16F4C0>>. 1598666285.1257
       I | plugin.DeviceMgr | scan_devices(). custom enumeration iter DONE, for <bound method KeepKeyPlugin.enumerate of <electrum.plugins.keepkey.qt.Plugin object at 0x000001F60BADF130>>. 1598666286.2251
       I | plugin.DeviceMgr | scan_devices(). custom enumeration iter DONE, for <bound method ColdcardPlugin.detect_simulator of <electrum.plugins.coldcard.qt.Plugin object at 0x000001F60BAA5AC0>>. 1598666286.2251
       I | plugin.DeviceMgr | scan_devices(). custom enumeration loop DONE. 1598666286.2251
       I | plugin.DeviceMgr | scan_devices(). find out what was disconnected DONE. 1598666286.2251
       I | plugin.DeviceMgr | scan_devices(). Unpair disconnected devices DONE. 1598666286.2251
       
       Diffstat:
         M electrum/plugins/trezor/trezor.py   |      23 ++++++++++++++++++-----
       
       1 file changed, 18 insertions(+), 5 deletions(-)
       ---
   DIR diff --git a/electrum/plugins/trezor/trezor.py b/electrum/plugins/trezor/trezor.py
       t@@ -130,6 +130,7 @@ class TrezorPlugin(HW_PluginBase):
                if not self.libraries_available:
                    return
                self.device_manager().register_enumerate_func(self.enumerate)
       +        self._is_bridge_available = None
        
            def get_library_version(self):
                import trezorlib
       t@@ -142,17 +143,29 @@ class TrezorPlugin(HW_PluginBase):
                else:
                    raise LibraryFoundButUnusable(library_version=version)
        
       +    def is_bridge_available(self) -> bool:
       +        # Testing whether the Bridge is available can take several seconds
       +        # (when it is not), as it is slow to timeout, hence we cache it.
       +        if self._is_bridge_available is None:
       +            try:
       +                call_bridge("enumerate")
       +            except Exception:
       +                self._is_bridge_available = False
       +                # never again try with Bridge due to slow timeout
       +                BridgeTransport.ENABLED = False
       +            else:
       +                self._is_bridge_available = True
       +        return self._is_bridge_available
       +
            def enumerate(self):
                # If there is a bridge, prefer that.
                # On Windows, the bridge runs as Admin (and Electrum usually does not),
                # so the bridge has better chances of finding devices. see #5420
                # This also avoids duplicate entries.
       -        try:
       -            call_bridge("enumerate")
       -        except Exception:
       -            devices = trezorlib.transport.enumerate_devices()
       -        else:
       +        if self.is_bridge_available():
                    devices = BridgeTransport.enumerate()
       +        else:
       +            devices = trezorlib.transport.enumerate_devices()
                return [Device(path=d.get_path(),
                               interface_number=-1,
                               id_=d.get_path(),