Skip to content

Apply MPP receive timeout to keysend payments#4558

Merged
tnull merged 1 commit intolightningdevkit:mainfrom
tnull:2026-04-fix-keysend-mpp-timeout
Apr 14, 2026
Merged

Apply MPP receive timeout to keysend payments#4558
tnull merged 1 commit intolightningdevkit:mainfrom
tnull:2026-04-fix-keysend-mpp-timeout

Conversation

@tnull
Copy link
Copy Markdown
Contributor

@tnull tnull commented Apr 13, 2026

Fixes #4553.

Incomplete keysend MPPs skipped the receive timeout path, allowing partial payments to hold HTLC slots until CLTV expiry instead of failing after MPP_TIMEOUT_TICKS. Apply the existing total_mpp_amount_msat completeness check to all MPP receives and add a regression test covering the keysend case.

The timeout logic was originally added only for
invoice-backed MPPs in 2022, and that invoice-only guard remained when receive-side MPP keysend support landed in 2023, leaving this gap latent until now.

Co-Authored-By: HAL 9000

@ldk-reviews-bot
Copy link
Copy Markdown

ldk-reviews-bot commented Apr 13, 2026

👋 Thanks for assigning @carlaKC as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@ldk-claude-review-bot
Copy link
Copy Markdown
Collaborator

ldk-claude-review-bot commented Apr 13, 2026

I've thoroughly re-reviewed the entire diff, including:

  1. The core change in channelmanager.rs (lines 8881-8900): Removal of the OnionPayload::Invoice guard so MPP timeout applies to all payment types.
  2. Condition matching: total_mpp_value <= total_intended_recvd_value in timer_tick_occurred (line 8887) correctly mirrors total_intended_recvd_value >= total_mpp_value in process_pending_htlc_forwards (line 8412).
  3. Single-path keysend safety: total_mpp_amount_msat falls back to outgoing_amt_msat for non-MPP keysend, so the completeness check passes immediately — no behavioral change for single-path keysend.
  4. Test correctness: Verified send_spontaneous_payment API usage matches the signature, RecipientOnionFields::secret_only(payment_secret, 200_000) correctly sets the total MPP amount, pass_along_path uses expected_preimage = None for incomplete first path and Some(payment_preimage) for the completing second path, and PaymentParameters::for_keysend with true enables MPP.

No issues found.

@ldk-reviews-bot ldk-reviews-bot requested a review from jkczyz April 13, 2026 09:04
Copy link
Copy Markdown
Contributor

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm - just one comment on the test

@TheBlueMatt TheBlueMatt removed the request for review from jkczyz April 13, 2026 21:19
TheBlueMatt
TheBlueMatt previously approved these changes Apr 13, 2026
Copy link
Copy Markdown
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. @carlaKC should land when she likes the test.

@tnull tnull force-pushed the 2026-04-fix-keysend-mpp-timeout branch from a3457de to c2f774d Compare April 14, 2026 08:24
@tnull tnull requested a review from carlaKC April 14, 2026 08:25
Incomplete keysend MPPs skipped the receive timeout path,
allowing partial payments to hold HTLC slots until CLTV
expiry instead of failing after `MPP_TIMEOUT_TICKS`.
Apply the existing `total_mpp_amount_msat` completeness
check to all MPP receives and add a regression test
covering the keysend case.

The timeout logic was originally added only for
invoice-backed MPPs in 2022, and that invoice-only
guard remained when receive-side MPP keysend support
landed in 2023, leaving this gap latent until now.

Co-Authored-By: HAL 9000
@tnull tnull force-pushed the 2026-04-fix-keysend-mpp-timeout branch from c2f774d to fd8846b Compare April 14, 2026 08:33
@ThomsenDrake
Copy link
Copy Markdown

LGTM. The fix is minimal and correct — applying the total_mpp_amount_msat completeness check to all MPP receive paths closes the gap where partial keysend payments could leak HTLC slots.

The regression test in payment_tests.rs is a good coverage anchor. One question: does parse_recv_partial_keysend_payment have any similar paths that bypass the timeout check?

@tnull
Copy link
Copy Markdown
Contributor Author

tnull commented Apr 14, 2026

parse_recv_partial_keysend_payment

Could you expand on what your're referring to? This method doesn't seem to exist in the codebase?

@tnull tnull merged commit 8fc122d into lightningdevkit:main Apr 14, 2026
20 of 23 checks passed
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.

Incomplete keysend MPP payments bypass MPP timeout

6 participants