Commit Graph

4611 Commits

Author SHA1 Message Date
SomberNight
3451140ce7 qt coins list: fix populating labels
follow-up e362d1aac4
2022-04-10 15:17:40 +02:00
ThomasV
5bd2524bfb follow-up #7748 2022-04-09 10:51:09 +02:00
ThomasV
877a9f553b Merge pull request #7748 from spesmilo/confirm_reverse_swaps
Confirm reverse swaps
2022-04-09 10:41:02 +02:00
ThomasV
3e6595ae98 Merge pull request #7756 from SomberNight/202204_qt_taskthread_cancel
qt taskthread cleaner shutdown
2022-04-09 10:38:06 +02:00
SomberNight
29c1106988 qt main_window: move TaskThread from wallet.thread to window.thread 2022-04-08 20:50:03 +02:00
SomberNight
428dff90f8 address_sync: include verifier in sync_state progress indicator 2022-04-08 20:36:45 +02:00
SomberNight
30650c524c address_sync: "up_to_date" now waits for SPV 2022-04-08 20:35:23 +02:00
SomberNight
a05ef140d6 address_sync: split off unconfirmed_tx from unverified_tx 2022-04-08 20:34:45 +02:00
SomberNight
837fc1606c address_sync: change up_to_date to be private; no lock needed to read
After some consideration I am fairly certain there is no need to take
wallet.lock in `is_up_to_date()`. Any caller that might want some kind
of guarantees re the value returned by is_up_to_date() would need to
enforce them itself by e.g. taking wallet.lock around its critical code
block. That is, even if is_up_to_date() itself takes the lock, between
the call returning and the caller reading the value there could still
have been a race.
Also, the GUI was directly accessing the field already.
2022-04-08 20:33:13 +02:00
SomberNight
214ac19f15 window.run_coroutine_from_thread: don't use wallet.thread
wallet.thread was serialising the fut.result() calls, so consider e.g.
- coro1 gets scheduled,
- wallet.thread waits on fut1.result()
- coro2 gets scheduled,
- coro2 finished with exception and wants to show an error popup,
-> wallet.thread is still waiting on fut1.result() before it looks at fut2.result
2022-04-07 20:20:30 +02:00
SomberNight
96c063028a qt TaskThread: implement cancellation of tasks, for cleaner shutdown
fixes https://github.com/spesmilo/electrum/issues/7750

Each task we schedule on `TaskThread` can provide an optional `cancel` method.
When stopping `TaskThread`, we call this `cancel` method on all tasks in the queue.
If the currently running task does not implement `cancel`, `TaskThread.stop` will block
until that task finishes.

Note that there is a significant change in behaviour here:
`ElectrumWindow.run_coroutine_from_thread` and `ElectrumWindow.pay_lightning_invoice`
previously serialised the execution of their coroutines via wallet.thread.
This is no longer the case: they will now schedule coroutines immediately.
So for example, the GUI now allows trying to pay multiple LN invoices "concurrently".
2022-04-07 19:51:58 +02:00
ThomasV
ad41f4aed0 trampoline legacy mpp: link to eclair issue 2022-04-07 19:50:30 +02:00
SomberNight
250795f137 verifier: small clean-up
this code runs in the interface's group, so it's confusing to call the network's methods
2022-04-04 20:55:47 +02:00
SomberNight
207600e00c transaction.py: TxOutpoint: nicer __str__ and __repr__
useful e.g. when TxOutpoint is used as key in a dict (and the dict is printed)
2022-04-01 21:31:50 +02:00
SomberNight
0226e7196d swaps: build index(es) for the swaps dict to avoid linear scanning 2022-04-01 21:30:41 +02:00
ThomasV
083205714c Qt: reorganize settings dialog 2022-04-01 20:20:04 +02:00
ThomasV
e362d1aac4 Qt: make display of lists more stable.
Use refresh_row() for address, utxo and contact lists.
Replace unneeded calls to update_tabs() with refresh_tabs()

