Commit Graph

476 Commits

Author SHA1 Message Date
ThomasV
e4273e5ab9 utxo privacy analysis:
- add a new event, 'adb_removed_tx'
 - new wallet method: get_tx_parents
 - number of parents is shown in coins tab
 - detailed list of parents is shown in dialog
2023-02-25 11:46:47 +01:00
SomberNight
d4338fb503 tests: clean-up use of asyncio 2023-02-20 16:53:44 +00:00
SomberNight
373db76ac9 util: kill bh2u
no longer useful, and the name is so confusing...
2023-02-17 11:43:11 +00:00
ThomasV
f617887509 RBF dialog: do not decrease payment for swap funding transactions. 2023-02-10 16:30:08 +01:00
ThomasV
bf16919a74 Merge pull request #8197 from spesmilo/new_tx_flow
Qt: new onchain tx creation flow:
2023-02-10 10:26:44 +01:00
SomberNight
8a53a3201c wallet.try_detecting_internal_addresses_corruption: check more addrs
related https://github.com/spesmilo/electrum/issues/8202

For a HD wallet, instead of checking the first 10 addrs + 10 additional random ones,
we now check the first 10 addrs + 10 random used addrs + 10 random unused addrs.
Checking unused addresses is useful to prevent getting money sent there,
and checking used addresses is useful to inform people of already lost money.
2023-02-08 23:32:32 +00:00
ThomasV
bc3946d2f4 Qt: new onchain tx creation flow:
- transaction_dialog is read-only
 - ConfirmTxDialog and RBF dialogs inherit from TxEditor
 - TxEditors are configurable
2023-02-07 16:42:20 +01:00
ThomasV
d6febb5c12 Display mined tx outputs as ShortIDs instead of full transaction outpoints.
ShortIDs were originally designed for lightning channels, and are now
understood by some block explorers.

This allows to remove one column in the UTXO tab (height is redundant).

In the transaction dialog, the space saving ensures that all inputs fit
into one line (it was not the case previously with p2wsh addresses).
For clarity and consistency, the ShortID is displayed for both inputs
and outputs in the transaction dialog.
2023-01-26 10:48:28 +01:00
ThomasV
062051b530 lnworker: store onchain default labels in a cache 2023-01-23 10:48:25 +01:00
Sander van Grieken
aac0e4f693 add explicit is_lightning check before potentially calling lnworker.get_invoice_status in wallet.export_request 2023-01-17 11:34:23 +01:00
ThomasV
7bfcf4f4d8 Merge pull request #8143 from MrNaif2018/tx-hashes-unpaid-invoices
Return list of tx hashes for partially paid invoices too
2023-01-13 18:29:58 +01:00
ThomasV
7d52021d6b Merge pull request #8139 from SomberNight/202301_locale_decimal_point
locale amounts: consistently use "." as dec point, and " " as thou sep
2023-01-13 16:00:47 +01:00
MrNaif2018
c785eb9ccd Return list of tx hashes for partially paid invoices too 2023-01-13 01:04:49 +03:00
SomberNight
9a0fff2571 wallet.get_request_by_addr: make deterministic
This makes test_invoices/test_wallet_get_request_by_addr pass without flakyness.

closes https://github.com/spesmilo/electrum/issues/8113
2023-01-12 18:19:11 +00:00
SomberNight
7dcaa4b204 tests: add tests for wallet/invoices functionality
only for payment requests ("incoming invoices") for now
2023-01-12 18:19:08 +00:00
SomberNight
8829b7cd63 wallet: fix deadlock in on_event_adb_added_verified_tx
wallet.lock -> wallet.transaction_lock order must be respected.

