Commit Graph

92 Commits

Author SHA1 Message Date
ThomasV 558f85296c trampoline: allow trampoline onion packets of arbitrary size 2026-03-19 08:47:07 +01:00
SomberNight 1c24c61364 tests: lnpeer: uncomment testcase: test_modern_shutdown_no_overlap
This test case has always been disabled, but looks like the justification is easy to fix.
2026-03-12 19:22:44 +00:00
SomberNight 7e3af72ad6 lnpeer: maybe_send_commitment: impl batching updates 2026-03-11 17:07:23 +00:00
ThomasV e309f89a27 test_lnpeer: factorize test_reestablish_replay_messages 2026-03-06 09:28:05 +01:00
SomberNight db003257ff tests: lnpeer: make mpp_cleanup_after_expiry more robust
As there are two htlcs, the `alice_htlc_resolved` Event might get set either once or twice by the time `alice_htlc_resolved.wait()` returns. The previous code was assuming that both htlcs are resolved by then, but it could happen that only one htlc was resolved, due to timing.
2026-03-04 18:12:53 +00: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
f321x ddb01f5355 lnpeer: don't save our own channel update as remote upd
I noticed CLN is sending our own channel update to us on
reestablishment, we then assume it to be the remote nodes
update and try to verify the signature against their pubkey
which fails and throws `InvalidGossipMsg`.

This adds a check preventing us from trying to save our own
channel updates as remote update.
2026-02-23 17:12:15 +01:00
ghost43 b7e58f659a Merge pull request #10448 from f321x/gossip_0126
lnpeermgr: fix proxy check in add_peer, don't connect to onion peers if no proxy
2026-01-29 18:52:10 +00:00
ThomasV 9aa2898c15 test_lnpeer: fix typo in test_reestablish 2026-01-29 14:16:20 +01:00
f321x db6b6a16f8 lnpeermgr: add_peer: fix check if proxy enabled
LNPeerManager.add_peer would only check if self.network.proxy is set,
which it is always as Network is initialized with self.proxy =
ProxySettings(). Instead it should check if proxy is set and enabled.
2026-01-27 12:49:19 +01:00
f321x dee2371738 test_lnpeer: use PeerInTests instead if Peer
ec65c53 replaces the usage of `PeerInTest` with `Peer` in
test_lnpeer.py.
PeerInTests sets `Peer.DELAY_INC_MSG_PROCESSING_SLEEP` to 0 so all
incoming messages get processed immediately. Because `Peer` instead of
`TestInPeer` was used the delay caused `test_reestablish_with_old_state`
to fail regularly because bob receives the old channel state and kills
the OldTaskGroup of the unittest with GracefulDisconnect before Alice
processed the answer of Bob and is still in ChannelState.REESTABLISHING.

