Skip to content

Expose pending HTLCs and channel dust exposure - #1103

Open
tnull wants to merge 1 commit into
lightningdevkit:mainfrom
tnull:2026-09-expose-channel-htlc-details
Open

tnull wants to merge 1 commit into
lightningdevkit:mainfrom
tnull:2026-09-expose-channel-htlc-details

Conversation

@tnull

@tnull tnull commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Make pending payment state and dust exposure available to callers so they can inspect stalled payments and assess force-close risk. Also expose the maximum splice-out amount to help plan withdrawals.

Expose the same information through Rust and the language bindings.

Rust and UniFFI checks, unit tests, the new integration test in both configurations, doctests, and binding generation pass. The full integration run had two failures in existing tests. Both passed in isolation, but channel_full_cycle_force_close_trusted_no_reserve failed again with Bitcoin Core RPC at tests/common/mod.rs:632. Its clean-main run passed, so the cause remains unresolved. UniFFI rustdoc also fails on three broken links reproduced on main.

Fixes #1102

@ldk-reviews-bot

ldk-reviews-bot commented Sep 17, 2026 •

Copy link
Copy Markdown

👋 I see @tankyleo was un-assigned.
If you'd like another reviewer assignment, please click here.

@f3r10 f3r10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks, this looks good to me overall, and the test covering a dust and a non-dust HTLC at the same time is nice.

And about that comment on the commit: I ran channel_full_cycle_force_close_trusted_no_reserve 5× on this branch (4 pass, 1 fail [panic: …]) and 5× on the parent commit (5 pass). That's too few runs to tell whether the test is flaky or something changed here, but since this diff only adds read-only fields to ChannelDetails and nothing in the force-close path touches them, I'd expect a pre-existing flake.

Comment thread src/types.rs Outdated
@tnull
tnull force-pushed the 2026-09-expose-channel-htlc-details branch from 7e6c231 to 9113433 Compare September 21, 2026 11:35
@tnull

tnull commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

And about that comment on the commit: I ran channel_full_cycle_force_close_trusted_no_reserve 5× on this branch (4 pass, 1 fail [panic: …]) and 5× on the parent commit (5 pass). That's too few runs to tell whether the test is flaky or something changed here, but since this diff only adds read-only fields to ChannelDetails and nothing in the force-close path touches them, I'd expect a pre-existing flake.

Yeah, it's flaky currently.

@tnull tnull added this to the 0.8 milestone Sep 22, 2026
@tnull
tnull force-pushed the 2026-09-expose-channel-htlc-details branch from 9113433 to 5467061 Compare September 22, 2026 13:11
@tnull
tnull requested review from tankyleo and removed request for TheBlueMatt October 15, 2026 11:24
@tnull

tnull commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

Reassigning @tankyleo .

@tankyleo tankyleo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  • Can we remove the splice_amount_msat > channel_details.outbound_capacity_msat check in src/lib.rs, fn splice_out ? There are cases where a user can specify an amount greater than the outbound capacity of the channel and still get a successful splice. We should let rust-lightning be fully responsible for validating the amount that the user wants to withdraw from the channel.
  • If we proceed with this, we will also want to update let excessive_splice_out_sats = node_a.list_channels()[0].outbound_capacity_msat / 1000 + 1; to use the new splice out maximum in tests/integration_tests_rust.rs.
  • Perhaps this is also a TODO in the rust-lightning documentation, but it might be worth clarifying in the docs here that passing next_splice_out_maximum_sat directly to fn splice_out will not work: the fn splice_out specifies the value of the spliced output, and this amount plus the fees of the splice transaction needs to be smaller than next_splice_out_maximum_sat.
  • A follow-up to this PR could be adding a splice_out_with_all function similar to the current splice_in_with_all.
  • Do we need to update the pending changelog with the new fields ?

Comment thread tests/integration_tests_rust.rs
Comment thread tests/integration_tests_rust.rs Outdated
@tnull

tnull commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author
  • Can we remove the splice_amount_msat > channel_details.outbound_capacity_msat check in src/lib.rs, fn splice_out ? There are cases where a user can specify an amount greater than the outbound capacity of the channel and still get a successful splice. We should let rust-lightning be fully responsible for validating the amount that the user wants to withdraw from the channel.

Not sure. It's there intentionally to abort early for impossible cases. What are the cases that still would allow a successful splice?

Make pending payment state and dust exposure available to callers so
that they can inspect stalled payments and assess force-close risk.
Also expose the maximum splice-out amount to help plan withdrawals.

Expose the same information through Rust and the language bindings.
Check that settling a dust HTLC leaves the non-dust HTLC committed
with no dust exposure, and match payment failures to their IDs.

Fixes lightningdevkit#1102
Co-Authored-By: HAL 9000
@tnull
tnull force-pushed the 2026-09-expose-channel-htlc-details branch from 5467061 to ad03a6f Compare October 16, 2026 12:58
@tnull
tnull requested a review from tankyleo October 16, 2026 12:58
@tankyleo

Copy link
Copy Markdown
Contributor

Not sure. It's there intentionally to abort early for impossible cases. What are the cases that still would allow a successful splice?

Using outbound_capacity_msat as your splice out maximum does not account for the reduced channel reserve as a result of the new reduced size of the channel. This is why we added next_splice_out_maximum_sat.

How about we keep the guard, but replace outbound_capacity_msat with next_splice_out_maximum_sat on that guard ? This would keep the early abort for the cases we know for sure are not possible.

Below is a case codex reproduced where it withdrew an amount greater than the outbound capacity of the channel:

  A funded a 500,000-sat channel, pushing 450,000 sats to B. B performed the splice-out, with no pending HTLCs.

   Parameter                           Before splice      After splice
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  ━━━━━━━━━━━━━━━━  ━━━━━━━━━━━━━━━━
   Channel value                        500,000 sats       52,322 sats
  ─────────────────────────────────  ────────────────  ────────────────
   B’s Lightning balance                450,000 sats        2,322 sats
  ─────────────────────────────────  ────────────────  ────────────────
   B’s required channel reserve           5,000 sats          523 sats
  ─────────────────────────────────  ────────────────  ────────────────
   B’s outbound_capacity_msat            445,000,000         1,799,000
  ─────────────────────────────────  ────────────────  ────────────────
   B’s next_splice_out_maximum_sat      449,495 sats        1,817 sats
  ─────────────────────────────────  ────────────────  ────────────────
   B’s on-chain wallet balance        1,000,000 sats    1,447,495 sats

  The actual splice transaction had:

  • Withdrawal output: 447,495 sats — 2,495 sats above the original outbound capacity.
  • Transaction fee: 183 sats, measured from the transaction’s input minus outputs.
  • Total channel debit: 447,678 sats, below the reported maximum of 449,495 sats.
  • New channel funding output: 52,322 sats.

  The reserve reduction makes this valid:

  New reserve:       floor(52,322 / 100) = 523 sats
  B’s remaining balance: 450,000 − 447,495 − 183 = 2,322 sats

  2,322 sats satisfies the new 523-sat reserve, even though it is below the old 5,000-sat reserve.

@tankyleo
tankyleo removed their request for review October 16, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose pending HTLCs and dust exposure in ChannelDetails

4 participants