deadlock example:
```
# ThreadID: 19100
File: ...\Python\Python310\lib\threading.py", line 966, in _bootstrap
  self._bootstrap_inner()
File: ...\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
  self.run()
File: ...\Python\Python310\lib\threading.py", line 946, in run
  self._target(*self._args, **self._kwargs)
File: "...\electrum\electrum\util.py", line 1552, in run_event_loop
  loop.run_until_complete(stopping_fut)
File: ...\Python\Python310\lib\asyncio\base_events.py", line 633, in run_until_complete
  self.run_forever()
File: ...\Python\Python310\lib\asyncio\windows_events.py", line 321, in run_forever
  super().run_forever()
File: ...\Python\Python310\lib\asyncio\base_events.py", line 600, in run_forever
  self._run_once()
File: ...\Python\Python310\lib\asyncio\base_events.py", line 1896, in _run_once
  handle._run()
File: ...\Python\Python310\lib\asyncio\events.py", line 80, in _run
  self._context.run(self._callback, *self._args)
File: "...\electrum\electrum\wallet.py", line 494, in on_event_adb_added_verified_tx
  self._update_invoices_and_reqs_touched_by_tx(tx_hash)
File: "...\electrum\electrum\wallet.py", line 2454, in _update_invoices_and_reqs_touched_by_tx
  status = self.get_invoice_status(request)
File: "...\electrum\electrum\wallet.py", line 2333, in get_invoice_status
  paid, conf = self.is_onchain_invoice_paid(invoice)
File: "...\electrum\electrum\wallet.py", line 1120, in is_onchain_invoice_paid
  is_paid, conf_needed, relevant_txs = self._is_onchain_invoice_paid(invoice)
File: "...\electrum\electrum\wallet.py", line 1095, in _is_onchain_invoice_paid
  with self.lock, self.transaction_lock:
File: "...\electrum\electrum\address_synchronizer.py", line 70, in acquire
  return self._lock.acquire(*args, **kwargs)

# ThreadID: 20040
File: "C:\Program Files\JetBrains\PyCharm Community Edition 2021.3.3\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py", line 51, in <module>
  sys.exit(pytest.main(args, plugins_to_load + [Plugin]))
File: "...\Python\Python310\site-packages\_pytest\config\__init__.py", line 164, in main
  ret: Union[ExitCode, int] = config.hook.pytest_cmdline_main(
File: ...\Python\Python310\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
  return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
File: ...\Python\Python310\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
  return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
File: ...\Python\Python310\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
  res = hook_impl.function(*args)
File: "...\Python\Python310\site-packages\_pytest\main.py", line 315, in pytest_cmdline_main
  return wrap_session(config, _main)
File: "...\Python\Python310\site-packages\_pytest\main.py", line 268, in wrap_session
  session.exitstatus = doit(config, session) or 0
File: "...\Python\Python310\site-packages\_pytest\main.py", line 322, in _main
  config.hook.pytest_runtestloop(session=session)
File: ...\Python\Python310\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
  return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
File: ...\Python\Python310\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
  return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
File: ...\Python\Python310\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
  res = hook_impl.function(*args)
File: "...\Python\Python310\site-packages\_pytest\main.py", line 347, in pytest_runtestloop
  item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
File: ...\Python\Python310\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
  return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
File: ...\Python\Python310\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
  return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
File: ...\Python\Python310\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
  res = hook_impl.function(*args)
File: "...\Python\Python310\site-packages\_pytest\runner.py", line 111, in pytest_runtest_protocol
  runtestprotocol(item, nextitem=nextitem)
File: "...\Python\Python310\site-packages\_pytest\runner.py", line 130, in runtestprotocol
  reports.append(call_and_report(item, "call", log))
File: "...\Python\Python310\site-packages\_pytest\runner.py", line 219, in call_and_report
  call = call_runtest_hook(item, when, **kwds)
File: "...\Python\Python310\site-packages\_pytest\runner.py", line 258, in call_runtest_hook
  return CallInfo.from_call(
File: "...\Python\Python310\site-packages\_pytest\runner.py", line 338, in from_call
  result: Optional[TResult] = func()
File: "...\Python\Python310\site-packages\_pytest\runner.py", line 259, in <lambda>
  lambda: ihook(item=item, **kwds), when=when, reraise=reraise
File: ...\Python\Python310\lib\site-packages\pluggy\_hooks.py", line 265, in __call__
  return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
File: ...\Python\Python310\lib\site-packages\pluggy\_manager.py", line 80, in _hookexec
  return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
File: ...\Python\Python310\lib\site-packages\pluggy\_callers.py", line 39, in _multicall
  res = hook_impl.function(*args)
File: "...\Python\Python310\site-packages\_pytest\runner.py", line 166, in pytest_runtest_call
  item.runtest()
File: "...\Python\Python310\site-packages\_pytest\unittest.py", line 327, in runtest
  self._testcase(result=self)  # type: ignore[arg-type]
File: ...\Python\Python310\lib\unittest\case.py", line 650, in __call__
  return self.run(*args, **kwds)
File: ...\Python\Python310\lib\unittest\case.py", line 591, in run
  self._callTestMethod(testMethod)
File: ...\Python\Python310\lib\unittest\case.py", line 549, in _callTestMethod
  method()
File: "...\electrum\electrum\tests\test_invoices.py", line 120, in test_wallet_without_ln_creates_payreq_and_gets_paid_onchain
  self.assertEqual(PR_PAID, wallet1.get_invoice_status(pr))
File: "...\electrum\electrum\wallet.py", line 2333, in get_invoice_status
  paid, conf = self.is_onchain_invoice_paid(invoice)
File: "...\electrum\electrum\wallet.py", line 1120, in is_onchain_invoice_paid
  is_paid, conf_needed, relevant_txs = self._is_onchain_invoice_paid(invoice)
File: "...\electrum\electrum\wallet.py", line 1095, in _is_onchain_invoice_paid
  with self.lock, self.transaction_lock:
File: "...\electrum\electrum\address_synchronizer.py", line 70, in acquire
  return self._lock.acquire(*args, **kwargs)
```
2023-01-12 18:19:04 +00:00
SomberNight
2a9909c252 locale amounts: consistently use "." as dec point, and " " as thou sep
Always use "." as decimal point, and " " as thousands separator.

