-
Notifications
You must be signed in to change notification settings - Fork 130
Expose ChannelDetails::channel_shutdown_state
#827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -145,7 +145,7 @@ 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; | ||
| use lightning::ln::channelmanager::PaymentId; | ||
| use lightning::ln::msgs::SocketAddress; | ||
| use lightning::routing::gossip::NodeAlias; | ||
|
|
@@ -173,7 +173,10 @@ use types::{ | |
| HRNResolver, KeysManager, OnionMessenger, PaymentStore, PeerManager, Router, Scorer, Sweeper, | ||
| Wallet, | ||
| }; | ||
| pub use types::{ChannelDetails, CustomTlvRecord, PeerDetails, SyncAndAsyncKVStore, UserChannelId}; | ||
| pub use types::{ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Rather than re-exporting via |
||
| ChannelDetails, ChannelShutdownState, CustomTlvRecord, PeerDetails, SyncAndAsyncKVStore, | ||
| UserChannelId, | ||
| }; | ||
| pub use vss_client; | ||
|
|
||
| use crate::scoring::setup_background_pathfinding_scores_sync; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ use bitcoin_payment_instructions::onion_message_resolver::LDKOnionMessageDNSSECH | |
| 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; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Let's drop the |
||
| use lightning::ln::msgs::{RoutingMessageHandler, SocketAddress}; | ||
| use lightning::ln::peer_handler::IgnoringMessageHandler; | ||
| use lightning::ln::types::ChannelId; | ||
|
|
@@ -529,6 +530,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. | ||
| /// | ||
| /// Returns `None` for `ChannelDetails` serialized on LDK versions prior to 0.0.116. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| pub channel_shutdown_state: Option<ChannelShutdownState>, | ||
| } | ||
|
|
||
| impl From<LdkChannelDetails> for ChannelDetails { | ||
|
|
@@ -584,6 +589,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, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
|
@@ -918,6 +918,28 @@ 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 on either side. | ||
| for channel in node_a.list_channels() { | ||
| assert!( | ||
| matches!( | ||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| ), | ||
| "Expected no shutdown in progress on node_a, got {:?}", | ||
| channel.channel_shutdown_state, | ||
| ); | ||
| } | ||
| for channel in node_b.list_channels() { | ||
| assert!( | ||
| matches!( | ||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| ), | ||
| "Expected no shutdown in progress on node_b, got {:?}", | ||
| channel.channel_shutdown_state, | ||
| ); | ||
| } | ||
|
|
||
| println!("\nB receive"); | ||
| let invoice_amount_1_msat = 2500_000; | ||
| let invoice_description: Bolt11InvoiceDescription = | ||
|
|
@@ -1233,6 +1255,20 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>( | |
| expect_channel_ready_event!(node_a, node_b.node_id()); | ||
| expect_channel_ready_event!(node_b, node_a.node_id()); | ||
|
|
||
| // After the splice-out, the channel must still report no shutdown in progress. | ||
| for channel in node_a.list_channels() { | ||
| assert!(matches!( | ||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| } | ||
| for channel in node_b.list_channels() { | ||
| assert!(matches!( | ||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| } | ||
|
|
||
| assert_eq!( | ||
| node_a | ||
| .list_payments_with_filter(|p| p.direction == PaymentDirection::Inbound | ||
|
|
@@ -1255,6 +1291,20 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>( | |
| expect_channel_ready_event!(node_a, node_b.node_id()); | ||
| expect_channel_ready_event!(node_b, node_a.node_id()); | ||
|
|
||
| // After the splice-in, the channel must still report no shutdown in progress. | ||
| for channel in node_a.list_channels() { | ||
| assert!(matches!( | ||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| } | ||
| for channel in node_b.list_channels() { | ||
| assert!(matches!( | ||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| } | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, if we add all these assertions for |
||
| assert_eq!( | ||
| node_a | ||
| .list_payments_with_filter(|p| p.direction == PaymentDirection::Outbound | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,7 +33,7 @@ use ldk_node::payment::{ | |
| ConfirmationStatus, PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus, | ||
| UnifiedPaymentResult, | ||
| }; | ||
| use ldk_node::{Builder, Event, NodeError}; | ||
| use ldk_node::{Builder, ChannelShutdownState, Event, NodeError}; | ||
| use lightning::ln::channelmanager::PaymentId; | ||
| use lightning::routing::gossip::{NodeAlias, NodeId}; | ||
| use lightning::routing::router::RouteParametersConfig; | ||
|
|
@@ -2108,24 +2108,26 @@ async fn lsps2_client_trusts_lsp() { | |
|
|
||
| service_node.sync_wallets().unwrap(); | ||
| client_node.sync_wallets().unwrap(); | ||
| assert_eq!( | ||
| client_node | ||
| .list_channels() | ||
| .iter() | ||
| .find(|c| c.counterparty_node_id == service_node_id) | ||
| .unwrap() | ||
| .confirmations, | ||
| Some(0) | ||
| ); | ||
| assert_eq!( | ||
| service_node | ||
| .list_channels() | ||
| .iter() | ||
| .find(|c| c.counterparty_node_id == client_node_id) | ||
| .unwrap() | ||
| .confirmations, | ||
| Some(0) | ||
| ); | ||
| let client_channel = client_node | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? |
||
| .list_channels() | ||
| .into_iter() | ||
| .find(|c| c.counterparty_node_id == service_node_id) | ||
| .unwrap(); | ||
| assert_eq!(client_channel.confirmations, Some(0)); | ||
| assert!(matches!( | ||
| client_channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| let service_channel = service_node | ||
| .list_channels() | ||
| .into_iter() | ||
| .find(|c| c.counterparty_node_id == client_node_id) | ||
| .unwrap(); | ||
| assert_eq!(service_channel.confirmations, Some(0)); | ||
| assert!(matches!( | ||
| service_channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
|
|
||
| // Now claim the JIT payment, which should release the funding transaction | ||
| let service_fee_msat = (jit_amount_msat * channel_opening_fee_ppm as u64) / 1_000_000; | ||
|
|
@@ -2152,24 +2154,26 @@ async fn lsps2_client_trusts_lsp() { | |
| generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; | ||
| service_node.sync_wallets().unwrap(); | ||
| client_node.sync_wallets().unwrap(); | ||
| assert_eq!( | ||
| client_node | ||
| .list_channels() | ||
| .iter() | ||
| .find(|c| c.counterparty_node_id == service_node_id) | ||
| .unwrap() | ||
| .confirmations, | ||
| Some(6) | ||
| ); | ||
| assert_eq!( | ||
| service_node | ||
| .list_channels() | ||
| .iter() | ||
| .find(|c| c.counterparty_node_id == client_node_id) | ||
| .unwrap() | ||
| .confirmations, | ||
| Some(6) | ||
| ); | ||
| let client_channel = client_node | ||
| .list_channels() | ||
| .into_iter() | ||
| .find(|c| c.counterparty_node_id == service_node_id) | ||
| .unwrap(); | ||
| assert_eq!(client_channel.confirmations, Some(6)); | ||
| assert!(matches!( | ||
| client_channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| let service_channel = service_node | ||
| .list_channels() | ||
| .into_iter() | ||
| .find(|c| c.counterparty_node_id == client_node_id) | ||
| .unwrap(); | ||
| assert_eq!(service_channel.confirmations, Some(6)); | ||
| assert!(matches!( | ||
| service_channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| } | ||
|
|
||
| #[tokio::test(flavor = "multi_thread", worker_threads = 1)] | ||
|
|
@@ -2280,24 +2284,26 @@ async fn lsps2_lsp_trusts_client_but_client_does_not_claim() { | |
| generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; | ||
| service_node.sync_wallets().unwrap(); | ||
| client_node.sync_wallets().unwrap(); | ||
| assert_eq!( | ||
| client_node | ||
| .list_channels() | ||
| .iter() | ||
| .find(|c| c.counterparty_node_id == service_node_id) | ||
| .unwrap() | ||
| .confirmations, | ||
| Some(6) | ||
| ); | ||
| assert_eq!( | ||
| service_node | ||
| .list_channels() | ||
| .iter() | ||
| .find(|c| c.counterparty_node_id == client_node_id) | ||
| .unwrap() | ||
| .confirmations, | ||
| Some(6) | ||
| ); | ||
| let client_channel = client_node | ||
| .list_channels() | ||
| .into_iter() | ||
| .find(|c| c.counterparty_node_id == service_node_id) | ||
| .unwrap(); | ||
| assert_eq!(client_channel.confirmations, Some(6)); | ||
| assert!(matches!( | ||
| client_channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| let service_channel = service_node | ||
| .list_channels() | ||
| .into_iter() | ||
| .find(|c| c.counterparty_node_id == client_node_id) | ||
| .unwrap(); | ||
| assert_eq!(service_channel.confirmations, Some(6)); | ||
| assert!(matches!( | ||
| service_channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| } | ||
|
|
||
| #[tokio::test(flavor = "multi_thread", worker_threads = 1)] | ||
|
|
@@ -2672,6 +2678,10 @@ async fn open_channel_with_all_with_anchors() { | |
| 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!( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
|
|
||
| node_a.stop().unwrap(); | ||
| node_b.stop().unwrap(); | ||
|
|
@@ -2723,6 +2733,10 @@ async fn open_channel_with_all_without_anchors() { | |
| assert!(channel.channel_value_sats > premine_amount_sat - 500); | ||
| assert_eq!(channel.counterparty_node_id, node_b.node_id()); | ||
| assert_eq!(channel.funding_txo.unwrap(), funding_txo); | ||
| assert!(matches!( | ||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
|
|
||
| node_a.stop().unwrap(); | ||
| node_b.stop().unwrap(); | ||
|
|
@@ -2766,6 +2780,10 @@ async fn splice_in_with_all_balance() { | |
| assert_eq!(channels.len(), 1); | ||
| assert_eq!(channels[0].channel_value_sats, channel_amount_sat); | ||
| assert_eq!(channels[0].funding_txo.unwrap(), funding_txo); | ||
| assert!(matches!( | ||
| channels[0].channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
|
|
||
| let balance_before_splice = node_a.list_balances().spendable_onchain_balance_sats; | ||
| assert!(balance_before_splice > 0); | ||
|
|
@@ -2787,6 +2805,10 @@ async fn splice_in_with_all_balance() { | |
| let channels = node_a.list_channels(); | ||
| assert_eq!(channels.len(), 1); | ||
| let channel = &channels[0]; | ||
| assert!(matches!( | ||
| channel.channel_shutdown_state, | ||
| None | Some(ChannelShutdownState::NotShuttingDown) | ||
| )); | ||
| assert!( | ||
| channel.channel_value_sats > premine_amount_sat - anchor_reserve_sat - 1000, | ||
| "Channel value {} should be close to premined amount {} minus anchor reserve {} and fees", | ||
|
|
||
There was a problem hiding this comment.
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?