Fix right-click menu after selecting multiple addresses.
2022-04-01 14:11:31 +02:00
ThomasV
f01197b6b5 Reverse swaps: Wait until funding tx is confirmed
- override with allow_instant_swaps option (Qt)
2022-04-01 14:05:01 +02:00
ThomasV
44d3b0bc61 Merge pull request #7724 from spesmilo/rbf_swap
bump fee of swap claim transactions
2022-04-01 13:56:05 +02:00
ThomasV
670f8dbe42 submarine_swaps: use prevout to determine if a txin is claiming a swap 2022-04-01 13:55:36 +02:00
ThomasV
1574e10869 follow-up 92c6d91157: remove paid item from request_list 2022-04-01 11:32:57 +02:00
SomberNight
7268fa55f2 config: abstract away mempool depth format str "%.1f MB from tip"
related: 4dd94172a6
(as that commit introduced depth targets that need more precision to display)
2022-03-31 22:50:31 +02:00
SomberNight
e36d7fed7d swaps: more precise tx size estimation for claim tx when RBF-ing 2022-03-31 20:55:11 +02:00
SomberNight
2b13576eb3 qt history tab: fix double-clicking inside collapsible items
Swaps (both reverse and forward) are displayed in the list as a tree, which can be
expanded/collapsed. When expanded, double-clicking on any of the children (regardless
of child being LN or onchain), was interacting with the incorrect item (the first few
items in the top-level list).

Consider `self.tx_item_from_proxy_row(idx.row())`.
`idx.row()` is probably a small int, e.g. `0`, and `tx_item_from_proxy_row` is just
getting that item from the top-level list.

Note that the right-click>"View ..." context menu behaves correctly, so prior to
this commit it was inconsistent with double-clicking.
2022-03-31 19:10:39 +02:00
SomberNight
357aaff582 swaps: when RBF-ing a forward swap tx, payment amt must not decrease 2022-03-30 19:01:57 +02:00
SomberNight
aa5172faa2 swaps: fix forward swap: lnworker.create_invoice is not async
follow-up cb39bbbd94
2022-03-30 17:42:12 +02:00
ThomasV
1364e7538a bump fee of swap claim transactions
Note: This adds a new field, spent_txid, to PartialTxOutput
2022-03-30 13:44:10 +02:00
SomberNight
4dd94172a6 config: fee slider: add more steps in mempool mode
closes https://github.com/spesmilo/electrum/issues/6474
2022-03-29 20:22:09 +02:00
SomberNight
68ba223ce1 qt ConfirmTxDialog: word-wrap error message text
e.g. this text:
"This transaction requires a higher fee, or it will not be propagated by your current server. Try to raise your transaction fee, or use a server with a lower relay fee."
is too long for a single line.
2022-03-29 20:15:52 +02:00
SomberNight
1810835fae lnchannel: get_capacity() should not raise when running with --offline
```
E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "...\electrum\electrum\gui\qt\channels_list.py", line 295, in do_update_rows
    field_map = self.format_fields(chan)
  File "...\electrum\electrum\gui\qt\channels_list.py", line 99, in format_fields
    capacity_str = self.parent.format_amount(chan.get_capacity(), whitespaces=True)
  File "...\electrum\electrum\lnchannel.py", line 481, in get_capacity
    return self.lnworker.lnwatcher.get_tx_delta(self.funding_outpoint.txid, self.cb.funding_address)
AttributeError: 'NoneType' object has no attribute 'get_tx_delta'
```
2022-03-29 18:30:55 +02:00
ThomasV
cb39bbbd94 lnworker: make calc_routing_hints_for_invoice and create_invoice non-async 2022-03-29 17:42:04 +02:00
SomberNight
ec98ef5aee hw ledger: sign_transaction: add progress indicator
related: https://github.com/spesmilo/electrum/issues/7516
2022-03-26 15:26:13 +01:00
SomberNight
69c5375cc5 prepare release 4.2.1 2022-03-24 15:59:14 +01:00
ThomasV
a15dac2b8c channel_establishment_flow: do not save wallet file backup in the background.
Instead, display a popup everytime, if the channel is not recoverable.
2022-03-24 14:55:45 +01:00
ThomasV
92c6d91157 Qt: on status changes, refresh item in invoice_list and request_list,
instead of calling update(), which repopulates the model.
2022-03-23 19:52:28 +01:00
ThomasV
d3476b6ba0 fix deadlock: self.lock should be taken before self.transaction_lock
(self.lock is taken in self.get_tx.height)
2022-03-23 19:27:49 +01:00
SomberNight
05649861c8 qt gui: more resilient startup: catch more exceptions, better fallback
fixes https://github.com/spesmilo/electrum/issues/7447

