Commit Graph

426 Commits

Author SHA1 Message Date
SomberNight
659d6890d9 wallet.get_request_URI: rm code duplication 2022-08-11 13:07:56 +00:00
SomberNight
bd2ca30f95 kivy: fix creating dust amount receive requests
fixes https://github.com/spesmilo/electrum/issues/7928
2022-08-11 12:38:46 +00:00
SomberNight
ea5c49b3ab wallet.delete_request(key): piggyback on get_request(key)
So that the two methods are consistent with each other.

As concrete motivation, see e.g.
- how the `getrequest(key)` command calls `wallet.get_request(key)`, and
- the `delete_request(address)` command calls `wallet.delete_request(address)`
2022-08-10 23:48:44 +02:00
SomberNight
0c81dc13a0 wallet: rm confusing get_request_by_address method
The _receive_requests dict is keyed by either 'address' or 'rhash' (see get_key_for_receive_request):
- 'rhash' is used if `req.lightning_invoice is not None`
- address is used otherwise

The `get_request_by_address` method was quite error-prone: it only worked for requests that had an LN part...
2022-08-10 23:23:00 +02:00
SomberNight
396a68cb58 wallet: delete_{invoice,request}: add "write_to_disk=True" param
to support faster batch-deletion
2022-08-10 22:50:23 +02:00
SomberNight
7b095158bf wallet: add get_label_for_address, and make get_label private
fixes https://github.com/spesmilo/electrum/issues/7919

In the past, when creating payment requests, we keyed them by on-chain address,
and set/saved the msg of the request as label for the address.
Many places in the code were calling wallet.get_label(addr) with the expectation that
relevant payment requests are found and their message/description (if any) is considered.

