Commit Graph

305 Commits

Author SHA1 Message Date
SomberNight 16c8cb50e3 lnchannel: (trivial) fix type hint of receive_fail_reasons 2026-04-18 17:16:57 +00: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
SomberNight 0b2c7a8a38 lnsweep: safer maybe_reveal_preimage_for_htlc, add "is_preimage_public"
"When should we reveal preimages onchain?"
This commit tries to simplify the thinking by making the observation:
- we can reveal preimages (actually in any context) if they are already public
- a preimage is public if any other lightning node knows it besides us
  - if we learn the preimage from another LN node, it is public
  - if we send update_fulfill_htlc, it becomes public
  - if we see a preimage onchain, it is public

- in lnsweep._maybe_reveal_preimage_for_htlc:
  - partial mpp check is not relevant if preimage is already public
  - let's just always do KeepWatchingTXO, for sanity/safety

Co-authored-by: ThomasV <thomasv@electrum.org>
2026-02-24 17:49:15 +00:00
ThomasV 5767913e07 lnhtlc: remove unneeded non-initiator fee_update in log 2026-01-28 12:32:59 +01:00
SomberNight c3e373a3b2 lnchannel: chan.lnworker must now always be set, even in unit tests 2026-01-05 15:56:07 +00:00
SomberNight dfeb9918d8 tests: lnchannel: rewrite create_test_channels to use LNWallet 2026-01-05 15:56:04 +00:00
SomberNight 1006e8092f lnworker: split LNWallet and LNWorker: LNWallet "has an" LNWorker
- LNWallet no longer "is-an" LNWorker, instead LNWallet "has-an" LNWorker
- the motivation is to make the unit tests nicer, and allow writing unit tests for more things
  - I hope this makes it possible to e.g. test lnsweep in the unit tests
  - some stuff we would previously have to write a regtest for, maybe we can write a unit test for, now
- in unit tests, MockLNWallet now
  - inherits LNWallet
  - the Wallet is no longer being mocked
2026-01-05 15:55:31 +00:00
SomberNight f339a6b76d lnwatcher: follow-up prev 2025-12-17 10:23:16 +00:00
SomberNight 7e1fd008f0 lnsweep: lnwatcher needs to keep_watching if htlc in dont_settle_htlcs
If RHASH is in lnworker.dont_settle_htlcs, we should not reveal
the preimage. But also, we should not disregard the htlc either.

E.g. during a JIT channel open, payment going A->B->C,
C would release the preimage to B (lsp) to cover the costs of the
JIT channel-open. If the upstream A->B channel gets force-closed, B should
only pull the HTLC's funds if he is sure he can forward them to C.

lnwatcher needs to keep watching (i.e. wait) until the RHASH gets removed from
lnworker.dont_settle_htlcs, or until the CLTV of the HTLC expires.
2025-12-15 14:53:50 +00:00
f321x c34efce984 lnchannel: allow deleting unfunded incoming channels
We tried to delete incoming channels that didn't get funded after
lnutil.CHANNEL_OPENING_TIMEOUT, however an assert prevented this:

```
  3.63 | E | lnwatcher.LNWatcher.[default_wallet-LNW] | Exception in check_onchain_situation: AssertionError()
Traceback (most recent call last):
  File "/home/user/code/electrum-fork/electrum/util.py", line 1233, in wrapper
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/code/electrum-fork/electrum/lnwatcher.py", line 117, in check_onchain_situation
    await self.update_channel_state(
    ...<5 lines>...
        keep_watching=keep_watching)
  File "/home/user/code/electrum-fork/electrum/lnwatcher.py", line 135, in update_channel_state
    chan.update_onchain_state(
    ~~~~~~~~~~~~~~~~~~~~~~~~~^
        funding_txid=funding_txid,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<2 lines>...
        closing_height=closing_height,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        keep_watching=keep_watching)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/code/electrum-fork/electrum/lnchannel.py", line 341, in update_onchain_state
    self.update_unfunded_state()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/user/code/electrum-fork/electrum/lnchannel.py", line 382, in update_unfunded_state
    self.lnworker.remove_channel(self.channel_id)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/user/code/electrum-fork/electrum/lnworker.py", line 3244, in remove_channel
    assert chan.can_be_deleted()
           ~~~~~~~~~~~~~~~~~~~^^
AssertionError
```
2025-12-10 13:20:32 +01:00
f321x fb566eb59e lnpeer: deduct jit channel fees from total amount
Deduct the just in time channel opening fees from the total amount so
htlcs don't get timed out if they come from a just in time channel with
opening fee.