Previously,
- for decimal point, we were using
  - "." in some places (e.g. AmountEdit, most fiat amounts), and
  - `locale.localeconv()['decimal_point']` in others.
- for thousands separator, we were using
  - "," in some places (most fiat amounts), and
  - " " in others (format_satoshis)

I think it is better to be consistent even if whatever we pick differs from the locale.
Using whitespace for thousands separator (vs comma) is probably less confusing for people
whose locale would user "." for ts and "," for dp (as in e.g. German).

The alternative option would be to always use the locale. Even if we decide to do that later,
this refactoring should be useful.

closes https://github.com/spesmilo/electrum/issues/2629
2023-01-10 14:45:35 +00:00
SomberNight
61f2654f31 wallet: fire fewer 'status' and 'wallet_updated' triggers
Especially during initial history sync, there are a lot of False->False up_to_date transitions
(e.g. adb.add_address generates one), and the GUI does some work for each, which adds up to a lot
of CPU usage for the full sync.
2022-12-23 09:35:29 +00:00
ThomasV
a383f56909 Simplify RBF user experience:
- replace complex strategies with a simpler choice,
   between preserving or decreasing the payment.
 - Always expose that choice to the user.
 - Show the resulting fees to the user before they click OK
2022-12-13 11:26:44 +01:00
ThomasV
e1dc7d1e6f Set the RBF flat to all transactions, and remove the 'use_rbf'
preference from the GUI, because the mempoolfullrbf option in
Bitcoin 0.24 makes RBF signaling pretty meaningless. Fixes #8088.

