Skip to content

Commit a67d97c

Browse files
authored
Merge pull request #827 from f3r10/feat/expose_channel_shutdown_state
Expose `ChannelDetails::channel_shutdown_state`
2 parents ee6c997 + f061a14 commit a67d97c

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

src/ffi/types.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub use bitcoin::{Address, BlockHash, Network, OutPoint, ScriptBuf, Txid};
2525
pub use lightning::chain::channelmonitor::BalanceSource;
2626
use lightning::events::PaidBolt12Invoice as LdkPaidBolt12Invoice;
2727
pub use lightning::events::{ClosureReason, PaymentFailureReason};
28+
use lightning::ln::channel_state::ChannelShutdownState;
2829
use lightning::ln::channelmanager::PaymentId;
2930
use lightning::ln::msgs::DecodeError;
3031
pub use lightning::ln::types::ChannelId;
@@ -1415,6 +1416,26 @@ uniffi::custom_type!(LSPSDateTime, String, {
14151416
},
14161417
});
14171418

1419+
/// The shutdown state of a channel as returned in [`ChannelDetails::channel_shutdown_state`].
1420+
///
1421+
/// [`ChannelDetails::channel_shutdown_state`]: crate::ChannelDetails::channel_shutdown_state
1422+
#[uniffi::remote(Enum)]
1423+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1424+
pub enum ChannelShutdownState {
1425+
/// Channel has not sent or received a shutdown message.
1426+
NotShuttingDown,
1427+
/// Local node has sent a shutdown message for this channel.
1428+
ShutdownInitiated,
1429+
/// Shutdown message exchanges have concluded and the channels are in the midst of
1430+
/// resolving all existing open HTLCs before closing can continue.
1431+
ResolvingHTLCs,
1432+
/// All HTLCs have been resolved, nodes are currently negotiating channel close onchain fee rates.
1433+
NegotiatingClosingFee,
1434+
/// We've successfully negotiated a closing_signed dance. At this point `ChannelManager` is about
1435+
/// to drop the channel.
1436+
ShutdownComplete,
1437+
}
1438+
14181439
/// The reason the channel was closed. See individual variants for more details.
14191440
#[uniffi::remote(Enum)]
14201441
#[derive(Clone, Debug, PartialEq, Eq)]

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ pub use lightning;
148148
use lightning::chain::BestBlock;
149149
use lightning::impl_writeable_tlv_based;
150150
use lightning::ln::chan_utils::FUNDING_TRANSACTION_WITNESS_WEIGHT;
151-
use lightning::ln::channel_state::{ChannelDetails as LdkChannelDetails, ChannelShutdownState};
151+
use lightning::ln::channel_state::ChannelDetails as LdkChannelDetails;
152+
pub use lightning::ln::channel_state::ChannelShutdownState;
152153
use lightning::ln::channelmanager::PaymentId;
153154
use lightning::ln::msgs::SocketAddress;
154155
use lightning::routing::gossip::NodeAlias;

src/types.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use bitcoin::{OutPoint, ScriptBuf};
1515
use bitcoin_payment_instructions::onion_message_resolver::LDKOnionMessageDNSSECHrnResolver;
1616
use lightning::chain::chainmonitor;
1717
use lightning::impl_writeable_tlv_based;
18-
use lightning::ln::channel_state::ChannelDetails as LdkChannelDetails;
18+
use lightning::ln::channel_state::{ChannelDetails as LdkChannelDetails, ChannelShutdownState};
1919
use lightning::ln::msgs::{RoutingMessageHandler, SocketAddress};
2020
use lightning::ln::peer_handler::IgnoringMessageHandler;
2121
use lightning::ln::types::ChannelId;
@@ -558,6 +558,10 @@ pub struct ChannelDetails {
558558
pub inbound_htlc_maximum_msat: Option<u64>,
559559
/// Set of configurable parameters that affect channel operation.
560560
pub config: ChannelConfig,
561+
/// The current shutdown state of the channel, if any.
562+
///
563+
/// Will be `None` for objects serialized with LDK Node v0.1 and earlier.
564+
pub channel_shutdown_state: Option<ChannelShutdownState>,
561565
}
562566

563567
impl From<LdkChannelDetails> for ChannelDetails {
@@ -613,6 +617,7 @@ impl From<LdkChannelDetails> for ChannelDetails {
613617
inbound_htlc_maximum_msat: value.inbound_htlc_maximum_msat,
614618
// unwrap safety: `config` is only `None` for LDK objects serialized prior to 0.0.109.
615619
config: value.config.map(|c| c.into()).unwrap(),
620+
channel_shutdown_state: value.channel_shutdown_state,
616621
}
617622
}
618623
}

tests/common/mod.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ use ldk_node::entropy::{generate_entropy_mnemonic, NodeEntropy};
3232
use ldk_node::io::sqlite_store::SqliteStore;
3333
use ldk_node::payment::{PaymentDirection, PaymentKind, PaymentStatus};
3434
use ldk_node::{
35-
Builder, CustomTlvRecord, Event, LightningBalance, Node, NodeError, PendingSweepBalance,
36-
UserChannelId,
35+
Builder, ChannelShutdownState, CustomTlvRecord, Event, LightningBalance, Node, NodeError,
36+
PendingSweepBalance, UserChannelId,
3737
};
3838
use lightning::io;
3939
use lightning::ln::msgs::SocketAddress;
@@ -916,6 +916,12 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
916916
let user_channel_id_a = expect_channel_ready_event!(node_a, node_b.node_id());
917917
let user_channel_id_b = expect_channel_ready_event!(node_b, node_a.node_id());
918918

919+
// After channel_ready, no shutdown should be in progress.
920+
assert!(node_a.list_channels().iter().all(|c| matches!(
921+
c.channel_shutdown_state,
922+
None | Some(ChannelShutdownState::NotShuttingDown)
923+
)));
924+
919925
println!("\nB receive");
920926
let invoice_amount_1_msat = 2500_000;
921927
let invoice_description: Bolt11InvoiceDescription =
@@ -1267,6 +1273,20 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
12671273
node_a.force_close_channel(&user_channel_id_a, node_b.node_id(), None).unwrap();
12681274
} else {
12691275
node_a.close_channel(&user_channel_id_a, node_b.node_id()).unwrap();
1276+
// The cooperative shutdown may complete before we get to check, but if the channel
1277+
// is still visible it must already be in a shutdown state.
1278+
if let Some(channel) =
1279+
node_a.list_channels().into_iter().find(|c| c.user_channel_id == user_channel_id_a)
1280+
{
1281+
assert!(
1282+
!matches!(
1283+
channel.channel_shutdown_state,
1284+
None | Some(ChannelShutdownState::NotShuttingDown)
1285+
),
1286+
"Expected shutdown in progress on node_a, got {:?}",
1287+
channel.channel_shutdown_state,
1288+
);
1289+
}
12701290
}
12711291

12721292
expect_event!(node_a, ChannelClosed);

0 commit comments

Comments
 (0)