```
FAILED tests/test_lnpeer.py::TestPeerDirect::test_reestablish_with_old_state - AssertionError: <PeerState.REESTABLISHING: 1> != <PeerState.BAD: 3>
```
2026-01-08 14:57:13 +01:00
SomberNight 927724145a tests: rm some more dead code 2026-01-05 15:56:13 +00:00
SomberNight 0afd433c42 tests: properly clean-up MockLNWallets after tests finish 2026-01-05 15:56:10 +00:00
SomberNight dfeb9918d8 tests: lnchannel: rewrite create_test_channels to use LNWallet 2026-01-05 15:56:04 +00:00
SomberNight 17f41044d5 tests: lnpeer: fix cyclic lnworker.wallet.lnworker inconsistency
These better hold, lol:
wallet.lnworker.wallet == wallet
lnworker.wallet.lnworker == lnworker
2026-01-05 15:56:01 +00:00
SomberNight ea42b02ceb tests: simplify MockLNWallet, add fixme for cyclic inconsistency 2026-01-05 15:55:58 +00:00
SomberNight 91b98240dc tests: lnpeer: follow-up prev: rm horrible ugly hack 2026-01-05 15:55:54 +00:00
SomberNight ec65c53de3 tests: lnpeer: mostly unify prepare_peers and prepare_graph 2026-01-05 15:55:51 +00:00
SomberNight 024f9b988d tests: lnpeer: (move-only) towards unifying prepare_{peers,graph} 2026-01-05 15:55:48 +00:00
SomberNight 17b7974800 tests: lnpeer: simplify tx_queue 2026-01-05 15:55:45 +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
ghost43 bdcd3f9c7c Merge pull request #10364 from f321x/test_dont_settle_htlcs_forwarding
lnpeer/lnworker: check dont_settle_htlcs when forwarding
2025-12-30 16:13:16 +00:00
SomberNight 08f101a7e5 tests: lnpeer/onion_msg: rm dead code 2025-12-19 14:53:28 +00:00
SomberNight 5e53f82bc6 tests: lnpeer: simplify MockNetwork: rm dead code
not needed since https://github.com/spesmilo/electrum/commit/92244041081db96b92925c9e76b117035e241011
2025-12-15 15:38:16 +00:00
f321x e0b835eee6 tests: rm TestPeerDirect::test_dont_settle_htlcs
The new test
TestPeerForwarding::test_dont_settle_htlcs_receiver_and_forwarder covers
the receiver as well as the forwarder. So this unittest becomes obsolete
as it only tests the receiver.
2025-12-15 10:36:14 +01:00
f321x cd1157ec14 tests: lnpeer: test_dont_settle_htlc_receiver_and_forwarder 2025-12-15 10:36:12 +01:00
f321x b4fc39ca5f test: lnpeer: add test_decode_short_ids 2025-12-11 15:53:30 +01:00
f321x 7c01d9db75 tests: lnpeer: add test_reject_mpp_for_non_mpp_invoice 2025-12-10 10:36:41 +01:00
f321x 183d426e93 lnpeer: fail htlcs if we get unwanted mpp
Fail incoming htlcs if we receive a payment consisting of multiple parts
if we signaled to not want mpp in the invoice.
2025-12-10 10:36:39 +01:00
f321x 125a921cc4 lnworker: add invoice features to PaymentInfo class
Adds the invoice features to the `PaymentInfo` class so we can check if
the sender respects our requested features (e.g. if they tried to send
mpp if we requested no mpp).
2025-12-10 10:36:31 +01:00
f321x 923d48f9db lnworker: differentiate PaymentInfo by direction
Allows storing two different payment info of the same payment hash by
including the direction into the db key.
We create and store PaymentInfo for sending attempts and for requests (receiving),
if we try to pay ourself (e.g. through a channel rebalance) the checks
in `save_payment_info` would prevent this and throw an exception.
By storing the PaymentInfos of outgoing and incoming payments separately in
the db this collision is avoided and it makes it easier to reason about
which PaymentInfo belongs where.
2025-12-01 18:39:56 +01:00
f321x 59586d6f94 tests: lnpeer: add test_payment_with_malformed_onion
Adds a simple forwarding test where the receiver fails a malformed onion with
`update_fail_malformed_htlc`.
2025-11-27 17:58:51 +01:00
f321x 1fd5458b0e tests: lnpeer: test_dont_expire_htlcs
Adds unittest to test the dont_expire_htlcs logic
2025-11-27 17:58:47 +01:00
f321x 4f2e1b65f0 tests: test_lnpeer: add test_dont_settle_htlcs
Adds test for the dont_settle_htlcs functionality of lnworker used by
Just-In-Time channels.
2025-11-27 17:58:46 +01:00
f321x abc469c846 lnworker: split dont_settle_htlcs
Splits `LNWallet.dont_settle_htlcs` into `LNWallet.dont_settle_htlcs`
and `LNWallet.dont_expire_htlcs`.

Registering a payment hash in dont_settle_htlcs will prevent it from
getting fulfilled if we have the preimage stored. The preimage will not
be released before the the payment hash gets removed from
dont_settle_htlcs. Htlcs can still get expired as usual or failed if no
preimage is known.
This is only used by Just-in-time channel openings.

Registering a payment hash in dont_expire_htlcs allows to overwrite the
minimum final cltv delta value after which htlcs would usually get
expired. This allows to delay expiry of htlcs or, if the value in the
dont_settle_htlcs dict is None, completely prevent expiry and let the
htlc get expired onchain.

Splitting this up in two different dicts makes it more explicit and
easier to reason about what they are actually doing.

 Please enter the commit message for your changes. Lines starting