Consider this trace for 4.2.0:
```
Traceback (most recent call last):
  File "electrum/gui/qt/__init__.py", line 332, in start_new_window
  File "electrum/gui/qt/__init__.py", line 363, in _start_wizard_to_select_or_create_wallet
  File "electrum/gui/qt/installwizard.py", line 302, in select_storage
  File "electrum/util.py", line 504, in get_new_wallet_name
PermissionError: [Errno 1] Operation not permitted: '/Users/admin/Documents/Peach/MS'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "electrum/gui/qt/__init__.py", line 426, in main
  File "electrum/gui/qt/__init__.py", line 307, in wrapper
  File "electrum/gui/qt/__init__.py", line 349, in start_new_window
  File "electrum/util.py", line 504, in get_new_wallet_name
PermissionError: [Errno 1] Operation not permitted: '/Users/admin/Documents/Peach/MS'
```

Note that `get_new_wallet_name` (os.listdir) can raise OSError,
and we were calling that on the main entrypoint codepath without exception-handling.
We were also calling it in the fallback codepath without exception-handling.
i.e. the GUI errored out on every startup for affected users, and without CLI usage
it was not possible to recover.
2022-03-23 03:58:33 +01:00
SomberNight
25fee6a6be kivy: locale: set default language to English
This reverts 7cb11ceda4 (set default language to OS lang).
Some languages (e.g. CJK, Arabic) do not work at all with kivy due to font issues,
so we should never use those as default. It is easiest to just default to English for now.

related https://github.com/spesmilo/electrum/issues/2032
related https://github.com/spesmilo/electrum/issues/4618
related https://github.com/spesmilo/electrum/issues/7494
2022-03-22 17:20:33 +01:00
SomberNight
b91947e585 kivy: delete some dead code 2022-03-22 16:28:04 +01:00
ghost43
483fed42d8 Merge pull request #7727 from SomberNight/202203_qtcamera_preferences_crash
qt gui: (maybe fix) opening "Preferences" segfaults on macOS for some
2022-03-22 14:40:49 +00:00
SomberNight
5149ee02a5 wallet: fix delete_address removing too many transactions
See testcase:
- imported wallet with addr1 and addr2
- three txs: tx1 funds addr1, tx2 funds addr2, tx3 spends all
- if we rm addr1 from the wallet,
  - previously both tx1 and tx3 was removed (as tx3 is a child of tx1)
  - now only tx1 is removed (tx3 still relates to the wallet via addr2)

