Skip to content

Conversation

@f321x
Copy link
Member

@f321x f321x commented Oct 21, 2025

This makes LNWallet.pay_to_node() wait
PaySession.TIMEOUT_WAIT_FOR_NEXT_RESOLVED_HTLC (0.5 sec) for another htlc to get resolved after receiving a htlc failure during a payment attempt.
This seems to make payments more reliable in scenarios where we receive multiple htlc failures closely after each other as LNWallet.create_route_for_payment() then has access to the failed routes/failure information of all these htlcs when trying to re-split the outstanding amount.
I especially noticed the improvement when running this test on top of #10230 which would otherwise fail regularly:

Unittest
diff --git a/tests/test_lnpeer.py b/tests/test_lnpeer.py
index dee22229e..c7fa6314d 100644
--- a/tests/test_lnpeer.py
+++ b/tests/test_lnpeer.py
@@ -1960,7 +1960,8 @@ class TestPeerForwarding(TestPeer):
                     bob_pubkey=keys[b].pubkey,
                     local_msat=channel_def['local_balance_msat'],
                     remote_msat=channel_def['remote_balance_msat'],
-                    anchor_outputs=self.TEST_ANCHOR_CHANNELS
+                    anchor_outputs=self.TEST_ANCHOR_CHANNELS,
+                    max_accepted_htlcs=20,
                 )
                 channels[(a, b)], channels[(b, a)] = channel_ab, channel_ba
                 transport_ab, transport_ba = transport_pair(keys[a], keys[b], channel_ab.name, channel_ba.name)
@@ -2585,6 +2586,35 @@ class TestPeerForwarding(TestPeer):
             await self._run_trampoline_payment(
                 graph, sender_name='alice', destination_name='edward',tf_names=('bob', 'dave'))
 
+    async def test_multi_trampoline_payment(self):
+        """
+        Alice splits her payment to Dave between two trampoline forwarding nodes Carol and Bob.
+        This should test Multi-Trampoline MPP:
+        https://github.com/lightning/bolts/blob/bc7a1a0bc97b2293e7f43dd8a06529e5fdcf7cd2/proposals/trampoline.md#multi-trampoline-mpp
+        """
+        graph_definition = self.GRAPH_DEFINITIONS['square_graph']
+        # payment amount is 100_000_000 msat, size the channels so that alice must use both to succeed
+        graph_definition['alice']['channels']['bob']['local_balance_msat'] = int(100_000_000 * 0.75)
+        graph_definition['alice']['channels']['carol']['local_balance_msat'] = int(100_000_000 * 0.75)
+        g = self.prepare_chans_and_peers_in_graph(graph_definition)
+        w = g.workers['alice'], g.workers['carol'], g.workers['bob'], g.workers['dave']
+        alice_w, carol_w, bob_w, dave_w = w
+
+        alice_w.config.TEST_FORCE_MPP = True
+        bob_w.config.TEST_FORCE_MPP = True
+        carol_w.config.TEST_FORCE_MPP = True
+        dave_w.features |= LnFeatures.BASIC_MPP_OPT
+        # alice_w.config.INITIAL_TRAMPOLINE_FEE_LEVEL = 6
+
+        with self.assertRaises(PaymentDone):
+            await self._run_trampoline_payment(
+                g,
+                sender_name='alice',
+                destination_name='dave',
+                tf_names=('bob', 'carol'),
+                attempts=30,  # the default used in LNWallet.pay_invoice()
+            )
+
     async def test_forwarder_fails_for_inconsistent_trampoline_onions(self):
         """
         verify that the receiver of a trampoline forwarding fails the mpp set

This makes `LNWallet.pay_to_node()` wait
`PaySession.TIMEOUT_WAIT_FOR_NEXT_RESOLVED_HTLC` (0.5 sec) for another
htlc to get resolved after receiving a htlc failure during a payment
attempt.
This seems to make payments more reliable in scenarios where we receive
multiple htlc failures closely after each other as
`create_route_for_payment` then has access to the failed routes/failure
information of all these htlcs when trying to re-split the outstanding
amount.
@f321x f321x changed the title lnworker: collect failed htlcs in payment, fix todo lnworker: collect failed htlcs during payment attempt, fix todo Oct 21, 2025
@SomberNight SomberNight merged commit 7cb5621 into spesmilo:master Nov 7, 2025
12 of 16 checks passed
@SomberNight
Copy link
Member

Thanks. I added a follow-up that split things up a bit for more readability.

@f321x f321x deleted the lnpay_collect_failed_htlcs branch November 7, 2025 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants