Browse Source

trezor: support outdated firmware notifications

Outdated firmware error messages were originally raised from
create_client, which would mean that a client for an outdated device
would not be created.

This had a number of undesirable outcomes due to "client does not exist"
being conflated with "no device is connected".

Instead, we raise in setup_client (which prevents creating new wallets
with outdated devices, BUT shows them in device list), and python-trezor
also raises on most calls (which gives us an error message when opening
wallet and/or trying to do basically anything with it).

This is still suboptimal - i.e., there's currently no way for Electrum to
claim higher version requirement than the underlying python-trezor, and
so minimum_firmware property is pretty much useless ATM.
3.3.3.1
matejcik 6 years ago
parent
commit
43acd09df8
  1. 16
      electrum/plugins/trezor/clientbase.py
  2. 22
      electrum/plugins/trezor/trezor.py

16
electrum/plugins/trezor/clientbase.py

@ -2,12 +2,12 @@ import time
from struct import pack from struct import pack
from electrum.i18n import _ from electrum.i18n import _
from electrum.util import PrintError, UserCancelled from electrum.util import PrintError, UserCancelled, UserFacingException
from electrum.keystore import bip39_normalize_passphrase from electrum.keystore import bip39_normalize_passphrase
from electrum.bip32 import serialize_xpub, convert_bip32_path_to_list_of_uint32 as parse_path from electrum.bip32 import serialize_xpub, convert_bip32_path_to_list_of_uint32 as parse_path
from trezorlib.client import TrezorClient from trezorlib.client import TrezorClient
from trezorlib.exceptions import TrezorFailure, Cancelled from trezorlib.exceptions import TrezorFailure, Cancelled, OutdatedFirmwareError
from trezorlib.messages import WordRequestType, FailureType, RecoveryDeviceType from trezorlib.messages import WordRequestType, FailureType, RecoveryDeviceType
import trezorlib.btc import trezorlib.btc
import trezorlib.device import trezorlib.device
@ -66,6 +66,8 @@ class TrezorClientBase(PrintError):
raise UserCancelled from exc_value raise UserCancelled from exc_value
elif issubclass(exc_type, TrezorFailure): elif issubclass(exc_type, TrezorFailure):
raise RuntimeError(exc_value.message) from exc_value raise RuntimeError(exc_value.message) from exc_value
elif issubclass(exc_type, OutdatedFirmwareError):
raise UserFacingException(exc_value) from exc_value
else: else:
return False return False
return True return True
@ -163,12 +165,10 @@ class TrezorClientBase(PrintError):
self.print_error("closing client") self.print_error("closing client")
self.clear_session() self.clear_session()
def firmware_version(self): def is_uptodate(self):
f = self.features if self.client.is_outdated():
return (f.major_version, f.minor_version, f.patch_version) return False
return self.client.version >= self.plugin.minimum_firmware
def atleast_version(self, major, minor=0, patch=0):
return self.firmware_version() >= (major, minor, patch)
def get_trezor_model(self): def get_trezor_model(self):
"""Returns '1' for Trezor One, 'T' for Trezor T.""" """Returns '1' for Trezor One, 'T' for Trezor T."""

22
electrum/plugins/trezor/trezor.py

@ -141,20 +141,7 @@ class TrezorPlugin(HW_PluginBase):
self.print_error("connected to device at", device.path) self.print_error("connected to device at", device.path)
# note that this call can still raise! # note that this call can still raise!
client = TrezorClientBase(transport, handler, self) return TrezorClientBase(transport, handler, self)
if not client.atleast_version(*self.minimum_firmware):
msg = (_('Outdated {} firmware for device labelled {}. Please '
'download the updated firmware from {}')
.format(self.device, client.label(), self.firmware_URL))
self.print_error(msg)
if handler:
handler.show_error(msg)
else:
raise UserFacingException(msg)
return None
return client
def get_client(self, keystore, force_pair=True): def get_client(self, keystore, force_pair=True):
devmgr = self.device_manager() devmgr = self.device_manager()
@ -265,6 +252,13 @@ class TrezorPlugin(HW_PluginBase):
if client is None: if client is None:
raise UserFacingException(_('Failed to create a client for this device.') + '\n' + raise UserFacingException(_('Failed to create a client for this device.') + '\n' +
_('Make sure it is in the correct state.')) _('Make sure it is in the correct state.'))
if not client.is_uptodate():
msg = (_('Outdated {} firmware for device labelled {}. Please '
'download the updated firmware from {}')
.format(self.device, client.label(), self.firmware_URL))
raise UserFacingException(msg)
# fixme: we should use: client.handler = wizard # fixme: we should use: client.handler = wizard
client.handler = self.create_handler(wizard) client.handler = self.create_handler(wizard)
if not device_info.initialized: if not device_info.initialized:

Loading…
Cancel
Save