Skip to content

Commit a5f9037

Browse files
committed
Do not Send FundingLocked messages while disconnected
While its generally harmless to do so (the messages will simply be dropped in `PeerManager`) there is a potential race condition where the FundingLocked message enters the outbound message queue, then the peer reconnects, and then the FundingLocked message is delivered prior to the normal ChannelReestablish flow. We also take this opportunity to rewrite `test_funding_peer_disconnect` to be explicit instead of using `reconnect_peers`. This allows it to check each message being sent carefully, whereas `reconnect_peers` is rather lazy and accepts that sometimes signatures will be exchanged, and sometimes not.
1 parent 7011624 commit a5f9037

File tree

2 files changed

+84
-36
lines changed

2 files changed

+84
-36
lines changed

lightning/src/ln/channel.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4175,11 +4175,13 @@ impl<Signer: Sign> Channel<Signer> {
41754175

41764176
if need_commitment_update {
41774177
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
4178-
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
4179-
return Some(msgs::FundingLocked {
4180-
channel_id: self.channel_id,
4181-
next_per_commitment_point,
4182-
});
4178+
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
4179+
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
4180+
return Some(msgs::FundingLocked {
4181+
channel_id: self.channel_id,
4182+
next_per_commitment_point,
4183+
});
4184+
}
41834185
} else {
41844186
self.monitor_pending_funding_locked = true;
41854187
}

lightning/src/ln/functional_tests.rs

Lines changed: 77 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3620,15 +3620,7 @@ fn test_funding_peer_disconnect() {
36203620

36213621
confirm_transaction(&nodes[0], &tx);
36223622
let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
3623-
let chan_id;
3624-
assert_eq!(events_1.len(), 1);
3625-
match events_1[0] {
3626-
MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
3627-
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
3628-
chan_id = msg.channel_id;
3629-
},
3630-
_ => panic!("Unexpected event"),
3631-
}
3623+
assert!(events_1.is_empty());
36323624

36333625
reconnect_nodes(&nodes[0], &nodes[1], (false, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
36343626

@@ -3637,53 +3629,107 @@ fn test_funding_peer_disconnect() {
36373629

36383630
confirm_transaction(&nodes[1], &tx);
36393631
let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
3640-
assert_eq!(events_2.len(), 2);
3641-
let funding_locked = match events_2[0] {
3632+
assert!(events_2.is_empty());
3633+
3634+
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
3635+
let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
3636+
nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
3637+
let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
3638+
3639+
// nodes[0] hasn't yet received a funding_locked, so it only sends that on reconnect.
3640+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
3641+
let events_3 = nodes[0].node.get_and_clear_pending_msg_events();
3642+
assert_eq!(events_3.len(), 1);
3643+
let as_funding_locked = match events_3[0] {
3644+
MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
3645+
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
3646+
msg.clone()
3647+
},
3648+
_ => panic!("Unexpected event {:?}", events_3[0]),
3649+
};
3650+
3651+
// nodes[1] received nodes[0]'s funding_locked on the first reconnect above, so it should send
3652+
// announcement_signatures as well as channel_update.
3653+
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reestablish);
3654+
let events_4 = nodes[1].node.get_and_clear_pending_msg_events();
3655+
assert_eq!(events_4.len(), 3);
3656+
let chan_id;
3657+
let bs_funding_locked = match events_4[0] {
36423658
MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
36433659
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
3660+
chan_id = msg.channel_id;
36443661
msg.clone()
36453662
},
3646-
_ => panic!("Unexpected event"),
3663+
_ => panic!("Unexpected event {:?}", events_4[0]),
36473664
};
3648-
let bs_announcement_sigs = match events_2[1] {
3665+
let bs_announcement_sigs = match events_4[1] {
36493666
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
36503667
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
36513668
msg.clone()
36523669
},
3653-
_ => panic!("Unexpected event"),
3670+
_ => panic!("Unexpected event {:?}", events_4[1]),
36543671
};
3672+
match events_4[2] {
3673+
MessageSendEvent::SendChannelUpdate { ref node_id, msg: _ } => {
3674+
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
3675+
},
3676+
_ => panic!("Unexpected event {:?}", events_4[2]),
3677+
}
36553678

3656-
reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
3679+
// Re-deliver nodes[0]'s funding_locked, which nodes[1] can safely ignore. It currently
3680+
// generates a duplicative announcement_signatures
3681+
nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &as_funding_locked);
3682+
let events_5 = nodes[1].node.get_and_clear_pending_msg_events();
3683+
assert_eq!(events_5.len(), 1);
3684+
match events_5[0] {
3685+
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
3686+
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
3687+
assert_eq!(*msg, bs_announcement_sigs);
3688+
},
3689+
_ => panic!("Unexpected event {:?}", events_5[0]),
3690+
};
36573691

