Skip to content

Expose ChannelDetails::channel_shutdown_state#827

Open
f3r10 wants to merge 1 commit intolightningdevkit:mainfrom
f3r10:feat/expose_channel_shutdown_state
Open

Expose ChannelDetails::channel_shutdown_state#827
f3r10 wants to merge 1 commit intolightningdevkit:mainfrom
f3r10:feat/expose_channel_shutdown_state

Conversation

@f3r10
Copy link
Copy Markdown

@f3r10 f3r10 commented Mar 14, 2026

Summary

Closes #803.

We currently don't expose ChannelDetails::channel_shutdown_state, so there is no good way for callers to tell whether a channel is actively going through a cooperative shutdown or merely has its peer temporarily disconnected — both situations cause is_usable to become false.

This PR adds:

  • A new ChannelShutdownState enum (mirroring LDK's own type) with variants NotShuttingDown, ShutdownInitiated, ResolvingHTLCs, NegotiatingClosingFee, and ShutdownComplete.
  • An Option<ChannelShutdownState> field on ChannelDetails, populated from LdkChannelDetails::channel_shutdown_state via the existing From conversion.
  • A typedef enum ChannelShutdownState entry in the UniFFI UDL so the field is available to Swift, Kotlin, and Python bindings.
  • Public re-export of ChannelShutdownState from the crate root.

@ldk-reviews-bot
Copy link
Copy Markdown

ldk-reviews-bot commented Mar 14, 2026

👋 Thanks for assigning @tnull 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-reviews-bot ldk-reviews-bot requested a review from tnull March 14, 2026 19:17
src/types.rs Outdated
pub config: ChannelConfig,
/// The current shutdown state of the channel, if any.
///
/// Returns `None` for channels that have not yet started the shutdown process.
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.

Could we replace this to accurately reflect what the source from the library says Returns None for ChannelDetails serialized on LDK versions prior to 0.0.116.

@Camillarhi
Copy link
Copy Markdown
Contributor

Thanks for looking into this. Could we add assertions for channel_shutdown_state in the existing integration tests? For example, after both nodes receive the channel_ready event in do_channel_full_cycle

@ldk-reviews-bot
Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

src/types.rs Outdated
/// [`ChannelDetails::channel_shutdown_state`]: crate::ChannelDetails::channel_shutdown_state
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
pub enum ChannelShutdownState {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we really need to duplicate this enum here, or could we get away with using the upstream one and only using #[uniffi::remote(Enum)] for uniffi?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yeah totally @tnull I am going to do that

@f3r10 f3r10 force-pushed the feat/expose_channel_shutdown_state branch from 30b610c to 32c3eef Compare March 19, 2026 16:09
@f3r10 f3r10 requested review from Camillarhi and tnull March 19, 2026 16:09
@ldk-reviews-bot
Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull @Camillarhi! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

1 similar comment
@ldk-reviews-bot
Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull @Camillarhi! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

Copy link
Copy Markdown
Collaborator

@tnull tnull left a comment

Choose a reason for hiding this comment

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

Thanks! Already looks good, just some minor remarks regarding re-exports and test coverage.

src/ffi/types.rs Outdated
pub use lightning::chain::channelmonitor::BalanceSource;
use lightning::events::PaidBolt12Invoice as LdkPaidBolt12Invoice;
pub use lightning::events::{ClosureReason, PaymentFailureReason};
pub use lightning::ln::channel_state::ChannelShutdownState;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: I believe we don't need this to be pub?

src/types.rs Outdated
use lightning::chain::chainmonitor;
use lightning::impl_writeable_tlv_based;
use lightning::ln::channel_state::ChannelDetails as LdkChannelDetails;
pub use lightning::ln::channel_state::ChannelShutdownState;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: Let's drop the pub here.

src/lib.rs Outdated
Wallet,
};
pub use types::{ChannelDetails, CustomTlvRecord, PeerDetails, SyncAndAsyncKVStore, UserChannelId};
pub use types::{
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: Rather than re-exporting via crate::types, lets just add a pub use lightning::ln::channel_state::ChannelShutdownState; line.

src/types.rs Outdated
pub config: ChannelConfig,
/// The current shutdown state of the channel, if any.
///
/// Returns `None` for `ChannelDetails` serialized on LDK versions prior to 0.0.116.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

As this is in LDK Node context, we should provide compatibility notes based on LDK Node's versions. In this case that would mean LDK Node versions prior to 0.2 (aruably that's so old we could also omit the note altogether).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I agree, I am going to remove that line

.confirmations,
Some(0)
);
let client_channel = client_node
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could you expand on why the LSPS2 tests in particular do need additional test coverage for channel shutdown?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

you are right, those tests are not necessary. I am going to revert those.

None | Some(ChannelShutdownState::NotShuttingDown)
));
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hmm, if we add all these assertions for NotShuttingDown, should we at least also add one later for a case when we are shutting down (i.e., close/force close)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I have been trying to test this part, but the problem is that for cooperative close, the shutdown completes very quickly in tests, so by the time we call list_channels() after close_channel(), the channel may already be gone.

In the force close phase, LDK doesn't use the cooperative shutdown state machine for force closes, so the field would still be None/NotShuttingDown right up until the channel disappears.

assert!(channel.channel_value_sats > premine_amount_sat - anchor_reserve_sat - 500);
assert_eq!(channel.counterparty_node_id, node_b.node_id());
assert_eq!(channel.funding_txo.unwrap(), funding_txo);
assert!(matches!(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we don't need to add all of these assertions, as the actual behavior should be tested in LDK.

@ldk-reviews-bot
Copy link
Copy Markdown

🔔 2nd Reminder

Hey @Camillarhi! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link
Copy Markdown

🔔 3rd Reminder

Hey @Camillarhi! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link
Copy Markdown

🔔 4th Reminder

Hey @Camillarhi! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link
Copy Markdown

🔔 5th Reminder

Hey @Camillarhi! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

Add a `ChannelShutdownState` enum mirroring LDK's own type, and expose
it as an `Option<ChannelShutdownState>` field on `ChannelDetails`.
@f3r10 f3r10 force-pushed the feat/expose_channel_shutdown_state branch from 32c3eef to 3b68c59 Compare March 30, 2026 16:19
@f3r10 f3r10 requested a review from tnull March 30, 2026 17:43
Copy link
Copy Markdown
Collaborator

@tnull tnull left a comment

Choose a reason for hiding this comment

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

One comment, otherwise LGTM

Though, IMO, you could further reduce the test changes. Maybe just add one at an opportune place? Asserting on NotShuttingDown over and over again isn't super helpful and just increases clutter.

pub inbound_htlc_maximum_msat: Option<u64>,
/// Set of configurable parameters that affect channel operation.
pub config: ChannelConfig,
/// The current shutdown state of the channel, if any.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please add a note that this will be None for objects first serialized with LDK Node v0.1.

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 ChannelDetails::channel_shutdown_state

4 participants