Note: RBF remains disabled for channel funding transactions.
In that case, the flag is actually only used as a semaphore
between different instances of the same wallet.
2022-12-10 18:58:15 +01:00
SomberNight
30f3d27baa wallet: change _requests_addr_to_key map to multi-map
I find this easier to reason about than occasionally overwriting the items.
get_request_by_addr still only returns a single invoice for simplicity,
but now all logic regarding how to handle collisions is inside that method.
2022-11-18 18:10:43 +00:00
SomberNight
1a8cc68f53 wallet: _requests_addr_to_key map to prefer unexpired reqs if collision 2022-11-18 16:59:47 +00:00
MrNaif2018
b357391c48 Add tx_hashes to exported payment requests (#7936)
* Add `tx_hashes` to payment requests

* Apply patch

* Fix for missing lnworker
2022-11-10 17:48:00 +00:00
SomberNight
a15e383dbb wallet.add_input_info: also add block_height if known
The coin_chooser requires the block_height field (to prioritise confirmed utxos).
2022-11-03 12:30:37 +00:00
SomberNight
d3227d7489 transaction: for witness v0 txins, put both UTXO and WIT_UTXO in psbt
Until now we have been only putting PSBT_IN_NON_WITNESS_UTXO (="UTXO", full tx)
in segwit witness v0 txins, as signers wanted the full tx anyway due to
bip-143 sighash issue [0], and as WITNESS_UTXO can be calculated from UTXO.

My reading of bip-174 is that either behaviour is correct, but
achow101 said bip-174 expects PSBT_IN_WITNESS_UTXO for segwit inputs.
Regardless, including both fields does not increase the tx size too much
(UTXO can be very large ofc but we were already including that, WIT_UTXO is small).
This also might increase compatibility with some other software - I've found
some issues where this might have been the culprit [1][2][3].

closes https://github.com/spesmilo/electrum/issues/8039

related:
[0] https://github.com/spesmilo/electrum/pull/6198
[1] https://github.com/cryptoadvance/specter-desktop/issues/868
[2] https://github.com/cryptoadvance/specter-desktop/issues/1046
[3] https://github.com/cryptoadvance/specter-desktop/issues/1544
2022-10-31 17:14:21 +00:00
ThomasV
3bb453aaba PayServer: add settings dialog and hook for view_url 2022-10-28 13:52:24 +02:00
Sander van Grieken
3590385fa2 Revert "only create lightning invoice if the wallet has channels in a suitable state"
This reverts commit 717b6dd5fb.
2022-10-19 14:50:38 +02:00
Sander van Grieken
717b6dd5fb only create lightning invoice if the wallet has channels in a suitable state 2022-10-19 12:27:19 +02:00
ThomasV
ff5ba7cca4 rbf: fix issues with bump_frr_through_decreasing_change
- break from loop if target is reached
- recompute delta if there is no next iteration.
2022-10-04 10:23:58 +02:00
Sander van Grieken
d4df633f22 move request details into separate dialog 2022-09-28 18:21:07 +02:00
ThomasV
60e2ad4316 follow-up 444dc7fb7f 2022-09-26 18:28:02 +02:00
ThomasV
444dc7fb7f wallet: fix race condition that inhibits proper call of set_up_to_date 2022-09-26 17:02:30 +02:00
ThomasV
30dfecc5dc wallet: check whether address can be reused in get_request_by_addr 2022-09-22 17:37:11 +02:00
Sander van Grieken
5681311fc2 fix request_status callback not passing the correct request key 2022-09-22 11:54:14 +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
ThomasV
7d317761da wallet API: remove get_request_status, it is redundant with get_invoice_status 2022-09-01 10:01:09 +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
6a9e8da218 remove sign_payment_request: broken and not used 2022-08-29 12:50:02 +02:00
ThomasV
2df45faeae follow-up previous commit 2022-08-29 10:27:56 +02:00
ThomasV
cf94ebc106 If an invoice cannot be parsed in import_invoices or import_requests,
raise FileImportFailed. Fixes #7950
2022-08-29 10:21:14 +02:00
ThomasV
d9f77a50e8 wallet API: remove get_request_status, it is redundant with get_invoice_status 2022-08-29 09:48:08 +02:00
SomberNight
757ec53ea2 AddressSynchronizer: set diagnostic_name for better logs
fixes regression from 121d8732f1

in particular, this is needed for Synchronizer.diagnostic_name and SPV.diagnostic_name
2022-08-24 11:05:01 +00:00
ThomasV
60c493dc15 adb: trigger adb_added_tx event only if the transaction is new 2022-08-17 10:40:43 +02:00
SomberNight
d1c15fe5e9 wallet: (perf) avoid iterating over all invoices in add_transaction 2022-08-16 12:14:44 +00:00
ThomasV
24145f1f52 detect paid invoices in on_event_adb_added_tx 2022-08-16 10:14:47 +02:00
ThomasV
a64aa45e85 get default label for txid based on invoices 2022-08-16 08:50:46 +02:00
ThomasV
2c53af1664 wallet: load lnworker earlier 2022-08-16 08:50:46 +02:00
SomberNight
13570a465c kivy request dialog: follow-up c95791d7ee
related https://github.com/spesmilo/electrum/pull/7929
2022-08-12 11:10:54 +00:00
SomberNight
c95791d7ee qt/kivy: receive tab: add wallet.ReceiveRequestHelp and refactor 2022-08-12 10:06:13 +02:00
SomberNight
767b058946 qt history tab: fix "View Channel" in context menu
related: https://github.com/spesmilo/electrum/issues/7930
2022-08-12 02:30:29 +00:00