Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/ffi/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub use bitcoin::{Address, BlockHash, FeeRate, Network, OutPoint, ScriptBuf, Txi
pub use lightning::chain::channelmonitor::BalanceSource;
use lightning::events::PaidBolt12Invoice as LdkPaidBolt12Invoice;
pub use lightning::events::{ClosureReason, PaymentFailureReason};
use lightning::ln::channel_state::ChannelShutdownState;
use lightning::ln::channelmanager::PaymentId;
use lightning::ln::msgs::DecodeError;
pub use lightning::ln::types::ChannelId;
Expand Down Expand Up @@ -1408,6 +1409,26 @@ uniffi::custom_type!(LSPSDateTime, String, {
},
});

/// The shutdown state of a channel as returned in [`ChannelDetails::channel_shutdown_state`].
///
/// [`ChannelDetails::channel_shutdown_state`]: crate::ChannelDetails::channel_shutdown_state
#[uniffi::remote(Enum)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ChannelShutdownState {
/// Channel has not sent or received a shutdown message.
NotShuttingDown,
/// Local node has sent a shutdown message for this channel.
ShutdownInitiated,
/// Shutdown message exchanges have concluded and the channels are in the midst of
/// resolving all existing open HTLCs before closing can continue.
ResolvingHTLCs,
/// All HTLCs have been resolved, nodes are currently negotiating channel close onchain fee rates.
NegotiatingClosingFee,
/// We've successfully negotiated a closing_signed dance. At this point `ChannelManager` is about
/// to drop the channel.
ShutdownComplete,
}

/// The reason the channel was closed. See individual variants for more details.
#[uniffi::remote(Enum)]
#[derive(Clone, Debug, PartialEq, Eq)]
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ pub use lightning;
use lightning::chain::BestBlock;
use lightning::impl_writeable_tlv_based;
use lightning::ln::chan_utils::FUNDING_TRANSACTION_WITNESS_WEIGHT;
use lightning::ln::channel_state::{ChannelDetails as LdkChannelDetails, ChannelShutdownState};
use lightning::ln::channel_state::ChannelDetails as LdkChannelDetails;
pub use lightning::ln::channel_state::ChannelShutdownState;
use lightning::ln::channelmanager::PaymentId;
use lightning::ln::msgs::SocketAddress;
use lightning::routing::gossip::NodeAlias;
Expand Down
7 changes: 6 additions & 1 deletion src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use bitcoin::{OutPoint, ScriptBuf};
use bitcoin_payment_instructions::onion_message_resolver::LDKOnionMessageDNSSECHrnResolver;
use lightning::chain::chainmonitor;
use lightning::impl_writeable_tlv_based;
use lightning::ln::channel_state::ChannelDetails as LdkChannelDetails;
use lightning::ln::channel_state::{ChannelDetails as LdkChannelDetails, ChannelShutdownState};
use lightning::ln::msgs::{RoutingMessageHandler, SocketAddress};
use lightning::ln::peer_handler::IgnoringMessageHandler;
use lightning::ln::types::ChannelId;
Expand Down Expand Up @@ -529,6 +529,10 @@ pub struct ChannelDetails {
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.

///
/// Will be `None` for objects serialized with LDK Node v0.1 and earlier.
pub channel_shutdown_state: Option<ChannelShutdownState>,
}

impl From<LdkChannelDetails> for ChannelDetails {
Expand Down Expand Up @@ -584,6 +588,7 @@ impl From<LdkChannelDetails> for ChannelDetails {
inbound_htlc_maximum_msat: value.inbound_htlc_maximum_msat,
// unwrap safety: `config` is only `None` for LDK objects serialized prior to 0.0.109.
config: value.config.map(|c| c.into()).unwrap(),
channel_shutdown_state: value.channel_shutdown_state,
}
}
}
Expand Down
24 changes: 22 additions & 2 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ use ldk_node::entropy::{generate_entropy_mnemonic, NodeEntropy};
use ldk_node::io::sqlite_store::SqliteStore;
use ldk_node::payment::{PaymentDirection, PaymentKind, PaymentStatus};
use ldk_node::{
Builder, CustomTlvRecord, Event, LightningBalance, Node, NodeError, PendingSweepBalance,
UserChannelId,
Builder, ChannelShutdownState, CustomTlvRecord, Event, LightningBalance, Node, NodeError,
PendingSweepBalance, UserChannelId,
};
use lightning::io;
use lightning::ln::msgs::SocketAddress;
Expand Down Expand Up @@ -918,6 +918,12 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
let user_channel_id_a = expect_channel_ready_event!(node_a, node_b.node_id());
let user_channel_id_b = expect_channel_ready_event!(node_b, node_a.node_id());

// After channel_ready, no shutdown should be in progress.
assert!(node_a.list_channels().iter().all(|c| matches!(
c.channel_shutdown_state,
None | Some(ChannelShutdownState::NotShuttingDown)
)));

println!("\nB receive");
let invoice_amount_1_msat = 2500_000;
let invoice_description: Bolt11InvoiceDescription =
Expand Down Expand Up @@ -1269,6 +1275,20 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
node_a.force_close_channel(&user_channel_id_a, node_b.node_id(), None).unwrap();
} else {
node_a.close_channel(&user_channel_id_a, node_b.node_id()).unwrap();
// The cooperative shutdown may complete before we get to check, but if the channel
// is still visible it must already be in a shutdown state.
if let Some(channel) =
node_a.list_channels().into_iter().find(|c| c.user_channel_id == user_channel_id_a)
{
assert!(
!matches!(
channel.channel_shutdown_state,
None | Some(ChannelShutdownState::NotShuttingDown)
),
"Expected shutdown in progress on node_a, got {:?}",
channel.channel_shutdown_state,
);
}
}

expect_event!(node_a, ChannelClosed);
Expand Down
Loading