-
Notifications
You must be signed in to change notification settings - Fork 113
Channel splicing support #677
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
92a4598
1218b25
3e5d836
03f7bbe
a1150c1
3fb9744
1549605
a4e7b44
98a348b
af45025
d14d2ce
b13f2a1
c2fcde7
30d08b3
5e6ac23
83e5d14
b5ef24d
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 |
|---|---|---|
|
|
@@ -199,6 +199,10 @@ pub enum Event { | |
| funding_txo: OutPoint, | ||
| }, | ||
| /// A channel is ready to be used. | ||
| /// | ||
| /// This event is emitted when: | ||
| /// - A new channel has been established and is ready for use | ||
| /// - An existing channel has been spliced and is ready with the new funding output | ||
| ChannelReady { | ||
| /// The `channel_id` of the channel. | ||
| channel_id: ChannelId, | ||
|
|
@@ -208,6 +212,14 @@ pub enum Event { | |
| /// | ||
| /// This will be `None` for events serialized by LDK Node v0.1.0 and prior. | ||
| counterparty_node_id: Option<PublicKey>, | ||
| /// The outpoint of the channel's funding transaction. | ||
| /// | ||
| /// This represents the channel's current funding output, which may change when the | ||
| /// channel is spliced. For spliced channels, this will contain the new funding output | ||
| /// from the confirmed splice transaction. | ||
| /// | ||
| /// This will be `None` for events serialized by LDK Node v0.6.0 and prior. | ||
| funding_txo: Option<OutPoint>, | ||
| }, | ||
| /// A channel has been closed. | ||
| ChannelClosed { | ||
|
|
@@ -222,6 +234,28 @@ pub enum Event { | |
| /// This will be `None` for events serialized by LDK Node v0.2.1 and prior. | ||
| reason: Option<ClosureReason>, | ||
| }, | ||
| /// A channel splice is pending confirmation on-chain. | ||
| SplicePending { | ||
| /// The `channel_id` of the channel. | ||
| channel_id: ChannelId, | ||
| /// The `user_channel_id` of the channel. | ||
| user_channel_id: UserChannelId, | ||
| /// The `node_id` of the channel counterparty. | ||
| counterparty_node_id: PublicKey, | ||
| /// The outpoint of the channel's splice funding transaction. | ||
| new_funding_txo: OutPoint, | ||
| }, | ||
| /// A channel splice has failed. | ||
| SpliceFailed { | ||
| /// The `channel_id` of the channel. | ||
| channel_id: ChannelId, | ||
| /// The `user_channel_id` of the channel. | ||
| user_channel_id: UserChannelId, | ||
| /// The `node_id` of the channel counterparty. | ||
| counterparty_node_id: PublicKey, | ||
| /// The outpoint of the channel's splice funding transaction. | ||
| abandoned_funding_txo: Option<OutPoint>, | ||
|
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. Why is this field optional?
Contributor
Author
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. It's optional in the LDK event because the splice may fail before the funding tx is negotiated.
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. Ah. Maybe it's worth adding a comment explaining this here and (more explicitly) on the LDK event field? |
||
| }, | ||
| } | ||
|
|
||
| impl_writeable_tlv_based_enum!(Event, | ||
|
|
@@ -246,6 +280,7 @@ impl_writeable_tlv_based_enum!(Event, | |
| (0, channel_id, required), | ||
| (1, counterparty_node_id, option), | ||
| (2, user_channel_id, required), | ||
| (3, funding_txo, option), | ||
| }, | ||
| (4, ChannelPending) => { | ||
| (0, channel_id, required), | ||
|
|
@@ -278,7 +313,19 @@ impl_writeable_tlv_based_enum!(Event, | |
| (10, skimmed_fee_msat, option), | ||
| (12, claim_from_onchain_tx, required), | ||
| (14, outbound_amount_forwarded_msat, option), | ||
| } | ||
| }, | ||
| (8, SplicePending) => { | ||
| (1, channel_id, required), | ||
| (3, counterparty_node_id, required), | ||
| (5, user_channel_id, required), | ||
| (7, new_funding_txo, required), | ||
| }, | ||
| (9, SpliceFailed) => { | ||
| (1, channel_id, required), | ||
| (3, counterparty_node_id, required), | ||
| (5, user_channel_id, required), | ||
| (7, abandoned_funding_txo, option), | ||
| }, | ||
| ); | ||
|
|
||
| pub struct EventQueue<L: Deref> | ||
|
|
@@ -1363,14 +1410,28 @@ where | |
| } | ||
| }, | ||
| LdkEvent::ChannelReady { | ||
| channel_id, user_channel_id, counterparty_node_id, .. | ||
| channel_id, | ||
| user_channel_id, | ||
| counterparty_node_id, | ||
| funding_txo, | ||
| .. | ||
| } => { | ||
| log_info!( | ||
| self.logger, | ||
| "Channel {} with counterparty {} ready to be used.", | ||
| channel_id, | ||
| counterparty_node_id, | ||
| ); | ||
| if let Some(funding_txo) = funding_txo { | ||
| log_info!( | ||
| self.logger, | ||
| "Channel {} with counterparty {} ready to be used with funding_txo {}", | ||
tnull marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| channel_id, | ||
| counterparty_node_id, | ||
| funding_txo, | ||
| ); | ||
| } else { | ||
| log_info!( | ||
| self.logger, | ||
| "Channel {} with counterparty {} ready to be used", | ||
| channel_id, | ||
| counterparty_node_id, | ||
| ); | ||
| } | ||
|
|
||
| if let Some(liquidity_source) = self.liquidity_source.as_ref() { | ||
| liquidity_source | ||
|
|
@@ -1382,6 +1443,7 @@ where | |
| channel_id, | ||
| user_channel_id: UserChannelId(user_channel_id), | ||
| counterparty_node_id: Some(counterparty_node_id), | ||
| funding_txo, | ||
| }; | ||
| match self.event_queue.add_event(event) { | ||
| Ok(_) => {}, | ||
|
|
@@ -1580,20 +1642,101 @@ where | |
| } | ||
| } | ||
| }, | ||
| LdkEvent::FundingTransactionReadyForSigning { .. } => { | ||
| debug_assert!(false, "We currently don't support interactive-tx, so this event should never be emitted."); | ||
| LdkEvent::FundingTransactionReadyForSigning { | ||
| channel_id, | ||
| counterparty_node_id, | ||
| unsigned_transaction, | ||
| .. | ||
| } => match self.wallet.sign_owned_inputs(unsigned_transaction) { | ||
| Ok(partially_signed_tx) => { | ||
| match self.channel_manager.funding_transaction_signed( | ||
| &channel_id, | ||
| &counterparty_node_id, | ||
| partially_signed_tx, | ||
| ) { | ||
| Ok(()) => { | ||
| log_info!( | ||
| self.logger, | ||
| "Signed funding transaction for channel {} with counterparty {}", | ||
| channel_id, | ||
| counterparty_node_id | ||
| ); | ||
| }, | ||
| Err(e) => { | ||
| log_error!(self.logger, "Failed signing funding transaction: {:?}", e); | ||
| }, | ||
| } | ||
| }, | ||
| Err(()) => log_error!(self.logger, "Failed signing funding transaction"), | ||
| }, | ||
| LdkEvent::SplicePending { .. } => { | ||
| debug_assert!( | ||
| false, | ||
| "We currently don't support splicing, so this event should never be emitted." | ||
| LdkEvent::SplicePending { | ||
| channel_id, | ||
| user_channel_id, | ||
| counterparty_node_id, | ||
| new_funding_txo, | ||
| .. | ||
| } => { | ||
| log_info!( | ||
| self.logger, | ||
| "Channel {} with counterparty {} pending splice with funding_txo {}", | ||
| channel_id, | ||
| counterparty_node_id, | ||
| new_funding_txo, | ||
| ); | ||
|
|
||
| let event = Event::SplicePending { | ||
| channel_id, | ||
| user_channel_id: UserChannelId(user_channel_id), | ||
| counterparty_node_id, | ||
| new_funding_txo, | ||
| }; | ||
|
|
||
| match self.event_queue.add_event(event) { | ||
| Ok(_) => {}, | ||
| Err(e) => { | ||
| log_error!(self.logger, "Failed to push to event queue: {}", e); | ||
| return Err(ReplayEvent()); | ||
| }, | ||
| }; | ||
| }, | ||
| LdkEvent::SpliceFailed { .. } => { | ||
| debug_assert!( | ||
| false, | ||
| "We currently don't support splicing, so this event should never be emitted." | ||
| ); | ||
| LdkEvent::SpliceFailed { | ||
| channel_id, | ||
| user_channel_id, | ||
| counterparty_node_id, | ||
| abandoned_funding_txo, | ||
| .. | ||
| } => { | ||
| if let Some(funding_txo) = abandoned_funding_txo { | ||
| log_info!( | ||
| self.logger, | ||
| "Channel {} with counterparty {} failed splice with funding_txo {}", | ||
| channel_id, | ||
| counterparty_node_id, | ||
| funding_txo, | ||
| ); | ||
| } else { | ||
| log_info!( | ||
| self.logger, | ||
| "Channel {} with counterparty {} failed splice", | ||
| channel_id, | ||
| counterparty_node_id, | ||
| ); | ||
| } | ||
|
|
||
| let event = Event::SpliceFailed { | ||
| channel_id, | ||
| user_channel_id: UserChannelId(user_channel_id), | ||
| counterparty_node_id, | ||
| abandoned_funding_txo, | ||
| }; | ||
|
|
||
| match self.event_queue.add_event(event) { | ||
| Ok(_) => {}, | ||
| Err(e) => { | ||
| log_error!(self.logger, "Failed to push to event queue: {}", e); | ||
| return Err(ReplayEvent()); | ||
| }, | ||
| }; | ||
| }, | ||
| } | ||
| Ok(()) | ||
|
|
@@ -1620,6 +1763,7 @@ mod tests { | |
| channel_id: ChannelId([23u8; 32]), | ||
| user_channel_id: UserChannelId(2323), | ||
| counterparty_node_id: None, | ||
| funding_txo: None, | ||
| }; | ||
| event_queue.add_event(expected_event.clone()).unwrap(); | ||
|
|
||
|
|
@@ -1656,6 +1800,7 @@ mod tests { | |
| channel_id: ChannelId([23u8; 32]), | ||
| user_channel_id: UserChannelId(2323), | ||
| counterparty_node_id: None, | ||
| funding_txo: None, | ||
| }; | ||
|
|
||
| // Check `next_event_async` won't return if the queue is empty and always rather timeout. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.