Commit Graph

9336 Commits

Author SHA1 Message Date
ThomasV 7c433c5645 rm 'received orphan channnel' log line (too verbose) 2026-04-23 09:29:08 +02:00
ghost43 230e627559 Merge pull request #10600 from SomberNight/202604_lnpeer_chan_reest
lnpeer: channel_reestablish: split "they_are_ahead" into ctn vs revnum
2026-04-22 16:27:10 +00:00
SomberNight 46eadbf442 lnpeer: channel_reestablish: further restrict states for msg handler
re REQUESTED_FCLOSE and WE_ARE_TOXIC (as per f321x):
> There is no reason for the peer to send channel_reestablish after we
> have sent the force close request (error) and I assume we don't
> want to give surface to the peer to attempt finding out if we really lost state?

re FORCE_CLOSING:
the peer might not have realised we started force-closing but we probably don't want to run the message-handler even in that case
2026-04-22 15:57:18 +00:00
ThomasV bca41d941d Merge pull request #10573 from f321x/qml_wallet_rename
qml: allow renaming wallets
2026-04-22 10:03:14 +02:00
ThomasV 294d21407a Merge pull request #10568 from SomberNight/202604_verifier_left_sibling_duplicates
verifier.py: fix CVE-2012-2459: reject left-sibling duplicates
2026-04-21 16:22:07 +02:00
ghost43 b45d89e120 Merge pull request #10546 from f321x/bolt12_preparation_1
bolt12: preparation 1
2026-04-20 15:09:41 +00:00
SomberNight 21946e1e87 lnpeer: channel_reestablish: split "they_are_ahead" into ctn vs revnum 2026-04-18 17:23:35 +00:00
SomberNight 16c8cb50e3 lnchannel: (trivial) fix type hint of receive_fail_reasons 2026-04-18 17:16:57 +00:00
accumulator 3fbf597485 Merge pull request #10579 from f321x/qml_relay_list_padding
qml: add top padding to nostr relay url list
2026-04-14 18:18:05 +02:00
SomberNight 4a14feffd4 lnpeer: chan_reest: clarify my_current_per_commitment_point is ignored
`my_current_per_commitment_point` was only used prior to option_static_remotekey
2026-04-14 14:18:14 +00:00
f321x 24d93420fb qml: add top padding to nostr relay url list
The first relay url was close to the top of the ElTextArea and looked a
bit sliced. Adding some padding makes it look better.
2026-04-14 08:34:18 +02:00
SomberNight 016c8b5f4c bip21: add comment listing URI scheme handler registrations
It is sufficiently rare that we have to touch this stuff that I always have to re-discover where/how it is done. And it is impractical to grep for "bitcoin:" or "lightning:".

Putting this "master list" comment very close to the BITCOIN_BIP21_URI_SCHEME variable seems like a good spot - at least this is where I would look for it first.
2026-04-11 02:55:54 +00:00
f321x 8a12874c8e qml: allow renaming wallets
Allows to rename a wallet file from the QML Wallet Details view.
This seems like a feature we should support as the use-case of a wallet can
change or maybe the user didn't think about a proper name when setting
up the wallet. Especially with lightning channels it is not possible to
restore from seed to change the name.

Fixes #4377
2026-04-08 10:45:59 +02:00
f321x 9827734ab6 exchange rate: fix coingecko api
The CoinGecko API failed as the Honduran Lempira currency returned
null as value, rendering the API unusable:
```
11.19 | I | exchange_rate.CoinGecko | getting fx quotes for EUR
11.41 | E | exchange_rate.CoinGecko | failed fx quotes: InvalidOperation([<class 'decimal.ConversionSyntax'>])
Traceback (most recent call last):
  File "/var/home/user/code/vibecoding_vm/electrum/electrum/exchange_rate.py", line 87, in update_safe
    self._quotes = await self.get_rates(ccy)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/home/user/code/vibecoding_vm/electrum/electrum/exchange_rate.py", line 449, in get_rates
    return dict([(ccy.upper(), to_decimal(d['value']))
                               ~~~~~~~~~~^^^^^^^^^^^^
  File "/var/home/user/code/vibecoding_vm/electrum/electrum/util.py", line 243, in to_decimal
    return Decimal(str(x))
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]
```