3658-
nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &funding_locked);
3659-
nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
3660-
let events_3 = nodes[0].node.get_and_clear_pending_msg_events();
3661-
assert_eq!(events_3.len(), 2);
3662-
let as_announcement_sigs = match events_3[0] {
3692+
// When we deliver nodes[1]'s funding_locked, however, nodes[0] will generate its
3693+
// announcement_signatures.
3694+
nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &bs_funding_locked);
3695+
let events_6 = nodes[0].node.get_and_clear_pending_msg_events();
3696+
assert_eq!(events_6.len(), 1);
3697+
let as_announcement_sigs = match events_6[0] {
36633698
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
36643699
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
36653700
msg.clone()
36663701
},
3667-
_ => panic!("Unexpected event"),
3702+
_ => panic!("Unexpected event {:?}", events_6[0]),
36683703
};
3669-
let (as_announcement, as_update) = match events_3[1] {
3704+
3705+
// When we deliver nodes[1]'s announcement_signatures to nodes[0], nodes[0] should immediately
3706+
// broadcast the channel announcement globally, as well as re-send its (now-public)
3707+
// channel_update.
3708+
nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
3709+
let events_7 = nodes[0].node.get_and_clear_pending_msg_events();
3710+
assert_eq!(events_7.len(), 1);
3711+
let (chan_announcement, as_update) = match events_7[0] {
36703712
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
36713713
(msg.clone(), update_msg.clone())
36723714
},
3673-
_ => panic!("Unexpected event"),
3715+
_ => panic!("Unexpected event {:?}", events_7[0]),
36743716
};
36753717

3718+
// Finally, deliver nodes[0]'s announcement_signatures to nodes[1] and make sure it creates the
3719+
// same channel_announcement.
36763720
nodes[1].node.handle_announcement_signatures(&nodes[0].node.get_our_node_id(), &as_announcement_sigs);
3677-
let events_4 = nodes[1].node.get_and_clear_pending_msg_events();
3678-
assert_eq!(events_4.len(), 1);
3679-
let (_, bs_update) = match events_4[0] {
3721+
let events_8 = nodes[1].node.get_and_clear_pending_msg_events();
3722+
assert_eq!(events_8.len(), 1);
3723+
let bs_update = match events_8[0] {
36803724
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
3681-
(msg.clone(), update_msg.clone())
3725+
assert_eq!(*msg, chan_announcement);
3726+
update_msg.clone()
36823727
},
3683-
_ => panic!("Unexpected event"),
3728+
_ => panic!("Unexpected event {:?}", events_8[0]),
36843729
};
36853730

3686-
nodes[0].net_graph_msg_handler.handle_channel_announcement(&as_announcement).unwrap();
3731+
// Provide the channel announcement and public updates to the network graph
3732+
nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).unwrap();
36873733
nodes[0].net_graph_msg_handler.handle_channel_update(&bs_update).unwrap();
36883734
nodes[0].net_graph_msg_handler.handle_channel_update(&as_update).unwrap();
36893735

@@ -3731,14 +3777,14 @@ fn test_funding_peer_disconnect() {
37313777

37323778
reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
37333779

3734-
// as_announcement should be re-generated exactly by broadcast_node_announcement.
3780+
// The channel announcement should be re-generated exactly by broadcast_node_announcement.
37353781
nodes[0].node.broadcast_node_announcement([0, 0, 0], [0; 32], Vec::new());
37363782
let msgs = nodes[0].node.get_and_clear_pending_msg_events();
37373783
let mut found_announcement = false;
37383784
for event in msgs.iter() {
37393785
match event {
37403786
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, .. } => {
3741-
if *msg == as_announcement { found_announcement = true; }
3787+
if *msg == chan_announcement { found_announcement = true; }
37423788
},
37433789
MessageSendEvent::BroadcastNodeAnnouncement { .. } => {},
37443790
_ => panic!("Unexpected event"),

0 commit comments

Comments
 (0)