Commit Graph

697 Commits

Author SHA1 Message Date
SomberNight
6ac3f84095 wallet/lnworker/etc: add sanity checks to start_network methods
related: https://github.com/spesmilo/electrum/issues/8301
2023-04-17 16:56:57 +00:00
SomberNight
db4943ff86 wallet.get_full_history: more consistent sort order
before:
```
>>> [print(wallet.get_tx_status(txid, wallet.adb.get_tx_height(txid))) for txid in list(wallet.get_full_history())[-10:]]
(7, '2023-04-04 16:13')
(7, '2023-04-04 16:13')
(7, '2023-04-04 16:13')
(7, '2023-04-04 16:13')
(0, 'Unconfirmed [20. sat/b, 0.00 MB]')
(2, 'in 2 blocks')
(3, 'Local [180.4 sat/b]')
(3, 'Local [180.2 sat/b]')
(2, 'in 2016 blocks')
(0, 'Unconfirmed [180. sat/b, 0.00 MB]')
```

after:
```
>>> [print(wallet.get_tx_status(txid, wallet.adb.get_tx_height(txid))) for txid in list(wallet.get_full_history())[-10:]]
(7, '2023-04-04 16:13')
(7, '2023-04-04 16:13')
(7, '2023-04-04 16:13')
(7, '2023-04-04 16:13')
(0, 'Unconfirmed [20. sat/b, 0.00 MB]')
(0, 'Unconfirmed [180. sat/b, 0.00 MB]')
(2, 'in 2016 blocks')
(2, 'in 2 blocks')
(3, 'Local [180.4 sat/b]')
(3, 'Local [180.2 sat/b]')
```
2023-04-04 18:32:53 +00:00
SomberNight
a30cda4ebd lnutil: test ImportedChannelBackupStorage.from_bytes
regression test - we should not inadvertently break deserialising existing backups
2023-03-19 19:15:44 +00:00
SomberNight
f2dc651c9b Qt history list: Ctrl+F filter to work for "Short ID" (scid) 2023-03-10 14:03:57 +00:00
SomberNight
ec889b8c3f wallet: fix import_requests, and mention quirk re preimages 2023-03-03 16:35:34 +00:00
SomberNight
a1a1fae4cc invoices.py: small clean-up 2023-03-03 16:02:19 +00:00
SomberNight
d11237d6a1 lnworker: start watching already redeemed chans if txs are missing
This fixes a bug where if one runs `wallet.clear_history()` they would see exceptions later:
```
Traceback (most recent call last):
  File "/home/user/wspace/electrum/electrum/gui/qt/main_window.py", line 866, in timer_actions
	self.update_wallet()
  File "/home/user/wspace/electrum/electrum/gui/qt/main_window.py", line 1021, in update_wallet
	self.update_tabs()
  File "/home/user/wspace/electrum/electrum/gui/qt/main_window.py", line 1033, in update_tabs
	self.utxo_list.update()
  File "/home/user/wspace/electrum/electrum/gui/qt/utxo_list.py", line 103, in update
	self.refresh_row(name, idx)
  File "/home/user/wspace/electrum/electrum/gui/qt/utxo_list.py", line 124, in refresh_row
	parents = self.wallet.get_tx_parents(txid)
  File "/home/user/wspace/electrum/electrum/wallet.py", line 885, in get_tx_parents
	result.update(self.get_tx_parents(_txid))
  File "/home/user/wspace/electrum/electrum/wallet.py", line 881, in get_tx_parents
	for i, txin in enumerate(tx.inputs()):
AttributeError: 'NoneType' object has no attribute 'inputs'
```
This is related to the privacy analysis, which assumes that for each tx item in the history list
we should have the raw tx in the db. This is no longer true after wallet.clear_history(), if
the wallet has certain LN channels. E.g. an already redeemed channel that was local-force-closed,
as that closing tx is not related to the wallet directly.

In commit 3541ecb576, we decided not to watch already redeemed channels.
This is potentially good for e.g. privacy, as the server would otherwise see us subscribe to that chan.
However it means that after running wallet.clear_history() txs related to the channel but not to the
wallet won't be re-downloaded.

Instead, now if there are missing txs for a redeemed channel, we start watching it, hence the
synchronizer will re-downloaded the txs.
2023-03-01 16:20:42 +00:00
ThomasV
719b468eee Refresh bolt11 routing hints when channel liquidity changes:
- wallet_db update: separate Invoices and Requests.
 - do not store bolt11 invoice in Request
