Skip to content

Commit

Permalink
Fix missing ChannelPending and ChannelReady flags, by clearing corres…
Browse files Browse the repository at this point in the history
…ponding state flags in
  • Loading branch information
optout21 committed May 3, 2024
1 parent a957229 commit 421e5da
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 18 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Client LDK Counterparty node (acceptor)
internal_splice() - ChannelManager
Do checks. Check if channel ID would change. Cycle back the channel to UnfundedInboundV2
splice_start() -- ChannelContext
Start the splice, update capacity, state, reset funding transaction
Start the splice, update capacity, state to NegotiatingFunding, reset funding transaction
get_splice_ack() -- Channel
begin_interactive_funding_tx_construction() - Channel
begin_interactive_funding_tx_construction() - ChannelContext
Expand All @@ -68,7 +68,7 @@ Client LDK Counterparty node (acceptor)
Do checks, check against initial splice()
Cycle back the channel to UnfundedOutboundV2
splice_start() -- ChannelContext
Start the splice, update capacity, state, reset funding transaction
Start the splice, update capacity, state to NegotiatingFunding, reset funding transaction
event: SpliceAckedInputsContributionReady
contains the pre & post capacities, channel ID
---
Expand All @@ -93,6 +93,7 @@ provide extra input(s) for new funding
message out: tx_add_output - for change
message in: tx_complete
message out: tx_add_output - for new funding

message in: tx_complete
handle_tx_complete() - ChannelManager
internal_tx_complete() -- ChannelManager
Expand All @@ -102,7 +103,7 @@ provide extra input(s) for new funding
get_initial_commitment_signed() - Channel
Splicing-specific: Add signature on the previous funding tx input
Mark finished interactive tx construction
Update channel state (FundingNegotiated)
Update channel state to FundingNegotiated
event: FundingTransactionReadyForSigning
contains the new funding transaction with the signature on the previous tx input
message out: commitment_signed (UpdateHTLCs)
Expand All @@ -127,15 +128,15 @@ action by client: Create and provide signature on the extra inputs
get_initial_commitment_signed() - Channel
Splicing-specific: Add signature on the previous funding tx input
Mark finished interactive tx construction
Update channel state (FundingNegotiated)
Update channel state to FundingNegotiated
message out: commitment_signed (UpdateHTLCs)
channel state: Funded
---
message in: commitment_signed (UpdateHTLCs)
handle_commitment_signed() - ChannelManager
internal_commitment_signed() -- ChannelManager
commitment_signed_initial_v2() -- Channel
Update channel state to AwaitingChannelReadyFlags
Update channel state to AwaitingChannelReady
watch_channel() - ChainMonitor
received_commitment_signed() -- InteractiveTxSigningSession
---
Expand All @@ -156,6 +157,7 @@ action by client: Create and provide signature on the extra inputs
received_tx_signatures() -- InteractiveTxSigningSession
Update signature on previous tx input (with shared signature)
Update channel state to AwaitingChannelReady
event: ChannelPending
Save funding transaction
message out: tx_signatures
funding transaction is ready, broadcast it
Expand All @@ -168,6 +170,7 @@ action by client: Create and provide signature on the extra inputs
received_tx_signatures() -- InteractiveTxSigningSession
Update signature on previous tx input (with shared signature)
Update channel state to AwaitingChannelReady
event: ChannelPending
Save funding transaction
funding transaction is ready, broadcast it
---
Expand All @@ -185,9 +188,11 @@ Waiting for confirmation
---
message in: channel_ready
handle_channel_ready() - ChannelManager
event: ChannelReady
message out: channel_update
message in: channel_ready
handle_channel_ready() - ChannelManager
event: ChannelReady
message out: channel_update
/end of sequence/

Expand Down
4 changes: 4 additions & 0 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3881,6 +3881,10 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
self.funding_tx_confirmed_in = None;
self.funding_tx_confirmation_height = 0;

// Clear these state flags, for sending `ChannelPending` and `ChannelReady` again
self.channel_pending_event_emitted = false;
self.channel_ready_event_emitted = false;

log_trace!(logger, "Splicing process started, new channel value {}, channel_id {}", self.channel_value_satoshis, self.channel_id);

Ok(())
Expand Down
62 changes: 49 additions & 13 deletions lightning/src/ln/functional_tests_splice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,8 +1096,18 @@ fn test_v2_splice_in() {
};

let _res = initiator_node.node.handle_tx_signatures(&acceptor_node.node.get_our_node_id(), &tx_signatures_1);
let events_0 = initiator_node.node.get_and_clear_pending_events();
assert_eq!(events_0.len(), 0);