```
"hnl":{"name":"Honduran Lempira","unit":"L","value":null,"type":"fiat"}
```
2026-04-08 10:20:01 +02:00
f321x fd230cf9d1 plugin: nwc: handle 'null' params in request
Some clients send 'params: null' instead of 'params: {}' or no
params key at all.
2026-04-07 09:52:13 +02:00
SomberNight 3d39074294 verifier.py: fix CVE-2012-2459: reject left-sibling duplicates
Due to how the txid-commitment merkle tree used in the block headers is constructed, we need an extra check to be able to validate the *position* of a txid in a block.

I think this is low severity for us.

See https://bitcointalk.org/?topic=102395 :

> The Merkle hash implementation that Bitcoin uses to calculate the Merkle
> root in a block header is flawed in that one can easily construct multiple
> lists of hashes that map to the same Merkle root.
> For example, merkle_hash([a, b, c]) and merkle_hash([a, b, c, c]) yield
> the same result. This is because, at every iteration, the Merkle hash
> function pads its intermediate list of hashes with the last hash if the
> list is of odd length, in order to make it of even length.
>
> And so, the Merkle root function can be effectively preimaged by
> changing the input so that one of the intermediate lists is of even
> length with the last two elements equal (where originally it was
> of odd length with a last element equal to the earlier mentioned two).
> As was later noted, this extends to any input length that is
> not a power of two:
> merkle_hash([a, b, c, d, e, f]) == merkle_hash([a, b, c, d, e, f, e, f]).
> Note that to maintain the same root hash, the only flexibility that
> exists is duplication of elements.

Ported from https://github.com/Electron-Cash/Electron-Cash/commit/165146362b4cb0ad74770b36aca1f9acb2800195

Co-authored-by: bitcoincashautist <80100588+A60AB5450353F40E@users.noreply.github.com>
2026-04-03 02:22:01 +00:00
ThomasV 7a6a39d1aa add comments about xpub encryption 2026-04-02 14:46:50 +02:00
SomberNight e71616e673 update release notes for version 4.7.2 2026-04-01 15:50:28 +00:00
f321x 4254c9a051 onion_message: fix route construction to ip
Don't include first hop of the path,
this is the hop from us to the first node and we don't
need a payload for ourselves.

Also adds unittest checking this.
2026-04-01 09:07:36 +02:00
f321x 4134dc7b25 onion_message: split send_onion_message_to
Factor out code from `send_onion_message_to` into a separate
function `_create_route_to_introduction_point` to make it
easier to reason about it and more testable.
2026-04-01 09:07:36 +02:00
Sander van Grieken 2e0f263269 onion_message: iterate blinded paths for onion message requests 2026-04-01 09:07:36 +02:00
Sander van Grieken 9bcbbdd3eb move blinding_privkey from onion_message to lnonion 2026-04-01 09:07:36 +02:00
Sander van Grieken 3e3bffa4a2 onion_message: let caller specify considered channels for blinded paths.
This allows restricting blinded paths to channels that have sufficient receive
capacity for payment.

NOTE: this might have privacy issues, as this can be used to probe channel capacity.
Maybe randomize leeway?

@f321x: changed to use scid alias in create_blinded_path
2026-04-01 09:07:36 +02:00
Sander van Grieken b7a512845f onion_message: factor out get_blinded_paths_to_me from get_blinded_reply_paths.
the former also calculates payinfo information for payment scenarios.
include payment_relay struct for payment blinded_paths.
2026-04-01 09:07:36 +02:00
Sander van Grieken 65fb739584 segwit_addr: bech32 decode without checksum option 2026-04-01 09:07:36 +02:00
ghost43 09a09057f6 Merge pull request #10548 from SomberNight/202603_lockdown_rpcserver
in GUI mode, only start a limited minimal RPC server
2026-03-31 15:25:52 +00:00
ghost43 8942ceace8 Merge pull request #10558 from f321x/followup_10541
trampoline: prevent adding ourself on the route, fixes CI
2026-03-30 14:33:00 +00:00
SomberNight 9d204abfae daemon: set restrictive permission on RPC-server unix domain socket
0600 instead of 0775.
2026-03-27 18:20:52 +00:00
f321x 11f0a68c96 trampoline: prevent adding ourself on the route
Followup #10541.
Fixes tests.regtest.TestLightningSwapserver.test_swapserver_forceclose.