wallet.get_label(key) is now made private, and instead the explicit non-polymorphic
wallet.get_label_for_{address,rhash,txid} alternatives should be used.
2022-08-09 17:21:14 +02:00
SomberNight
73ba00d7dd wallet.restore_wallet_from_text: support creating wallet in-memory 2022-08-08 16:34:04 +02:00
ThomasV
a59c8797dc wallet: write to disk in create_request 2022-07-22 17:01:46 +02:00
SomberNight
ed65f335bd wallet_db upgrade: fix possible corruption of invoice amounts
see https://github.com/spesmilo/electrum/pull/7774
2022-07-15 18:26:13 +02:00
SomberNight
d067e0e314 wallet: make "invoices" and "receive_requests" private
Other modules should use getters such as "get_request(key)" or "get_unpaid_requests()",
direct access is error-prone.
2022-07-12 15:46:47 +02:00
SomberNight
056de017f0 wallet: use get_request(addr) instead of receive_requests[addr]
since "invoice unification", requests are often keyed by rhash
2022-07-12 15:38:54 +02:00
SomberNight
2c73e7f854 wallet: (regression) fix get_spendable_coins when "domain" arg is given
`get_spendable_coins` was ignoring the "domain" param, and returning utxos for the whole wallet
2022-07-11 16:18:38 +02:00
ThomasV
9ae0e5bffc remove lightning parameter from wallet.create_request 2022-07-11 13:52:13 +02:00
ThomasV
88b2dc3589 show onchain address of request in CLI. Fixes #7886 2022-07-11 11:35:21 +02:00
SomberNight
9b8750b9cc wallet.export_invoice: should support onchain invoice with "!" (max) amount
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: '!'
```
2022-07-10 16:26:20 +02:00
SomberNight
68581ce80a invoices: fix type hint for get_address() 2022-07-10 16:08:02 +02:00
SomberNight
9c5277c9a1 wallet: rm get_onchain_request_status; just use is_onchain_invoice_paid
There is some duplication between `wallet.get_onchain_request_status` and `wallet.is_onchain_invoice_paid`
(both in terms of code, and conceptually). `get_onchain_request_status` is used for incoming invoices (receive requests),
and `is_onchain_invoice_paid` is used for outgoing invoices. I think `get_onchain_request_status` existed first,
but as it uses txi/txo, it only works for ismine addresses, so `is_onchain_invoice_paid` was added later
(along with a `get_prevouts_by_scripthash` and corresponding new persisted data structure) to handle the non-ismine
addresses corresponding to outgoing invoices.

I think we could just merge the two functions together... (?)
and this PR does that.
2022-07-09 03:32:33 +02:00
SomberNight
c463f5e23d password unification refactor: move methods from wallet to daemon
Note in particular that check_password_for_directory was not safe to use while the daemon had wallets loaded,
as the same file would have two corresponding Wallet() instances in memory. This was specifically handled in
the kivy GUI, on the caller side, by stopping-before and reloading-after the wallets; but it was dirty to
have the caller handle this.
2022-07-06 19:57:27 +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
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
7df24f0adf fix typo 2022-06-14 17:14:02 +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
7d5125c935 lnwatcher: fix tx replacement and notifications
- revert the logic of do_breach_remedy to what it was
   before 0ca3d66d15,
   but now calling self.maybe_redeem unconditionally.
 - replace mempool transactions only if the fee increases
 - do not notify the GUI if a local tx is replaced
 - delete labels when replacing
2022-06-12 14:28:11 +02:00
SomberNight
29d8d8de26 wallet: (fix) cannot just piggyback on adb.is_up_to_date()
The wallet needs its own up_to_date logic:
- the adb being up_to_date means all its addresses are synced
- but an HD wallet might decide to roll the gap limit and generate new addresses
  - the adb does not know about this...
  - the wallet should be considered *not* up_to_date
- relatedly, it is now the wallet that decides to reset the network request counters

- note that wallet.main() was never cleaned up previously.
  - now wallet gets its own taskgroup, which is cleaned up in wallet.stop.

Follow-up to adb refactor: 121d8732f1
2022-06-10 18:55:55 +02:00
ThomasV
d81610b2e1 wallet: filter non-wallet transactions before rebroadcasting event 2022-06-10 13:07:53 +02:00
ThomasV
6e7ffa29ae Move address_is_old to AddressSynchronizer.
Cache local_height at that level instead of wallet.synchronize
2022-06-10 13:07:53 +02:00
ThomasV
c47057b484 Move get_wallet_delta to wallet class, because it requires wallet.is_mine
Do not call it in AddressSynchronizer.get_tx_fee
2022-06-10 13:07:53 +02:00
ThomasV
151500fb72 follow-up afa2ed1fe285886fdd087aa8b1e303e2634d9098 2022-06-10 13:07:53 +02:00
ThomasV
121d8732f1 Persist LNWatcher transactions in wallet file:
- separate AddressSynchronizer from Wallet and LNWatcher
 - the AddressSynchronizer class is referred to as 'adb' (address database)
 - Use callbacks to replace overloaded methods
2022-06-10 13:07:53 +02:00
ThomasV
5d659cda0e improve channel_funding_sat suggestion. add min_amount parameter to new_channel_dialog 2022-05-22 17:18:28 +02:00
ThomasV
53151244e2 LNWorker: Add suggest_rebalance methods for sending and receiving.
These methods return a list of channels that can be rebalanced,
in order to receive or send a given amount.

Also add 'channels' parameter to submarine swaps.
Previously, swaps were not considering which channel to use.

When we do not have liquidity to pay an invoice:
 - add 'rebalance' option in order to pay an invoice
 - use the suggested channel in the 'swap' option

When we do not have the liquidity to receive an invoice:
 - add 'Rebalance' and 'Swap' buttons to the receive tab
2022-05-21 20:25:44 +02:00
ThomasV
917f256e33 remove scheduled invoices: bad UX. better expect the user to retry later. 2022-05-21 12:24:26 +02:00
SomberNight
2ec9e869b3 invoice.get_amount_sat: handle None in more places
I believe lightning requests created before https://github.com/spesmilo/electrum/pull/7730
can have an amount of None - ones created after have amount 0 instead.
We could do a wallet db upgrade potentially.
Regardless, the type hint is `get_amount_sat(self) -> Union[int, str, None]`,
so None should be handled. (well, arguably "!" should be handled too...)

```
E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "...\electrum\electrum\gui\qt\request_list.py", line 101, in item_changed
    self.parent.show_receive_request(req)
  File "...\electrum\electrum\gui\qt\main_window.py", line 1279, in show_receive_request
    URI = req.get_bip21_URI(lightning=bip21_lightning)
  File "...\electrum\electrum\invoices.py", line 164, in get_bip21_URI
    amount = int(self.get_amount_sat())
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
```

```
E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "...\electrum\electrum\gui\qt\request_list.py", line 101, in item_changed
    self.parent.show_receive_request(req)
  File "...\electrum\electrum\gui\qt\main_window.py", line 1281, in show_receive_request
    can_receive_lightning = self.wallet.lnworker and req.get_amount_sat() <= self.wallet.lnworker.num_sats_can_receive()