2025-11-27 17:58:44 +01:00
f321x b1e58450bd tests: test_lnpeer: add test_payment_bundle_with_hold_invoice
Adds test_payment_bundle_with_hold_invoice to simulate the use of a
payment bundle in which one invoice of the bundle needs to trigger a hold invoice
callback (similar to submarine swaps).
Also modifies the test helper _test_simple_payment() to compare the
results of all payment attempts instead of just returning after the
first (of multiple) payments raises its result causing the test to miss
if all payments were successful or not.
2025-11-27 17:58:43 +01:00
f321x 042557da9b tests: test_lnpeer: test_htlc_switch_iteration_benchmark
Benchmark how long a call to _run_htlc_switch_iteration takes with 10
trampoline mpp sets of 1 htlc each.
2025-11-27 17:58:40 +01:00
f321x f56b13b610 tests: test_lnpeer: test_hold_invoice_set_doesnt_get_exp
Add test `test_hold_invoice_set_doesnt_get_expired` to test_lnpeer to
ensure a mpp set on which a hold invoice callback doesn't get expired
automatically if the cltv_abs falls below MIN_FINAL_CLTV_DELTA_ACCEPTED
as these sets should only get failed if the htlcs are safe to fail by
the target of the hold invoice callback (e.g. swap got refunded
successfully).
2025-11-27 17:58:38 +01:00
f321x bb828097b3 tests: test_lnpeer: test compare trampoline onions
Adds test_forwarder_fails_for_inconsistent_trampoline_onions
which checks that a forwarder compares the trampoline onions of a mpp
set and fails the set if the onions are not similar.
In the test alice sends a mpp through bob with 2 htlcs, in one
trampoline onion amt_to_forward is off by 1 msat so bob fails the htlc
set instead of initiating the trampoline forwarding.
2025-11-27 17:58:34 +01:00
f321x 447d91d7b6 tests: lnpeer: test_trampoline_mpp_consolidation_forwarding_amount
Add sanity check that bob is not forwarding more sats to carol if than
he receives from alice. (he only forwards once and doesn't try to
forward multiple times).
This should get caught by asserts in lnworker/lnpeer, nevertheless it
seems to make sense to just add this test to prevent regressions of this
kind.
2025-11-27 17:57:26 +01:00
f321x f35b353841 tests: lnpeer: test_mpp_cleanup_after_expiry
1. Alice sends two HTLCs to Bob, not reaching total_msat,
   and eventually they MPP_TIMEOUT
2. Bob fails both HTLCs
3. Alice then retries and sends HTLCs again to Bob, for the same RHASH,
   this time reaching total_msat, and the payment succeeds

Test that the sets are properly cleaned up after MPP_TIMEOUT
and the sender gets a second chance to pay the same invoice.
2025-11-27 17:57:25 +01:00
f321x a91f7c519f tests: lnpeer: test_dont_settle_partial_mpp_trigger_with_invalid_cltv_htlc
Adds unittest to verify that lnpeer doesn't settle any htlcs of
incomplete mpp.
2025-11-27 17:57:23 +01:00
f321x a7de8de5a2 tests: lnpeer: test_reject_multiple_payments_of_same_invoice
Test that lnpeer rejects incoming htlcs for payments that have already
been paid so invoices cannot be paid twice.
2025-11-27 17:57:21 +01:00
f321x 7840df2e0d tests: lnpeer: test_reject_payment_for_expired_invoice
Test that lnpeer is rejecting incoming htlcs for invoices that are
already expired.
2025-11-27 17:57:19 +01:00
f321x da5f59903d tests: lnpeer: test_reject_invalid_min_final_cltv_delta
Add `test_reject_invalid_min_final_cltv_delta` which is supposed to test
that the peer rejects incoming htlcs with final cltv delta differing
from what has been requested in the lightning invoice.
2025-11-27 17:57:18 +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
f321x 41d391a617 Fix: For inner trampoline onions amt_to_forward can be larger than the htlc amount
Add unittest to TestPeerForwarding which sends a multi trampoline
payment.

Wait another htlc_switch iteration in tests because trampolines might have different delays
2025-11-27 17:44:31 +01:00
f321x 196cc33c1c ln: fix race when doing concurrent ln payments
There is a race when initiating multiple lightning payments concurrently
(e.g. when doing a reverse swap with prepayment + swap payment).
suggest_splits might overallocate
split amounts for a channel as the splitting of both invoice amounts runs
concurrently and before acutal htlcs that reduce the channels balance
have been added to the channel yet. This results in a "not
enough balance" PaymentFailure once we try to send the htlcs and the
other payment attempt already reduced the available balance of the
channel.

This fix takes a lock from splitting the amount until the htlcs are
put on the channel, so suggest_splits always acts on the correct channel
balance.
2025-11-27 16:43:40 +01:00
SomberNight e53666ac86 lnworker: follow-up prev: split pay_to_node 2025-11-07 15:37:49 +00:00
f321x 286fc4b86e lnworker: enforce creation of PaymentInfo for b11
Enforce that the information used to create a bolt11 invoice using
`get_bolt11_invoice()` is similar to the related instance of PaymentInfo
by requiring a PaymentInfo as argument for `get_bolt11_invoice()`.
This way the invoice cannot differ from the created PaymentInfo.
This allows to use the information in PaymentInfo for validation of
incoming htlcs more reliably.

To cover all required information for the creation of a b11 invoice the
PaymentInfo class has to be extended with a expiry and
min_final_cltv_expiry. This requires a db upgrade.
2025-09-30 09:54:35 +02:00