fixes https://github.com/spesmilo/electrum/issues/7587
2022-03-21 19:30:08 +01:00
SomberNight
10b2d705a1 qt chan details dlg: break stats into 2 cols, add local/remote balance 2022-03-21 17:49:08 +01:00
SomberNight
d8e2582889 qt gui: (maybe fix) opening "Preferences" segfaults on macOS for some
see https://github.com/spesmilo/electrum/issues/7725
related https://github.com/Electron-Cash/Electron-Cash/pull/1545
2022-03-21 15:50:28 +01:00
SomberNight
e00c998df3 transaction: TxInput.witness_elements() to return [] if not segwit
Previously it would raise:
```
>>> import electrum
>>> tx = electrum.transaction.tx_from_any("0200000001d945b6b076ad7858f7a2227374a42ada71582b1d558fde9ece4bf6c9395c67ca000000006a473044022034867c61623a147dbe7e8541da1086ec8691d4f39181deeba4be70559e26734d02205c0288c96ae6950a0687c0d8c06f9cd343362e6a174cd4c66cfc2abd2278aed801210330fb51ac7b556a599a05c2b8670e79008406e4c0b7e46d4a522ad01804f25dbbfdffffff02389d0700000000001976a9146d687bece6d502519ce5317e25f48da60a52ca8f88ac20a1070000000000220020a948d7fa6abbb97e31779ae54383012b413d53821c7fd394900f6b443c61deeee82a1800")
>>> tx.inputs()[0].witness_elements()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/wspace/electrum/electrum/transaction.py", line 257, in witness_elements
    vds.write(self.witness)
  File "/home/user/wspace/electrum/electrum/transaction.py", line 279, in write
    assert isinstance(_bytes, (bytes, bytearray))
AssertionError
```
2022-03-20 16:55:36 +01:00
SomberNight
3e42f2f33d kivy: fix cpfp dialog: qt not available on android
(and the imports are unused.)

fixes https://github.com/spesmilo/electrum/issues/7723
2022-03-19 00:02:54 +01:00
SomberNight
a92dede490 lnpeer: some rework of error/warning message handling
- rm the `_get_channel_ids` abstraction as each of its usages needs subtle differences.
  Some code duplication is preferable in this case.
- raise exceptions in `wait_for_message`, so that callers such as the GUI can show user-feedback
- on_error/on_warning were dropping messages with temp_chan_ids if they were not stored in
  `temp_id_to_id` - which was only done once the mapping was known (so the normal chan_id was known).
  To fix this, we now store temp_chan_ids into `temp_id_to_id` early.
- `schedule_force_closing` only works if the chan_id is already in `channels`

related:
https://github.com/spesmilo/electrum/pull/7645 (and related commits)

-----

example before commit:
```
D/P | lnpeer.Peer.[LNWallet, 03933884aa-3b53e4ab] | Sending OPEN_CHANNEL
D/P | lnpeer.Peer.[LNWallet, 03933884aa-3b53e4ab] | Received ERROR
I/P | lnpeer.Peer.[LNWallet, 03933884aa-3b53e4ab] | remote peer sent error [DO NOT TRUST THIS MESSAGE]: invalid funding_satoshis=10000 sat (min=400000 sat max=1500000000 sat)

E | gui.qt.main_window.[test_segwit_2] | Could not open channel
Traceback (most recent call last):
  File "...\electrum\electrum\util.py", line 1160, in wrapper
    return await func(*args, **kwargs)
  File "...\electrum\electrum\lnpeer.py", line 661, in wrapper
    return await func(self, *args, **kwargs)
  File "...\electrum\electrum\lnpeer.py", line 742, in channel_establishment_flow
    payload = await self.wait_for_message('accept_channel', temp_channel_id)  #
  File "...\electrum\electrum\lnpeer.py", line 315, in wait_for_message
    name, payload = await asyncio.wait_for(q.get(), LN_P2P_NETWORK_TIMEOUT)
  File "...\Python39\lib\asyncio\tasks.py", line 468, in wait_for
    await waiter
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "...\Python39\lib\asyncio\tasks.py", line 492, in wait_for
    fut.result()
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "...\electrum\electrum\gui\qt\util.py", line 914, in run
    result = task.task()
  File "...\electrum\electrum\gui\qt\main_window.py", line 1875, in task
    return self.wallet.lnworker.open_channel(
  File "...\electrum\electrum\lnworker.py", line 1075, in open_channel
    chan, funding_tx = fut.result()
  File "...\Python39\lib\concurrent\futures\_base.py", line 445, in result
    return self.__get_result()
  File "...\Python39\lib\concurrent\futures\_base.py", line 390, in __get_result
    raise self._exception
  File "...\electrum\electrum\util.py", line 1160, in wrapper
    return await func(*args, **kwargs)
  File "...\electrum\electrum\lnworker.py", line 1006, in _open_channel_coroutine
    chan, funding_tx = await asyncio.wait_for(coro, LN_P2P_NETWORK_TIMEOUT)
  File "...\Python39\lib\asyncio\tasks.py", line 494, in wait_for
    raise exceptions.TimeoutError() from exc
asyncio.exceptions.TimeoutError
```