Related: https://github.com/spesmilo/electrum/pull/9584
2025-12-06 10:14:07 +01:00
f321x 0f314d1dd9 lnpeer/lnworker: refactor htlc_switch
refactor `htlc_switch` to new architecture to make it more robust
against partial settlement of htlc sets and increase maintainability.
Htlcs are now processed in two steps, first the htlcs are collected into
sets from the channels, and potentially failed on their own already.
Then a second loop iterates over the htlc sets and finalizes only on
whole sets.

# Conflicts:
#	electrum/lnpeer.py
2025-11-27 17:57:14 +01:00
ThomasV 077bcf515d StoredDict: use pointers instead of path
Instead of storing its own path, each StoredDict element stores
its own key and a pointer to its parent. If a dict is removed
from the db, its parent pointer is set to None. This makes
self.path return None for all branches that have been pruned.

This passes tests/tests_json_db.py and fixes issue #10000
2025-11-07 10:00:10 +01:00
f321x e6ea6dbf0a lnutil: make UpdateAddHtlc dataclass
it is straightforward to move UpdateAddHtlc away from attr
to a dataclass without requiring any db update.
2025-09-29 16:11:07 +00:00
SomberNight b944371ffd adb: change API of util.TxMinedInfo: height() is now always SPV-ed 2025-09-24 13:46:24 +00:00
ThomasV 43ca469774 Merge pull request #9555 from tianzedavid/master
chore: fix some typos
2025-05-30 14:36:12 +02:00
ghost43 6b7a026945 Merge pull request #9848 from SomberNight/202505_refactor_lnchannel_ctx_updates
lnchannel: refactor can_send_ctx_updates
2025-05-21 15:49:34 +00:00
SomberNight 65c9a5f875 lnchannel: refactor can_send_ctx_updates
This adds a lot more sanity checks to lnpeer/lnchannel for chan update operations,
and more logging in case they are violated.
2025-05-21 14:57:56 +00:00
ThomasV 0bce76c49d lnchannel: add strict parameter to remaining_max_inflight
also fix some indentations and rm unused imports
2025-05-20 17:45:39 +02:00
ThomasV d1917b2951 Merge pull request #9837 from spesmilo/htlc_slots_left
pass number of htlc_slots_left to suggest_splits
2025-05-20 12:55:45 +02:00
ThomasV b432a1406a lnchannel: apply stricter max_htlc_value_in_flight rules for receiving
Otherwise we create invoices that eclair cannot route to us
2025-05-20 12:44:14 +02:00
SomberNight d0be5fcfc8 lnchannel: persist error sent by remote peer into db
If a force-close happens due to e.g. a feerate disagreement or an invalid signature, etc,
and the remote peer sends us an error, it can be useful if users can provide us with this error.
If the user does not have logging enabled when the error is sent, without this persistence it will likely get lost.
2025-05-18 16:54:56 +00:00
ThomasV 4a17d5a316 pass number of htlc_slots_left to suggest_splits 2025-05-17 15:50:03 +02:00
ThomasV 9f9919e351 available_to_spend: check too_many_htlcs
partial fix for #8857
(this should at least fix the trampoline case)
2025-05-16 12:34:27 +02:00
ThomasV 128eb9cc8b available_to_spend: remove unused 'strict' parameter 2025-05-16 12:29:49 +02:00
ThomasV fed526bbdf lnchannel: create helper functions too_many_htlcs and remaining_max_inflight 2025-05-16 12:29:00 +02:00
Sander van Grieken 7f621d29b5 lnchannel: available_to_spend constrain max amount to channel max_htlc_value_in_flight_msat 2025-05-16 12:28:11 +02:00
SomberNight 586cf33c05 lnchannel: rm sweep_info cache
- was added when functions in lnsweep returned already signed tx, and signing is expensive
- get_ctx_sweep_info does not presign anymore
- cache invalidation is difficult here
  - e.g. not only on new blocks, but we should e.g. also invalidate the cache when learning new preimages
