1
0
Commit Graph

16377 Commits

Author SHA1 Message Date
SomberNight
c9536180c5 lnutil.LnFeatures: limit max feature bit to 10_000
closes https://github.com/spesmilo/electrum/issues/8403

> In Python 3.10 that worked fine, however in Python 3.11 large integer check https://github.com/python/cpython/issues/95778, so now this throws an error.

Apparently this change was deemed a security fix and was backported to all supported branches of CPython (going back to 3.7). i.e. it affects ~all versions of python (if sufficiently updated with bugfix patches), not just 3.11

> Some offending node aliases:
> ```
> ergvein-fiatchannels
> test-mainnet
> arakis
> ```

The features bits set by some of these nodes:
```
(1, 7, 8, 11, 13, 14, 17, 19, 23, 27, 45, 32973, 52973)
(1, 7, 8, 11, 13, 14, 17, 19, 23, 27, 39, 45, 55, 32973, 52973)
```

> P.S. I see there are a lot of nodes with 253 bytes in their feature vectors. Any idea why that could happen?

Note that the valid [merged-into-spec features](50b2df24a2/09-features.md) currently only go as high as ~51.
However the spec does not specify how to choose feature bits for experimental stuff, so I guess some people are using values in the 50k range. The only limit imposed by the spec on the length of the features bitvector is an implicit one due to the max message size: every msg must be smaller than 65KB, and the features bitvector needs to fit inside the init message, hence it can be up to ~524K bits.
(note that the features are not stored in a sparse representation in the init message and in gossip messages, so if many nodes set such high feature bits, that would noticably impact the size of the gossip).

-----

Anyway, our current implementation of LnFeatures is subclassing IntFlag, and it looks like it does not work well for such large integers. I've managed to make IntFlags reasonably in python 3.11 by overriding __str__ and __repr__ (note that in cpython it is apparently only the base2<->base10 conversions that are slow, power-of-2 conversions are fast, so we can e.g. use `hex()`). However in python 3.10 and older, enum.py itself seems really slow for bigints, e.g. enum._decompose in python 3.10.

Try e.g. this script, which is instant in py3.11 but takes minutes in py3.10:
```py
from enum import IntFlag
class c(IntFlag):
    known_flag_1 = 1 << 0
    known_flag_2 = 1 << 1
    known_flag_3 = 1 << 2
    if hasattr(IntFlag, "_numeric_repr_"):  # python 3.11+
        _numeric_repr_ = hex
    def __repr__(self):
        return f"<{self._name_}: {hex(self._value_)}>"
    def __str__(self):
        return hex(self._value_)

a = c(2**70000-1)
q1 = repr(a)
q2 = str(a)
```

AFAICT we have two options: either we rewrite LnFeatures so that it does not use IntFlag (and enum.py), or, for the short term as workaround, we could just reject very large feature bits.
For now, I've opted to the latter, rejecting feature bits over 10k.

(note that another option is bumping the min required python to 3.11, in which case with the overrides added in this commit the performance looks perfectly fine)
2023-05-08 19:37:33 +00:00
Sander van Grieken
d12752cc42 qml: add Technical properties header for TxDetails and LightningPaymentDetails 2023-05-08 14:53:45 +02:00
SomberNight
209c9f75e0 transaction: fix add_info_from_wallet_and_network
fixes https://github.com/spesmilo/electrum/issues/8406
2023-05-07 21:50:23 +00:00
SomberNight
38ec72527f wallet.get_bolt11_invoice: handle request not having LN part
fixes https://github.com/spesmilo/electrum/issues/8402