example after commit:
```
D/P | lnpeer.Peer.[LNWallet, 03933884aa-ff3a866f] | Sending OPEN_CHANNEL
D/P | lnpeer.Peer.[LNWallet, 03933884aa-ff3a866f] | Received ERROR
I/P | lnpeer.Peer.[LNWallet, 03933884aa-ff3a866f] | remote peer sent error [DO NOT TRUST THIS MESSAGE]: invalid funding_satoshis=10000 sat (min=400000 sat max=1500000000 sat). chan_id=124ca21fa6aa2993430ad71f465f0d44731ef87f7478e4b31327e4459b5a3988
E | lnworker.LNWallet.[test_segwit_2] | Exception in _open_channel_coroutine: GracefulDisconnect('remote peer sent error [DO NOT TRUST THIS MESSAGE]: invalid funding_satoshis=10000 sat (min=400000 sat max=1500000000 sat)')
Traceback (most recent call last):
  File "...\electrum\electrum\util.py", line 1160, in wrapper
    return await func(*args, **kwargs)
  File "...\electrum\electrum\lnworker.py", line 1006, in _open_channel_coroutine
    chan, funding_tx = await asyncio.wait_for(coro, LN_P2P_NETWORK_TIMEOUT)
  File "...\Python39\lib\asyncio\tasks.py", line 481, in wait_for
    return fut.result()
  File "...\electrum\electrum\lnpeer.py", line 673, in wrapper
    return await func(self, *args, **kwargs)
  File "...\electrum\electrum\lnpeer.py", line 755, in channel_establishment_flow
    payload = await self.wait_for_message('accept_channel', temp_channel_id)
  File "...\electrum\electrum\lnpeer.py", line 326, in wait_for_message
    raise GracefulDisconnect(
electrum.interface.GracefulDisconnect: remote peer sent error [DO NOT TRUST THIS MESSAGE]: invalid funding_satoshis=10000 sat (min=400000 sat max=1500000000 sat)
I/P | lnpeer.Peer.[LNWallet, 03933884aa-ff3a866f] | Disconnecting: GracefulDisconnect()
```
2022-03-17 17:52:38 +01:00
SomberNight
d154e368f1 wallet: fix clear_requests and clear_invoices
these are StoredDicts, subdicts in wallet_db.data, so reassigning the name does not work
2022-03-16 12:51:03 +01:00
SomberNight
f94f142605 prepare release 4.2.0 2022-03-15 15:06:28 +01:00
SomberNight
15643b7951 qt init: make sure wallet file parsing errors are shown in gui
Some exceptions were just killing the gui silently and not even logged.