2023-02-28 15:33:17 +01:00
ThomasV
72fb43f950 lnworker: do not assume MPP in num_sats_can_receive 2023-02-25 12:23:34 +01:00
SomberNight
373db76ac9 util: kill bh2u
no longer useful, and the name is so confusing...
2023-02-17 11:43:11 +00:00
ThomasV
768eb35c86 follow-up 5d9678a269 2023-01-24 14:45:55 +01:00
ThomasV
062051b530 lnworker: store onchain default labels in a cache 2023-01-23 10:48:25 +01:00
ThomasV
5d9678a269 lnworker: extend swap label only if we are still watching the address
Without this, old swap transactions for which we have deleted the
channel are incorrectly labeled.
2023-01-21 12:39:19 +01:00
ThomasV
b9393b0603 Support scid alias:
- save remote alias for use in invoices
 - derive local alias from wallet xpub
 - send channel_type without the option_scid_alias bit
   (apparently LND does not like it)
2023-01-13 15:47:30 +01:00
ThomasV
c109d5e722 lnwire: update csv files with recent BOLTs
Note: there are no more optional fields in msgdata, per f068dd0d8d
2023-01-13 12:50:48 +01:00
ThomasV
d95f3e5622 Use different trampoline bits than Eclair. Fixes #8141 2023-01-13 12:48:13 +01:00
ThomasV
d70a574780 Increase trampoline fee if we receive TEMPORARY_CHANNEL_FAILURE
Sometimes the trampoline node fails to send a payment and returns
TEMPORARY_CHANNEL_FAILURE, while it succeeds with a higher trampoline
fee. My guess is that the initial fee was not sufficient to try
all routes, and that a higher fee allows to use extra routes. I
suppose it would make more sense if the trampoline node returned
TRAMPOLINE_FEE_INSUFFICIENT in that case.
2023-01-13 11:02:19 +01:00
accumulator
6e536d2d91 add invoice status to invoice_status callback (#8020)
* add invoice status to invoice_status callback

* debug statement fails tests

* removed commented lines, added progress/attempt counter comment in lnworker.pay_to_node,
and update the invoice_status event handler in qeinvoicelistmodel.py
2022-10-21 16:45:12 +00:00
ThomasV
8867387847 lnworker: fix stuck payment loop (fixes #7995)
If the short_channel_id of a channel update received
with update_fail_htlc does not match the channel in
our route, blacklist the channel in our route.
2022-10-04 10:51:18 +02:00
ThomasV
20bcb15480 Factorize code in create_routes_for_payment.
Calling suggest_splits with exclude_single_part_payments=False
2022-09-20 13:55:22 +02:00
ThomasV
ead886781a create_routes_for_payment: fix 'we atomically loop'
Before this commit, partial results were yielded before we had
examined the whole split configuration.

I think the correct behaviour is to create all the routes for the
current configuration, then to yield them. If there is an exception,
we should try the next one.
2022-09-20 12:52:36 +02:00
ThomasV
5e77886b98 trampoline MPP: handle direct payment to trampoline node 2022-09-20 11:44:23 +02:00
ThomasV
478046289a follow-up c6f940d092 2022-09-20 10:55:19 +02:00
ThomasV
2af59e32b2 lnworker: define use_trampoline() for code clarity 2022-09-19 17:43:13 +02:00
ThomasV
68bf714ae6 Trampoline: Remember failed routes (fixes #7967).
Upon receiving UNKNOWN_NEXT_PEER, TEMPORARY_NODE_FAILURE
or TEMPORARY_CHANNEL_FAILURE, remember the trampoline route
that was used, and try other routes before raising the
trampoline fee.

Before this commit, we used to raise the trampoline fee
upon receiving any error message, in order to ensure
termination of the payment loop.

Note that we will still retry failing routes after we have
raised the trampoline fee. This choice is questionable, it
is unclear if doing so significantly increases the probability
of success.

Tests: add a test for trampoline handling of UNKNOWN_NEXT_PEER
2022-09-19 16:42:46 +02:00
ThomasV
2c57a8c394 lnworker: fix maybe_raise_trampoline_level.
That function was a no-op due to wrong indentation level
2022-09-03 18:32:05 +02:00
ThomasV
c6f940d092 trampoline: less verbose, do not log routes that are not tried 2022-09-03 18:24:58 +02:00
ThomasV
14e96f4d53 Index request by ID instead of receiving address.
Replace get_key_for_outgoing_invoice, get_key_for_incoming_request
with Invoice.get_id()

When a new request is created, reuse addresses of expired requests (fixes #7927)

The API is changed for the following commands:
 get_request, get_invoice,
 list_requests, list_invoices,
 delete_request, delete_invoice
2022-09-02 10:58:11 +02:00
SomberNight
42f2a3da31 Qt pay_lightning_invoice: handle NoDynamicFeeEstimates
`wallet.make_unsigned_transaction` can raise NotEnoughFunds or NoDynamicFeeEstimates.
These are "expected" exceptions that need to be handled or worked around. Added a note
of this in the docstring now.

We now handle NoDynamicFeeEstimates by allowing a static fallback fee in
`wallet.can_pay_onchain` and `lnworker.suggest_funding_amount`. It should be
fine to have a static fallback in these cases, as the user still has a chance
to set their own fee later in the flow.
(though ofc the static fallback might be too high in some mempool conditions,
in which case e.g. can_pay_onchain might return a false-negative, but this
is still an improvement over raising I believe)

fixes https://github.com/spesmilo/electrum/issues/5784
2022-08-30 11:46:52 +00:00
ThomasV
1f403d1ca1 remove support for channels without static remote pubkey 2022-08-16 08:48:59 +02:00
SomberNight
3541ecb576 lnwatcher: don't add REDEEMED channels
Previously lnworker called LNWatcher.add_channel() on these, and then LNWatcher itself decided to unwatch them.

-----

note: motivation related to https://github.com/spesmilo/electrum/pull/7932#discussion_r945755584 ,
where I have legacy (pre-staticremotekey) redeemed channels in a wallet.
Tracebacks:
```
E/W | lnwatcher.LNWalletWatcher.[default_wallet-LNW] | Exception in do_breach_remedy: AssertionError()
Traceback (most recent call last):
  File "...\electrum\electrum\util.py", line 1235, in wrapper
    return await func(*args, **kwargs)
  File "...\electrum\electrum\lnwatcher.py", line 443, in do_breach_remedy
    sweep_info_dict = chan.sweep_ctx(closing_tx)
  File "...\electrum\electrum\lnchannel.py", line 264, in sweep_ctx
    our_sweep_info = self.create_sweeptxs_for_our_ctx(ctx)
  File "...\electrum\electrum\lnchannel.py", line 253, in create_sweeptxs_for_our_ctx
    return create_sweeptxs_for_our_ctx(chan=self, ctx=ctx, sweep_address=self.sweep_address)
  File "...\electrum\electrum\lnchannel.py", line 757, in sweep_address
    assert self.is_static_remotekey_enabled()
AssertionError
```
```
E/W | lnwatcher.LNWalletWatcher.[default_wallet-LNW] | Exception in trigger_callbacks: AssertionError()
Traceback (most recent call last):
  File "...\electrum\electrum\util.py", line 1235, in wrapper
    return await func(*args, **kwargs)
  File "...\electrum\electrum\lnwatcher.py", line 208, in trigger_callbacks
    await callback()
  File "...\electrum\electrum\lnwatcher.py", line 225, in check_onchain_situation
    keep_watching = await self.do_breach_remedy(funding_outpoint, closing_tx, spenders)
  File "...\electrum\electrum\util.py", line 1235, in wrapper
    return await func(*args, **kwargs)
  File "...\electrum\electrum\lnwatcher.py", line 443, in do_breach_remedy
    sweep_info_dict = chan.sweep_ctx(closing_tx)
  File "...\electrum\electrum\lnchannel.py", line 264, in sweep_ctx
    our_sweep_info = self.create_sweeptxs_for_our_ctx(ctx)
  File "...\electrum\electrum\lnchannel.py", line 253, in create_sweeptxs_for_our_ctx
    return create_sweeptxs_for_our_ctx(chan=self, ctx=ctx, sweep_address=self.sweep_address)
  File "...\electrum\electrum\lnchannel.py", line 757, in sweep_address
    assert self.is_static_remotekey_enabled()
AssertionError
```
2022-08-15 13:56:44 +00:00
ThomasV
a5965933d2 Fix CTNs in should_be_closed_due_to_expiring_htlcs (fixes #7906).
Also fix sending too many fee updates.
Rename lnworker.on_channel_update, that name was misleading.
2022-08-02 18:00:39 +02:00
ThomasV
b5617ec0fd lnworker: get_channel_objects method to be used by GUI 2022-07-20 21:07:13 +02:00
ThomasV
af1fb1ae9f remove_channel_backup: a channel backup might be in both lists 2022-07-20 17:00:57 +02:00
ThomasV
f5abd4f1d1 add command line for rebalancing channels 2022-07-13 10:14:34 +02:00
ThomasV
9b075ba187 get_node_alias: allow node_id prefixes for channel backups 2022-07-11 11:30:02 +02:00
ThomasV
36a6fd6311 request_force_close_from_backup:
- 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.
2022-07-11 11:16:43 +02:00
SomberNight
1b6706bed6 replace some erroneous usages of IntFlag with IntEnum 2022-06-29 18:07:03 +02:00
SomberNight
9f1da8422b qt LightningTxDialog: (fix regression) show fee for ln payments
follow-up e1d34300e5
2022-06-29 18:02:55 +02:00
SomberNight
2511d8118c lnworker.get_lightning_history(&get_payment_value): rm failing assert
follow-up e1d34300e5
follow-up dc15d59fcf

```
Traceback (most recent call last):
  File ".../electrum/gui/qt/main_window.py", line 910, in timer_actions
    self.update_wallet()
  File ".../electrum/gui/qt/main_window.py", line 1068, in update_wallet
    self.update_tabs()
  File ".../electrum/gui/qt/main_window.py", line 1075, in update_tabs
    self.history_model.refresh('update_tabs')
  File ".../electrum/util.py", line 439, in <lambda>
    return lambda *args, **kw_args: do_profile(args, kw_args)
  File ".../electrum/util.py", line 435, in do_profile
    o = func(*args, **kw_args)
  File ".../electrum/gui/qt/history_list.py", line 275, in refresh
    transactions = wallet.get_full_history(
  File ".../electrum/util.py", line 439, in <lambda>
    return lambda *args, **kw_args: do_profile(args, kw_args)
  File ".../electrum/util.py", line 435, in do_profile
    o = func(*args, **kw_args)
  File ".../electrum/wallet.py", line 1109, in get_full_history
    lightning_history = self.lnworker.get_lightning_history() if self.lnworker and include_lightning else {}
  File ".../electrum/lnworker.py", line 839, in get_lightning_history
    assert direction == PaymentDirection.FORWARDING
AssertionError
```
2022-06-29 16:12:47 +02:00
ThomasV
dc15d59fcf get_payment_value: rm failing assert 2022-06-29 13:33:04 +02:00
SomberNight
cafd5c4af0 lnworker.add_request: force keyword args
and change type-hint to reflect that fallback_address can be None
2022-06-22 02:26:54 +02:00
ThomasV
dbf055de9a EventListener class to handle callbacks
and QtEventListener for Qt
2022-06-22 02:07:46 +02:00
ThomasV
e1d34300e5 lnworker: get_payment_value
- the detection of self-payments was using the length
   of the htlc list, incorrectly categorizing all MPPs.
 - the fee for self-payments was not correctly computed.
2022-06-16 21:02:34 +02:00
ThomasV
cfb6ab6822 Trampoline: always increase fees, to ensure we do not get stuck in a loop.
Also handle TEMPORARY_CHANNEL_FAILURE, which is sometimes returned by Eclair.
2022-06-15 19:18:04 +02:00
ThomasV
9fe93524b7 Index lightning requests with rhash instead of onchain address.
get_unused_addresses() has been broken since #7730, because
addresses are considered as permanently used if they are in
the list of keys of receive_requests. This is true even if
an address is used as fallback for a lightning payment. This
means that the number of lightning payments we can receive
is constrained by the gap limit.

If a payment succeeds off-chain, we want to be able to reuse
its fallback address in other requests (this does not reduce
privacy, because invoices already share the same public key).

This implies that we should not use the onchain address as key
for lightning-enabled requests in wallet.receive_requests. If
we did, paid invoices would be overwritten when the address is
reused. That is the reason for the wallet_db upgrade.

Related: a3faf85e3c
2022-06-15 18:44:52 +02:00
ThomasV
adb5b6213b follow-up a3faf85e3c 2022-06-14 20:33:19 +02:00
ThomasV
a3faf85e3c wallet:
- add new index: requests_rhash_to_key (fixes #7845)
 - when creating a request, do not save its description in labels.
   Instead, return it as default value in wallet.get_label_by_rhash
lnworker:
  - rename 'payments' to 'payment_info'
  - add note to delete_payment_info
commands: rename 'rmrequest' to 'delete_request'
2022-06-14 13:39:18 +02:00
ThomasV
c316d406db unconfirmed swaps: revert label change (follow-up 599ad1c017) 2022-06-13 10:37:25 +02:00
ThomasV
599ad1c017 lnworker: get_onchain_history does not need to be online anymore 2022-06-13 10:26:07 +02:00