TypeError: '<=' not supported between instances of 'NoneType' and 'decimal.Decimal'
```
2022-05-19 19:43:07 +02:00
ThomasV
1d498eeefc Change the semantics of get_balance:
It does not make sense to count change outputs in our unconfirmed balance,
because our balance will not be negatively affected if the transaction does
not get confirmed.

It is also incorrect to add signed values of get_addr_balance in order to compute
the balance over a domain. For example, this leads to incoming and outgoing
transactions cancelling out in our total unconfirmed balance.

This commit looks at the coins that are spent by a transaction. If those
coins belong to us and are confirmed, we do not count the transaction outputs
in our unconfirmed balance.

As a result, get_balance always returns positive values for unconfirmed balance.
2022-05-11 08:50:09 +02:00
ThomasV
1274ec7655 Qt balance piechart: show lightning funds that are frozen 2022-05-10 20:07:30 +02:00
SomberNight
238619f1ed hardware wallets: smarter pairing during sign_transaction
Scenario:
- 2of2 multisig wallet with device1 and device2
- disconnect all devices
- open wallet file
- fail all pairings at wallet-open
- connect device2
- try to sign a tx
At this point Electrum will try to find the device for keystore1 first, and there is only a single unpaired device: device2.
Automatic pairing of keystore1 and device2 will fail, due to device id mismatching compared to what is persisted on disk for keystore1, so the user is prompted for manual selection. The selection dialog is somewhat confusing as it is not clear that the app is asking to select a device for keystore1. Pairing would fail, so the user is expected to cancel the dialog. If they cancel, keystore1 is skipped, and we try to pair for keystore2 now, and device2 will pair with it automatically.

fixes https://github.com/spesmilo/electrum/issues/4199#issuecomment-1112552416
2022-04-28 21:38:08 +02:00
SomberNight
adfe542fae wallet_db upgrade: recalc keys of outgoing on-chain invoices
closes https://github.com/spesmilo/electrum/issues/7777
2022-04-22 19:53:55 +02:00
SomberNight
63c8aeb54c wallet: fix paying invoice with "max" amount
fixes https://github.com/spesmilo/electrum/pull/7774
2022-04-22 16:46:47 +02:00
ThomasV
bb2e410942 Do not reuse addresses of expired requests.
Since expired requests are user-visible, it is very
confusing that they get replaced when the user creates
a new request.
2022-04-21 12:16:39 +02:00
ThomasV
f53b413643 set_frozen_state: trigger refresh of piechart in status bar 2022-04-21 11:54:29 +02:00
ThomasV
ba018c707f Qt: add bolt11_fallback and bip21_lightning options to preferences 2022-04-20 12:48:22 +02:00
ThomasV
0c64a884c9 Qt: show single balance in statusbar
- details in popup dialop
  - piechart in status bar
2022-04-20 12:48:22 +02:00
ThomasV
60865f3902 Show options if we do not have the liquidity to pay a lightning invoice:
pay onchain, open channel, rebalance.

If we do a swap or open a channel, the payment will be scheduled.
2022-04-20 12:48:22 +02:00
ThomasV
bf4455ef30 follow-up db invoice unification:
- fix command line
 - deprecate add_lightning_request
2022-04-20 12:48:22 +02:00
ThomasV
7102fb732e follow-up prev:
- detect payment of requests both onchain or LN
 - create single type of requests in GUI
2022-04-20 12:48:22 +02:00
ThomasV
e392197ab9 wallet_db upgrade:
- unify lightning and onchain invoices, with optional fields for bip70 and lightning
 - add receive_address fields to submarine swaps
2022-04-20 12:48:22 +02:00
SomberNight
30650c524c address_sync: "up_to_date" now waits for SPV 2022-04-08 20:35:23 +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
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