2025-05-15 19:41:44 +00:00
ThomasV 0607a406ce Qt: add closing warning if we have an unconfirmed local commitment tx with htlcs
add htlc direction (offered, received) to the htlc sweep_info name
regtest: add test_reedeem_received_htlcs
2025-05-12 15:48:20 +02:00
ThomasV 7bcc7fb0c4 txbatcher: do not require password in memory
- if password is needed, await future and request it from GUI
 - run asyncio task for each TxBatch, so that batches can
   request the password concurrently
2025-05-06 13:04:19 +02:00
SomberNight 089568430d lnchannel: remove threshold from should_be_closed_due_to_expiring_htlcs
The threshold was added a long time ago before we considered running electrum as a forwarding node.
(also, 500k sats are now worth 20x more in fiat terms, lol)
Against a forwarding node, it is actually exploitable.
2025-03-13 16:10:51 +00:00
SomberNight 8c320b4b5c lnchannel: add comment to extract_preimage_from_htlc_txin
ref https://github.com/spesmilo/electrum/issues/9631
2025-03-13 16:06:00 +00:00
f321x 7a6b4adca9 validate zeroconf channel once mined 2025-03-13 10:56:54 +01:00
ThomasV 798df671ea If we have proposed htlcs in a channel that was force-closed,
call lnworker.htlc_failed once the htlc_tx is deeply mined.