let events = initiator_node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::ChannelPending { channel_id, former_temporary_channel_id, counterparty_node_id, funding_txo, .. } => {
assert_eq!(channel_id.to_string(), expected_funded_channel_id);
// TODO check if former_temporary_channel_id should be set to empty in this case (or previous non-temp channel id?)
assert_eq!(former_temporary_channel_id.unwrap().to_string(), expected_temporary_channel_id);
assert_eq!(counterparty_node_id, acceptor_node.node.get_our_node_id());
}
_ => panic!("ChannelPending event missing, {:?}", events[0]),
};
let msg_events = initiator_node.node.get_and_clear_pending_msg_events();
assert_eq!(msg_events.len(), 1);
let tx_signatures_0 = match msg_events[0] {
Expand All @@ -1117,8 +1127,17 @@ fn test_v2_splice_in() {

let _res = acceptor_node.node.handle_tx_signatures(&initiator_node.node.get_our_node_id(), &tx_signatures_0);

let events_1 = acceptor_node.node.get_and_clear_pending_events();
assert_eq!(events_1.len(), 0);
let events = acceptor_node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::ChannelPending { channel_id, former_temporary_channel_id, counterparty_node_id, funding_txo, .. } => {
assert_eq!(channel_id.to_string(), expected_funded_channel_id);
// TODO check if former_temporary_channel_id should be set to empty in this case (or previous non-temp channel id?)
assert_eq!(former_temporary_channel_id.unwrap().to_string(), expected_temporary_channel_id);
assert_eq!(counterparty_node_id, initiator_node.node.get_our_node_id());
}
_ => panic!("ChannelPending event missing, {:?}", events[0]),
};

// Check that funding transaction has been broadcasted
assert_eq!(chanmon_cfgs[initiator_node_index].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 2);
Expand Down Expand Up @@ -1157,19 +1176,36 @@ fn test_v2_splice_in() {
confirm_transaction(&acceptor_node, &broadcasted_splice_tx);
let channel_ready_message2 = get_event_msg!(acceptor_node, MessageSendEvent::SendChannelReady, initiator_node.node.get_our_node_id());

let _res = initiator_node.node.handle_channel_ready(&acceptor_node.node.get_our_node_id(), &channel_ready_message2);
// let _ev = get_event!(initiator_node, Event::ChannelReady);
let events = initiator_node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::ChannelReady { channel_id, counterparty_node_id, .. } => {
assert_eq!(channel_id.to_string(), expected_funded_channel_id);
assert_eq!(counterparty_node_id, acceptor_node.node.get_our_node_id());
}
_ => panic!("ChannelReady event missing, {:?}", events[0]),
};
let _channel_update = get_event_msg!(initiator_node, MessageSendEvent::SendChannelUpdate, acceptor_node.node.get_our_node_id());

let _res = acceptor_node.node.handle_channel_ready(&initiator_node.node.get_our_node_id(), &channel_ready_message);
// let _ev = get_event!(acceptor_node, Event::ChannelReady);
let events_0 = acceptor_node.node.get_and_clear_pending_events();
assert_eq!(events_0.len(), 0);
let events = acceptor_node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::ChannelReady { channel_id, counterparty_node_id, .. } => {
assert_eq!(channel_id.to_string(), expected_funded_channel_id);
assert_eq!(counterparty_node_id, initiator_node.node.get_our_node_id());
}
_ => panic!("ChannelReady event missing, {:?}", events[0]),
};
let _channel_update = get_event_msg!(acceptor_node, MessageSendEvent::SendChannelUpdate, initiator_node.node.get_our_node_id());
// let _announcement_signatures2 = get_event_msg!(acceptor_node, MessageSendEvent::SendAnnouncementSignatures, initiator_node.node.get_our_node_id());

let _res = initiator_node.node.handle_channel_ready(&acceptor_node.node.get_our_node_id(), &channel_ready_message2);
// let _ev = get_event!(initiator_node, Event::ChannelReady);
let events_0 = initiator_node.node.get_and_clear_pending_events();
assert_eq!(events_0.len(), 0);
let _channel_update = get_event_msg!(initiator_node, MessageSendEvent::SendChannelUpdate, acceptor_node.node.get_our_node_id());
// let _announcement_signatures1 = get_event_msg!(initiator_node, MessageSendEvent::SendAnnouncementSignatures, acceptor_node.node.get_our_node_id());
let events = initiator_node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 0);
let events = acceptor_node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 0);

// check new channel capacity and other parameters
assert_eq!(initiator_node.node.list_channels().len(), 1);
Expand Down

0 comments on commit 421e5da

Please sign in to comment.