In the regtest bob would now signal trampoline support due to #10541 and
include Alice into the invoice trampoline as he is connected to Alice.
Alice would then try to add herself onto the trampoline route, causing
the payment to fail.
2026-03-27 18:05:00 +01:00
SomberNight d33212656f crypto.py: replace sys.exit with ImportError
not nice to call sys.exit from inside the library
(run_electrum can do it, but the library probably should not)
2026-03-27 15:30:34 +00:00
ThomasV eb6a796de0 Merge pull request #10555 from f321x/nwc_handle_missing_params
plugin: nwc: handle missing params dict in request
2026-03-27 15:58:36 +01:00
ThomasV efbe1907d7 Merge pull request #10556 from f321x/settings_dialog_guard_network
qt: SettingsDialog: guard self.network access
2026-03-27 15:54:36 +01:00
f321x 1aad09a61d qt: SettingsDialog: guard self.network access
Check if self.network before trying to access it. This would trigger an
exception when toggling the trampoline checkbox in offline mode:
```
 29.13 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "/home/user/Documents/electrum/electrum/gui/qt/settings_dialog.py", line 133, in on_trampoline_checked
    self.network.run_from_another_thread(
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'run_from_another_thread'
 31.00 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
  File "/home/user/Documents/electrum/electrum/gui/qt/settings_dialog.py", line 131, in on_trampoline_checked
    self.network.start_gossip()
    ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'start_gossip'
```
2026-03-27 15:40:22 +01:00
f321x b9a24ae1cf plugin: nwc: handle missing params dict in request
Even though the NIP-47 specification kind of defines that requests should
always pass a params dict in their request i witnessed way too often
that clients don't include it in some requests where it is technically
not neccessary and we fail on it.
Handling this gracefully improves compatibility without obvious
downsides.
2026-03-27 15:05:15 +01:00
SomberNight 7afec53828 follow-up prev 2026-03-27 13:15:07 +00:00
SomberNight a508519017 plugin.py: fix some type hints 2026-03-26 18:56:02 +00:00
ThomasV 032dfcf107 plugins: use decorator to early return if plugin not authorized 2026-03-26 17:40:25 +01:00
f321x 609a274661 LNWallet: set trampoline invoice feature independently
Make the trampoline signaling in bolt11 invoices dependent upon all
unfrozen channels being with trampoline peers instead of the trampoline
config.
Stops automatically freezing non-trampoline channels for receiving if
trampoline is enabled.

One effect of this change is that now we don't signal trampoline support
anymore in the invoice even if trampoline is enabled, if one of the
channels is with a non trampoline peer.
2026-03-26 12:10:22 +01:00
f321x 0265c70766 LNWallet: only include tramp r_tags if tramp feature
Only include r_tags for trampoline nodes in a bolt11 invoice
if its invoice_features signal trampoline support.
2026-03-26 12:10:19 +01:00
SomberNight 726d3995f4 qt gui: more defensive 'gui' RPC (i.e. URI) handling 2026-03-25 18:54:13 +00:00
SomberNight d951a3d2f4 in GUI mode, only start a limited minimal RPC server
To limit attack surface.

Context:
- both in daemon mode and in GUI mode, we start an RPC server
- the RPC server uses HTTP basic auth, with a random password that is saved in the config file
- read access to the config file implies access to the RPC server
- the traffic is unencrypted
- by default the server listens
  - on Windows, on localhost TCP
  - all other platform, via unix domain sockets
- if an attacker can listen to localhost TCP traffic, and there was traffic
  - they could see the plaintext RPC password and issue their own commands
  - e.g. if wireshark was already installed on the system, this might not require root access
