A user provided an invoice that requires feature bit 30. (That bit is not in the spec)
To test:
```
lnbc1p324a66pp5tundykxx3q5kztsr8x00eknpn2uwe3394cnky3j9a0fswm568wnsdp9facx2mj5d9kk2um5v9khqueqv3hkuct5d9hkucqzpgxq9z0rgqsp5l73jgfgctzc92juer5rk2mqcrkj8teng53dr9vfxj4n8lulu4jmq9q8pqqqssq4gacn859tpzz99hkusnh7m93d5ncpx3t4zns8ynca7akmljpl5vh504qjz7dqwewqjh4md7xagaz5wg85knvxywrhp0sp2t09yta7lcq3qs6fy
lntb1p324a66pp5tundykxx3q5kztsr8x00eknpn2uwe3394cnky3j9a0fswm568wnssp5l73jgfgctzc92juer5rk2mqcrkj8teng53dr9vfxj4n8lulu4jmqdp9facx2mj5d9kk2um5v9khqueqv3hkuct5d9hkuxq9z0rgq9q8pqqqssqdte0z9dy7ur7fagsk7r3mtfj6upq88xfylhufys87zqpamklcfgn2f3xeq3nlhvn3qy9tdgg42vq9eq99qz6rz6tzqezfhzuv6zsr5qp7cgel4
```
In commit 9bba65199e,
the QRCodeWidget was put inside a BoxLayout as a workaround to avoid the "copy to clipboard" and
"save as file" functionality grabbing extra whitespace/stretch/padding and putting it into the
exported image.
However, in turn that commit introduced a bug, where making the dialog larger does not make the
QRCodeWidget larger (which worked prior).
This commit tries to fix the regression and also the original bug.
If keystore.check_password is called with some pw on a keystore that does not have a password set,
it now raises better exceptions: it should now always raise InvalidPassword, and with a nicer msg.
Previously the exc type would depend on the ks type.
Examples before change:
```
>>> wallet.keystore.check_password("asd")
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/keystore.py", line 580, in check_password
xprv = pw_decode(self.xprv, password, version=self.pw_hash_version)
File "/home/user/wspace/electrum/electrum/crypto.py", line 311, in pw_decode
plaintext_bytes = pw_decode_bytes(data, password, version=version)
File "/home/user/wspace/electrum/electrum/crypto.py", line 270, in pw_decode_bytes
data_bytes = bytes(base64.b64decode(data))
File "/usr/lib/python3.10/base64.py", line 87, in b64decode
return binascii.a2b_base64(s)
binascii.Error: Incorrect padding
```
```
>>> wallet.keystore.check_password("asd")
Traceback (most recent call last):
s = aes_decrypt_with_iv(secret, iv, e)
File "/home/user/wspace/electrum/electrum/crypto.py", line 157, in aes_decrypt_with_iv
data = decryptor.update(data) + decryptor.finalize()
File "/usr/lib/python3/dist-packages/cryptography/hazmat/primitives/ciphers/base.py", line 148, in finalize
data = self._ctx.finalize()
File "/usr/lib/python3/dist-packages/cryptography/hazmat/backends/openssl/ciphers.py", line 193, in finalize
raise ValueError(
ValueError: The length of the provided data is not a multiple of the block length.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/gui/qt/console.py", line 254, in exec_command
result = eval(command, self.namespace, self.namespace)
File "<string>", line 1, in <module>
File "/home/user/wspace/electrum/electrum/keystore.py", line 248, in check_password
self.get_private_key(pubkey, password)
File "/home/user/wspace/electrum/electrum/keystore.py", line 267, in get_private_key
sec = pw_decode(self.keypairs[pubkey], password, version=self.pw_hash_version)
File "/home/user/wspace/electrum/electrum/crypto.py", line 311, in pw_decode
plaintext_bytes = pw_decode_bytes(data, password, version=version)
File "/home/user/wspace/electrum/electrum/crypto.py", line 271, in pw_decode_bytes
return _pw_decode_raw(data_bytes, password, version=version)
File "/home/user/wspace/electrum/electrum/crypto.py", line 255, in _pw_decode_raw
raise InvalidPassword() from e
electrum.util.InvalidPassword: Incorrect password
```
-----
Examples after change:
```
>>> wallet.keystore.check_password("asd")
Traceback (most recent call last):
return binascii.a2b_base64(s)
binascii.Error: Incorrect padding
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "...\electrum\keystore.py", line 68, in wrapper
return check_password_fn(self, password)
File "...\electrum\keystore.py", line 605, in check_password
xprv = pw_decode(self.xprv, password, version=self.pw_hash_version)
File "...\electrum\crypto.py", line 311, in pw_decode
plaintext_bytes = pw_decode_bytes(data, password, version=version)
File "...\electrum\crypto.py", line 267, in pw_decode_bytes
raise CiphertextFormatError("ciphertext not valid base64") from e
electrum.crypto.CiphertextFormatError: ciphertext not valid base64
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "...\electrum\gui\qt\console.py", line 254, in exec_command
result = eval(command, self.namespace, self.namespace)
File "<string>", line 1, in <module>
File "...\electrum\keystore.py", line 76, in wrapper
raise InvalidPassword("password given but keystore has no password") from e
electrum.util.InvalidPassword: password given but keystore has no password
```
```
>>> wallet.keystore.check_password("asd")
Traceback (most recent call last):
s = aes_decrypt_with_iv(secret, iv, e)
File "...\electrum\crypto.py", line 158, in aes_decrypt_with_iv
data = cipher.decrypt(data)
File "...\Python310\site-packages\Cryptodome\Cipher\_mode_cbc.py", line 246, in decrypt
raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size)
ValueError: Data must be padded to 16 byte boundary in CBC mode
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "...\electrum\keystore.py", line 68, in wrapper
return check_password_fn(self, password)
File "...\electrum\keystore.py", line 272, in check_password
self.get_private_key(pubkey, password)
File "...\electrum\keystore.py", line 291, in get_private_key
sec = pw_decode(self.keypairs[pubkey], password, version=self.pw_hash_version)
File "...\electrum\crypto.py", line 311, in pw_decode
plaintext_bytes = pw_decode_bytes(data, password, version=version)
File "...\electrum\crypto.py", line 268, in pw_decode_bytes
return _pw_decode_raw(data_bytes, password, version=version)
File "...\electrum\crypto.py", line 249, in _pw_decode_raw
raise InvalidPassword() from e
electrum.util.InvalidPassword: Incorrect password
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "...\electrum\gui\qt\console.py", line 254, in exec_command
result = eval(command, self.namespace, self.namespace)
File "<string>", line 1, in <module>
File "...\electrum\keystore.py", line 76, in wrapper
raise InvalidPassword("password given but keystore has no password") from e
electrum.util.InvalidPassword: password given but keystore has no password
```
- for an onchain backups, if the channel is with a
hardcoded trampoline, try first without gossip DB.
- for imported backups, fallback to gossip DB if we
fail to connect with the provided network address.
As the GUI allows saving such invoices, CLI should not break for these wallets.
Also note the pre-existing assert on the next line.
follow-up bf4455ef30
```
>>> list_invoices()
Traceback (most recent call last):
File "...\electrum\gui\qt\main_window.py", line 1506, in <lambda>
return lambda *args, **kwargs: f(method,
File "...\electrum\commands.py", line 191, in _run
result = fut.result()
File "...\Python310\lib\concurrent\futures\_base.py", line 446, in result
return self.__get_result()
File "...\Python310\lib\concurrent\futures\_base.py", line 391, in __get_result
raise self._exception
File "...\electrum\commands.py", line 154, in func_wrapper
return await func(*args, **kwargs)
File "...\electrum\commands.py", line 1188, in list_invoices
return [wallet.export_invoice(x) for x in l]
File "...\electrum\commands.py", line 1188, in <listcomp>
return [wallet.export_invoice(x) for x in l]
File "...\electrum\wallet.py", line 2405, in export_invoice
amount_sat = int(x.get_amount_sat())
ValueError: invalid literal for int() with base 10: '!'
```