To reproduce,
- create wallet from a zpub
- LN is disabled there by default
- create a receive request, which won't have a lightning part
- enable config var "bip21_lightning"
- enable LN
- existing request is now ~breaking receive tab
2023-05-07 00:39:06 +00:00
ThomasV
c0917e65af fix #8391: reintroduce recursion, limited to unconfirmed transactions
It would be better to have topological order, but this issue needs to
be fixed quickly.
2023-05-06 18:10:51 +02:00
SomberNight
1e55042830 wallet: set_frozen_state_of_{addresses,coins} to save_db() to disk
fixes https://github.com/spesmilo/electrum/issues/8389
2023-05-06 13:26:08 +00:00
SomberNight
3674fc5a91 follow-up prev: forgot to amend the commit message :(
follow-up a0c43573ab

This now runs the more advanced GUI-specific default lang detection
before the specific GUI is imported. This means even module-level
translated strings will use the correct language, at least in the
GUI modules.

Before this commit, more UI strings would be translated to German
if the user explicitly set the language to German, compared to
how many were translated if the language was "default" and got
set to German via the default-lang mechanism. This should no longer
be the case.

related: https://github.com/spesmilo/electrum/issues/4621
2023-05-05 17:38:41 +00:00
SomberNight
a0c43573ab locale/i18n: get default language and set it as early as possible
TODO elaborate xxxxx
2023-05-05 17:00:18 +00:00
SomberNight
9c47144418 qt: handle expected errors in DSCancelDialog
closes https://github.com/spesmilo/electrum/issues/8390
2023-05-05 16:06:16 +00:00
SomberNight
3020499199 hww: ledger: bump required ledger-bitcoin and adapt to API change 2023-05-05 15:02:34 +00:00
SomberNight
fea0b84372 SECURITY.md: make email addrs more bot-resistant 2023-05-04 20:13:57 +00:00
SomberNight
847b3e9193 update release notes 2023-05-04 15:24:34 +00:00
SomberNight
205f2955f0 network: add another hardcoded signet server 2023-05-04 15:05:34 +00:00
ThomasV
ff287e518f update version to 4.4.2 + date release notes 4.4.2 2023-05-04 14:24:26 +02:00
ThomasV
8e81b920a7 Merge pull request #8385 from SomberNight/20230504_qml_ks_password
qml: always ask for the password on wallet-open, even for ks-enc-only wallets
2023-05-04 14:22:24 +02:00
ThomasV
ce7abd99c1 update locale 2023-05-04 14:01:11 +02:00
Sander van Grieken
9d11aae394 qml: take internal, external, billing address colors from desktop client and color output addresses
accordingly in ConfirmTxDialog, TxDetails, CpfpBumpFeeDialog, RbfBumpFeeDialog and RbfCancelDialog
2023-05-04 13:26:56 +02:00
Sander van Grieken
397019fe19 qml: veriyMasterKey don't raise Exception on unsupported wallet_type, log error and provide user feedback 2023-05-04 12:45:40 +02:00
SomberNight
97650399cf qml: always ask for the password on wallet-open, even for ks-enc-only wallets
This is a hugely hackish -- it uses the kivy approach, which uses this same hack...
I am not really content with it but it should be relatively easy to review,
and if ok, should hotfix the linked issue.

fixes https://github.com/spesmilo/electrum/issues/8374
related https://github.com/spesmilo/electrum/pull/8382
2023-05-04 10:11:30 +00:00
SomberNight
2732a82535 build: update pinned pyqt5 (partial rerun freeze_packages)
User at https://bitcointalk.org/index.php?topic=5450976.0 reported getting
a segfault on macos using qt gui, after entering password to open wallet.
Shot in the dark, but let's try updating Qt.
2023-05-04 01:20:00 +00:00
Sander van Grieken
325a1bbba6 followup ae12d236b2 2023-05-04 01:17:29 +02:00
Sander van Grieken
ae12d236b2 qml: fix broadcastFailed signal connections in txdetails (fixes #8384) 2023-05-04 01:15:25 +02:00
Sander van Grieken
3b31e68a86 update release notes 2023-05-04 01:11:35 +02:00
Sander van Grieken
2eaf3dcc64 qml: cleanup 2023-05-03 22:50:58 +02:00
Sander van Grieken
0be8beb9c4 qml: add secure flag to WalletDetails, set when seed is shown 2023-05-03 22:41:25 +02:00
SomberNight
56fa832563 wallet.get_tx_parents: explicitly handle missing "from address"
(happened to work even without this)
2023-05-03 15:08:56 +00:00
SomberNight
a1bfea6121 wallet.get_tx_parents: fix: tx should not be its own uncle
```
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp0. entered for txid='407d03126255cce62a1101075db906587bd492f512166119d3f87b8a1b013497'
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp4.1. parents=['e2d915520f6d42273158a6fd08b38d812bd554aa906d3ed45d103757d45af2bb']
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp4.2. uncles=[]
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp2. populating cache... _txid='434808dab0c93715bb8b7ce85f73bffd0bdf7c1ba205fe0f704226646971e555'
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp0. entered for txid='434808dab0c93715bb8b7ce85f73bffd0bdf7c1ba205fe0f704226646971e555'
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp3.0. uncle_txid='434808dab0c93715bb8b7ce85f73bffd0bdf7c1ba205fe0f704226646971e555'
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp3.1. reuse_height=-2 reuse_pos=-1
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp3.2. my_height=1338 my_pos=1
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp4.1. parents=['407d03126255cce62a1101075db906587bd492f512166119d3f87b8a1b013497']
  3.06 | I | w/wallet.Standard_Wallet.[default_wallet] | get_tx_parents() cp4.2. uncles=['434808dab0c93715bb8b7ce85f73bffd0bdf7c1ba205fe0f704226646971e555']
 40.82 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "/home/user/wspace/electrum/electrum/gui/qt/main_window.py", line 846, in timer_actions
    self.update_wallet()
  File "/home/user/wspace/electrum/electrum/gui/qt/main_window.py", line 1001, in update_wallet
    self.update_tabs()
  File "/home/user/wspace/electrum/electrum/gui/qt/main_window.py", line 1013, in update_tabs
    self.utxo_list.update()
  File "/home/user/wspace/electrum/electrum/util.py", line 470, in <lambda>
    return lambda *args, **kw_args: do_profile(args, kw_args)
  File "/home/user/wspace/electrum/electrum/util.py", line 465, in do_profile
    o = func(*args, **kw_args)
  File "/home/user/wspace/electrum/electrum/gui/qt/utxo_list.py", line 115, in update
    self.refresh_row(name, idx)
  File "/home/user/wspace/electrum/electrum/gui/qt/utxo_list.py", line 137, in refresh_row
    num_parents = self.wallet.get_num_parents(txid)
  File "/home/user/wspace/electrum/electrum/wallet.py", line 897, in get_num_parents
    self._num_parents[txid] = len(self.get_tx_parents(txid))
  File "/home/user/wspace/electrum/electrum/wallet.py", line 910, in get_tx_parents
    self.get_tx_parents(_txid)
  File "/home/user/wspace/electrum/electrum/wallet.py", line 938, in get_tx_parents
    p = self._tx_parents_cache[_txid]
KeyError: '434808dab0c93715bb8b7ce85f73bffd0bdf7c1ba205fe0f704226646971e555'
```
2023-05-03 15:06:37 +00:00
SomberNight
5512c7d905 wallet.get_tx_info: distinguish "future" tx from local in "status" str
closes https://github.com/spesmilo/electrum/issues/8379
2023-05-03 14:15:08 +00:00
SomberNight
53d61c011a qml network: restrict cases where server is shown "lagging" 2023-05-03 13:49:44 +00:00
SomberNight
3bdda3a861 config: force 'history_rates' config var to bool
fixes https://github.com/spesmilo/electrum/issues/8367

probably regression from 503776c0de
(note that before that commit, we were casting to bool)
2023-05-03 12:18:34 +00:00
Sander van Grieken
1a889d19b5 Merge branch 'seed_keyboard' 2023-05-03 11:47:52 +02:00
Sander van Grieken
c8c76a8d6f qml: fix var ref 2023-05-02 20:16:36 +02:00
SomberNight
33d394c9d7 ledger: fix scan_devices for certain devices with multiple interfaces
regression from https://github.com/spesmilo/electrum/pull/8041 (4.3.3)

maybe fixes https://github.com/spesmilo/electrum/issues/8293

-----

Testing with a "Ledger Nano S", btc app version 1.6.3.
btchip-python==0.1.32
ledgercomm==1.1.1
ledger-bitcoin==0.1.1

Trying to scan devices hangs/blocks forever on Linux (ubuntu 22.04).

```patch
diff --git a/electrum/plugins/ledger/ledger.py b/electrum/plugins/ledger/ledger.py
index 17c1caca48..ba5ae2e3ee 100644
--- a/electrum/plugins/ledger/ledger.py
+++ b/electrum/plugins/ledger/ledger.py
@@ -306,17 +306,25 @@ class Ledger_Client(HardwareClientBase, ABC):
     @staticmethod
     def construct_new(*args, device: Device, **kwargs) -> 'Ledger_Client':
         """The 'real' constructor, that automatically decides which subclass to use."""
+        _logger.info(f"xxx construct_new(). cp1. {device.path=}. {device=}")
         if LedgerPlugin.is_hw1(device.product_key):
             return Ledger_Client_Legacy_HW1(*args, **kwargs, device=device)
         # for nano S or newer hw, decide which client impl to use based on software/firmware version:
+        _logger.info(f"xxx construct_new(). cp2.")
         hid_device = HID()
         hid_device.path = device.path
+        _logger.info(f"xxx construct_new(). cp3.")
         hid_device.open()
+        _logger.info(f"xxx construct_new(). cp4.")
         transport = ledger_bitcoin.TransportClient('hid', hid=hid_device)
-        cl = ledger_bitcoin.createClient(transport, chain=get_chain())
+        _logger.info(f"xxx construct_new(). cp5.")
+        cl = ledger_bitcoin.createClient(transport, chain=get_chain(), debug=True)
+        _logger.info(f"xxx construct_new(). cp6.")
         if isinstance(cl, ledger_bitcoin.client.NewClient):
+            _logger.info(f"xxx construct_new(). cp7. trying Ledger_Client_New")
             return Ledger_Client_New(hid_device, *args, **kwargs)
         else:
+            _logger.info(f"xxx construct_new(). cp7. trying Ledger_Client_Legacy")
             return Ledger_Client_Legacy(hid_device, *args, **kwargs)

     def __init__(self, *, plugin: HW_PluginBase):
@@ -1416,7 +1424,7 @@ class LedgerPlugin(HW_PluginBase):
         try:
             return Ledger_Client.construct_new(device=device, product_key=device.product_key, plugin=self)
         except Exception as e:
-            self.logger.info(f"cannot connect at {device.path} {e}")
+            self.logger.info(f"cannot connect at {device.path} {e}")  #
         return None

     def setup_device(self, device_info, wizard, purpose):
```

scanning devices freezes... log:
```
  8.94 | I | plugin.DeviceMgr | scanning devices...
  9.18 | D | util.profiler | DeviceMgr.scan_devices 0.2357 sec
  9.18 | I | plugins.ledger.ledger | xxx construct_new(). cp1. device.path=b'0001:0008:00'. device=Device(path=b'0001:0008:00', interface_number=0, id_="b'0001:0008:00',0001,0,0", product_key=(11415, 4117), usage_page=0, transport_ui_string='hid')
  9.18 | I | plugins.ledger.ledger | xxx construct_new(). cp2.
  9.18 | I | plugins.ledger.ledger | xxx construct_new(). cp3.
heyheyhey. cp1. self.path=b'0001:0008:00'
  9.18 | I | plugins.ledger.ledger | xxx construct_new(). cp4.
  9.18 | I | plugins.ledger.ledger | xxx construct_new(). cp5.
=> b001000000
<= 010c426974636f696e205465737405312e362e3301029000
  9.22 | I | plugins.ledger.ledger | xxx construct_new(). cp6.
  9.22 | I | plugins.ledger.ledger | xxx construct_new(). cp7. trying Ledger_Client_Legacy
  9.29 | I | plugin.DeviceMgr | Registering <electrum.plugins.ledger.ledger.Ledger_Client_Legacy object at 0x7f4369e6e380>
 10.33 | I | plugins.ledger.ledger | xxx construct_new(). cp1. device.path=b'0001:0008:01'. device=Device(path=b'0001:0008:01', interface_number=1, id_="b'0001:0008:01',0001,1,0", product_key=(11415, 4117), usage_page=0, transport_ui_string='hid')
 10.33 | I | plugins.ledger.ledger | xxx construct_new(). cp2.
 10.33 | I | plugins.ledger.ledger | xxx construct_new(). cp3.
heyheyhey. cp1. self.path=b'0001:0008:01'
 10.33 | I | plugins.ledger.ledger | xxx construct_new(). cp4.
 10.33 | I | plugins.ledger.ledger | xxx construct_new(). cp5.
=> b001000000
```

in Qt console (before change):
```
>>> lp = plugins.get_plugin("ledger")
>>> plugins.device_manager.scan_devices()
[Device(path=b'0001:000a:00', interface_number=0, id_="b'0001:000a:00',0001,0,0", product_key=(11415, 4117), usage_page=0, transport_ui_string='hid'), Device(path=b'0001:000a:01', interface_number=1, id_="b'0001:000a:01',0001,1,0", product_key=(11415, 4117), usage_page=0, transport_ui_string='hid')]
```
2023-05-02 17:23:07 +00:00
SomberNight
7f52415807 util: add some logging to NetworkJobOnDefaultServer starting/stopping
to help debug claims of Synchronizer maybe getting stuck
2023-05-02 13:41:47 +00:00
Sander van Grieken
0672ea20ab qml: implement toggle for android SECURE_FLAG and add marker to wizard pages
that should be secured.
2023-05-02 15:16:51 +02:00
Sander van Grieken
8cd26820bf qml: styling seedtextarea 2023-05-02 13:56:55 +02:00
Sander van Grieken
95f960bb67 qml: seedtext word suggestions below text area 2023-05-02 13:04:33 +02:00
Sander van Grieken
b290fbd4b5 qml: seedkeyboard padding, explicit keycode, backspace next to spacebar 2023-05-02 13:03:13 +02:00
ThomasV
8a25d59ba6 wallet: save num_parents of utxos in wallet file.
fixes #8361
2023-05-02 09:27:39 +02:00
ThomasV
6d392a67f9 wallet.get_tx_parents: populate cache regardless of self.is_up_to_date()
Fixes #8315
2023-05-02 09:11:21 +02:00
Sander van Grieken
6394cdcd3b qml: disable Qt Virtual Keyboard and refactor keyboardFreeZone item to take
android system keyboard into account
2023-05-01 18:39:16 +02:00
Sander van Grieken
9ac83f6d9f qml: add SeedKeyboard for seed entry without using system virtual keyboard 2023-05-01 16:59:40 +02:00
Sander van Grieken
5600375d51 qml: no auto caps on import and master key controls 2023-04-29 14:30:25 +02:00
Sander van Grieken
56165c3790 qml: don't start loadWallet if daemon is busy loading. 2023-04-29 14:13:12 +02:00
Sander van Grieken
1b362f64f2 qml: properly delete wizard components after use. fixes #8357 2023-04-29 13:57:16 +02:00
Sander van Grieken
db53b0f573 qml: fix 2fa callback issue #8368 2023-04-29 12:05:25 +02:00
SomberNight
155258f208 release.sh: check we have each binary (RM case)
~duplicated from the non-RM case
2023-04-27 17:36:09 +00:00
SomberNight
22b8c4e397 hww: fix digitalbitbox(1) support
regression from cea4238b81

```
975.04 | E | plugin.DeviceMgr | failed to create client for digitalbitbox at <REDACTED>: AttributeError("'NoneType' object has no attribute 'get_passphrase'")
Traceback (most recent call last):
  File "...\electrum\electrum\plugin.py", line 620, in list_pairable_device_infos
    soft_device_id = client.get_soft_device_id()
  File "...\electrum\electrum\plugins\hw_wallet\plugin.py", line 251, in get_soft_device_id
    root_fp = self.request_root_fingerprint_from_device()
  File "...\electrum\electrum\plugin.py", line 362, in wrapper
    return run_in_hwd_thread(partial(func, *args, **kwargs))
  File "...\electrum\electrum\plugin.py", line 352, in run_in_hwd_thread
    return func()
  File "...\electrum\electrum\plugins\hw_wallet\plugin.py", line 264, in request_root_fingerprint_from_device
    child_of_root_xpub = self.get_xpub("m/0'", xtype='standard')
  File "...\electrum\electrum\plugins\digitalbitbox\digitalbitbox.py", line 115, in get_xpub
    reply = self._get_xpub(bip32_path)
  File "...\electrum\electrum\plugins\digitalbitbox\digitalbitbox.py", line 110, in _get_xpub
    if self.check_device_dialog():
  File "...\electrum\electrum\plugins\digitalbitbox\digitalbitbox.py", line 197, in check_device_dialog
    if not self.password_dialog(msg):
  File "...\electrum\electrum\plugins\digitalbitbox\digitalbitbox.py", line 159, in password_dialog
    password = self.handler.get_passphrase(msg, False)
AttributeError: 'NoneType' object has no attribute 'get_passphrase'
```
2023-04-27 17:33:54 +00:00
SomberNight
499f51535f bip32: fix hardened char "h" vs "'" compatibility for some hw wallets
in particular, ledger: fix sign_message for some wallets

```
156.02 | E | plugins.ledger.ledger |
Traceback (most recent call last):
  File "...\electrum\electrum\plugins\ledger\ledger.py", line 1265, in sign_message
    result = base64.b64decode(self.client.sign_message(message, address_path))
  File "...\Python310\site-packages\ledger_bitcoin\client.py", line 230, in sign_message
    sw, response = self._make_request(self.builder.sign_message(message_bytes, bip32_path), client_intepreter)
  File "...\Python310\site-packages\ledger_bitcoin\command_builder.py", line 176, in sign_message
    bip32_path: List[bytes] = bip32_path_from_string(bip32_path)
  File "...\Python310\site-packages\ledger_bitcoin\common.py", line 68, in bip32_path_from_string
    return [int(p).to_bytes(4, byteorder="big") if "'" not in p
  File "...\Python310\site-packages\ledger_bitcoin\common.py", line 68, in <listcomp>
    return [int(p).to_bytes(4, byteorder="big") if "'" not in p
ValueError: invalid literal for int() with base 10: '84h'
```

Regression from df2bd61de6, where the
default hardened char was changed from "'" to "h". Note that there was
no corresponding wallet db upgrade, so some files use one char and
others use the other.
2023-04-27 17:03:16 +00:00
SomberNight
9e1bb940ac prepare release 4.4.1 4.4.1 2023-04-27 11:11:29 +00:00