E.g.:
```
E | gui.qt.ElectrumGui | error loading wallet (or creating window for it)
Traceback (most recent call last):
  File "/opt/electrum/electrum/gui/qt/__init__.py", line 433, in main
    if not self.start_new_window(path, self.config.get('url'), app_is_starting=True):
  File "/opt/electrum/electrum/gui/qt/__init__.py", line 307, in wrapper
    return func(self, *args, **kwargs)
  File "/opt/electrum/electrum/gui/qt/__init__.py", line 332, in start_new_window
    wallet = self._start_wizard_to_select_or_create_wallet(path)
  File "/opt/electrum/electrum/gui/qt/__init__.py", line 377, in _start_wizard_to_select_or_create_wallet
    db = WalletDB(storage.read(), manual_upgrades=False)
  File "/opt/electrum/electrum/wallet_db.py", line 73, in __init__
    self.load_data(raw)
  File "/opt/electrum/electrum/wallet_db.py", line 104, in load_data
    self._after_upgrade_tasks()
  File "/opt/electrum/electrum/wallet_db.py", line 202, in _after_upgrade_tasks
    self._load_transactions()
  File "/opt/electrum/electrum/util.py", line 439, in <lambda>
    return lambda *args, **kw_args: do_profile(args, kw_args)
  File "/opt/electrum/electrum/util.py", line 435, in do_profile
    o = func(*args, **kw_args)
  File "/opt/electrum/electrum/wallet_db.py", line 1310, in _load_transactions
    self.data = StoredDict(self.data, self, [])
  File "/opt/electrum/electrum/json_db.py", line 79, in __init__
    self.__setitem__(k, v)
  File "/opt/electrum/electrum/json_db.py", line 44, in wrapper
    return func(self, *args, **kwargs)
  File "/opt/electrum/electrum/json_db.py", line 97, in __setitem__
    v = self.db._convert_dict(self.path, key, v)
  File "/opt/electrum/electrum/wallet_db.py", line 1361, in _convert_dict
    v = dict((k, SwapData(**x)) for k, x in v.items())
```
2022-03-15 14:23:30 +01:00
SomberNight
3771553a2c crash reporter: if disabled via config, make sure EEQueue is flushed
If the user had `config.get("show_crash_reporter")==False`, they would
never get to see excs collected via `send_exception_to_crash_reporter(exc)`.

E.g.:
```
E | gui.qt.ElectrumGui | error loading wallet (or creating window for it)
Traceback (most recent call last):
  File "/opt/electrum/electrum/gui/qt/__init__.py", line 433, in main
    if not self.start_new_window(path, self.config.get('url'), app_is_starting=True):
  File "/opt/electrum/electrum/gui/qt/__init__.py", line 307, in wrapper
    return func(self, *args, **kwargs)
  File "/opt/electrum/electrum/gui/qt/__init__.py", line 332, in start_new_window
    wallet = self._start_wizard_to_select_or_create_wallet(path)
  File "/opt/electrum/electrum/gui/qt/__init__.py", line 377, in _start_wizard_to_select_or_create_wallet
    db = WalletDB(storage.read(), manual_upgrades=False)
  File "/opt/electrum/electrum/wallet_db.py", line 73, in __init__
    self.load_data(raw)
  File "/opt/electrum/electrum/wallet_db.py", line 104, in load_data
    self._after_upgrade_tasks()
  File "/opt/electrum/electrum/wallet_db.py", line 202, in _after_upgrade_tasks
    self._load_transactions()
  File "/opt/electrum/electrum/util.py", line 439, in <lambda>
    return lambda *args, **kw_args: do_profile(args, kw_args)
  File "/opt/electrum/electrum/util.py", line 435, in do_profile
    o = func(*args, **kw_args)
  File "/opt/electrum/electrum/wallet_db.py", line 1310, in _load_transactions
    self.data = StoredDict(self.data, self, [])
  File "/opt/electrum/electrum/json_db.py", line 79, in __init__
    self.__setitem__(k, v)
  File "/opt/electrum/electrum/json_db.py", line 44, in wrapper
    return func(self, *args, **kwargs)
  File "/opt/electrum/electrum/json_db.py", line 97, in __setitem__
    v = self.db._convert_dict(self.path, key, v)
  File "/opt/electrum/electrum/wallet_db.py", line 1361, in _convert_dict
    v = dict((k, SwapData(**x)) for k, x in v.items())
```
2022-03-15 13:39:33 +01:00