In the case of a forwarding, this will fail incoming htlcs.
(fixes #8547)
2025-03-12 20:11:11 +01:00
SomberNight a7c634b1ab regtests: extend "extract_preimage" to cover both types of extracts 2025-03-07 17:06:55 +00:00
ThomasV 764cc78386 Merge pull request #9590 from f321x/jit-update-unfunded-state
Handle unfunded zeroconf channels in update_unfunded_state
2025-03-07 13:55:55 +01:00
f321x 6fd833ccfb add handling of zeroconf channels to update_unfunded_state 2025-03-07 13:53:01 +01:00
ThomasV 840243e029 separate fee policy from config
- Wallet.make_unsigned_transaction takes a FeePolicy parameter
 - fee sliders act on a FeePolicy instead of config
 - different fee policies may be used for different purposes
 - do not detect dust outputs in lnsweep, delegate that to lnwatcher
2025-03-05 10:29:26 +01:00
ThomasV 4917f7e3ce fix balance sanity check in get_lightning_history 2025-02-28 09:42:24 +01:00
tianzedavid c080d6531f chore: fix some typos
Signed-off-by: tianzedavid <cuitianze@aliyun.com>
2025-02-13 00:34:04 +08:00
SomberNight cba073dfd1 lightning: change derivation of funding_pubkey
Ideally, given an on-chain backup, after the remote force-closes, we should be able to spend our anchor output,
to CPFP the remote commitment tx (assuming the channel used OPTION_ANCHORS).
To spend the anchor output, we need to be able to sign with the local funding_privkey.

Previously we derived the funding_key from the channel_seed (which comes from os.urandom).
Prior to anchors, there was no use case for signing with the funding_key given a channel backup.
Now with anchors, we should make its derivation deterministic somehow, in a way so that it can
be derived given just an on-chain backup.
- one way would be to put some more data into the existing OP_RETURN
  - uses block space
  - the OP_RETURNs can be disabled via "use_recoverable_channels"
  - only the initiator can use OP_RETURNs (so what if channel is in incoming dir?)
- instead, new scheme for our funding_key:
  - we derive the funding_privkey from the lnworker root secret (derived from our bip32 seed)
  - for outgoing channels:
    - lnworker_root_secret + remote_node_id + funding_tx_nlocktime
  - for incoming channels:
    - lnworker_root_secret + remote_node_id + remote_funding_pubkey
  - a check is added to avoid reusing the same key between channels:
      not letting to user open more than one channel with the same peer in a single block
  - only the first 16 bytes of the remote_node_id are used, as the onchain backup OP_RETURNs only contain that
- as the funding_privkey cannot be derived from the channel_seed anymore, it is included in the
imported channel backups, which in turn need a new version defined
  - a wallet db upgrade is used to update already stored imported cbs
  - alternatively we could keep the imported cbs as-is, so no new version, no new funding_privkey field, as it is clearly somewhat redundant given on-chain backups can reconstruct it
    - however adding the field seems easier
      - otherwise the existing code would try to derive the funding_privkey from the channel_seed
      - also note: atm there is no field in the imported backups to distinguish anchor channels vs static-remotekey channels
2025-01-14 17:56:48 +00:00
ThomasV 67470b92b7 lnchannel: fix extract_preimage for MPP.
- enforce MPP in the corresponding regtest.
 - fix get_invoice_status returning inflight if it was settled onchain
2024-12-15 10:46:18 +01:00
ThomasV 3b1dc194e4 Refactor lnsweep:
- txins have an optional make_witness method
 - instead of gen_tx, SweepInfo has a txin and
   an optional txout, for 1st stage HTLCs
 - sweep transactions are created by lnwatcher

The purpose of this change is to allow combining several
inputs in the same sweep transaction.
2024-12-11 17:14:14 +01:00
bitromortac d535821516 htlctx: deal with possible peer htlctx batching
Due to anchor channel's sighash.SINGLE and sighash.ANYONECANPAY,
several HTLC-transactions can be combined. This means we must watch for
revoked outputs in the HTLC transaction not only at index 0 but at any
index.
2024-11-26 09:28:00 +01:00
bitromortac 9c277802e9 sweep: rename sweep creation functions
naming scheme: tx(s)_our/their_ctx/htlctx_output-description

function names are shortened to whether a single (tx) or several sweep
transactions (txs) are generated
2024-11-25 19:24:51 +01:00
bitromortac ea584e13fc anchors: switch to zero-fee-htlcs
* sets the weight of htlc transactions to zero, thereby putting a zero
  fee for the htlc transactions
* add inputs to htlc-tx for fee bumping
* switches feature flags
* disable anchor test vectors, which are now partially invalid
2024-11-25 10:56:50 +01:00
ThomasV 78d19c6e2f amchor outputs: fixes after rebase 2024-11-23 11:26:04 +01:00
bitromortac 3a3f5059b4 backups: restore from closing tx, sweep to_remote
* add a method for backups to sweep to_remote
* to_remote sweeping needs the payment_basepoint's private key
  to sign the sweep transaction
* we restore the private key from our funding multisig pubkey
  (pubished with the closing transaction) and a static payment key secret
2024-11-21 12:18:53 +01:00
ThomasV 4d26fb552b fixes after rebase 2024-11-20 15:02:05 +01:00
bitromortac 7aa3dc1e40 lnutil+lnchannel: add anchors, adapt to_remote
* to_remote has now an additional csv lock of 1
* anchor outputs are added if to_local/remote outputs are present
* funder balance is reduced to accomodate anchors
2024-11-20 11:54:55 +01:00