- the "ping" and "gui" commands are used by everyday operations that affect most users:
  - "ping" is used when trying to launch a second instance of electrum, to contact the first instance and enforce "singleton" behaviour
  - "gui" is used for URI handling (`$ xdg-open bitcoin:asdasd`)
- many other sensitive commands, that operate on wallets, require *also* the wallet password
  - but note that wallet.unlock can be used by the user to bypass this and store the wallet password in memory (exposed in GUI)

I propose locking down the RPC server when running in GUI mode:
- we still start it, as it is used for "ping" and "gui" RPCs, however we disable all other RPCs
- we could opt-in enable it, using a config var, except that ofc would not help against an attacker that has filesystem write access to the config file
- so I think it's even safer to just "hardcode" disable it: however the functionality is useful for development
  - I propose we branch based on `constants.net.TESTNET`
  - an alternative we could branch on that is hard to fake is `is_git_clone` in run_electrum
2026-03-25 18:44:56 +00:00
SomberNight e08390a01d daemon: (trivial) CommandsServer.run: move tcp-specific line
this line would raise if site was a web.NamedPipeSite
2026-03-25 16:19:14 +00:00
f321x 06490657bc fix: remove negative fee assert from get_tx_fee_warning
rm the `assert fee >= 0, f"{fee=!r} must be non-negative satoshis"`
from `Abstract_Wallet.get_tx_fee_warning()` to prevent an exception when
users load a psbt with negative tx fee.
2026-03-25 11:55:03 +01:00
ThomasV 3012c367ad Qt: move LN fee slider to payment dialog. fixes #10516 2026-03-25 10:53:38 +01:00
ThomasV efb3e344d0 Merge pull request #10543 from f321x/qml_trustedcoin
qml: make 2fa secret copyable, open 2fa app for user
2026-03-25 08:36:32 +01:00
ThomasV 06e9f2b5e3 Merge pull request #10534 from SomberNight/202603_rpc_password_not_empty
daemon: forbid "setconfig" command to change rpcserver settings in-flight
2026-03-25 08:35:52 +01:00
SomberNight 0dcef9780b daemon: forbid "setconfig" command to change rpcserver settings in-flight
It is much easier to reason about the rpcserver if we don't allow changing its basic settings while it is already running. What does it mean to change the TCP port it is listening on ("rpcport") if it's already running? It is even problematic to change the rpcpassword: care needs to be taken to already update it for the current server.
(ref https://github.com/spesmilo/electrum/issues/6762)

This commit disallows changing all of the "rpc*" config variables if the daemon is already running.

---

Simultaneously, it also ensures rpc_password is always set and auth cannot be disabled.

Previously if there was a daemon running, and the user ran
`$ electrum setconfig rpcpassword ""` that would leave the RPC unauthenticated
for the current session. However next time the daemon restarted, get_rpc_credentials would see
the unset password and generate one.

I think this was the worst of both worlds:
- we did not really allow removing the rpc password, except for the current session, and
- perhaps unexpectedly, we would generate a new password on daemon restart

Instead now we explicitly make sure the RPC server can never get into a state where it does not have a password set.

Based on a report by `Zuzana Kotásková <36777@mail.vsfs.cz>`
2026-03-24 17:07:26 +00:00
f321x cb023e22e4 qml: 2fa: make 2fa setup qr code clickable
This will make the 2fa app open when the user clicks on the qr code,
much more convenient than manually copy pasting the secret.
2026-03-24 14:50:45 +01:00
f321x 37159e47a2 qml: 2fa: make it possible to copy 2fa secret
The 2fa secret is not selectable or copyable, this is very inconveniant
when setting up a new 2fa wallet as the user has to somehow manually
write the secret e.g. on a paper to then enter it again in their 2fa
app. This makes the secret string copyable by clicking on it.
2026-03-24 14:50:42 +01:00
ThomasV 3cf2c325d5 Merge pull request #10506 from accumulator/spend_from_coin_selection_refactor
qt: perform 'fully spend' action with coin selection, keep separate from coin control when doing action
2026-03-24 12:46:02 +01:00