Skip to content

Commit 0243f21

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 a6ddb97 commit 0243f21

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
@@ -4343,11 +4343,13 @@ impl<Signer: Sign> Channel<Signer> {
43434343

43444344
if need_commitment_update {
43454345
if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
4346-
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
4347-
return Some(msgs::FundingLocked {
4348-
channel_id: self.channel_id,
4349-
next_per_commitment_point,
4350-
});
4346+
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
4347+
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
4348+
return Some(msgs::FundingLocked {
4349+
channel_id: self.channel_id,
4350+
next_per_commitment_point,
4351+
});
4352+
}
43514353
} else {
43524354
self.monitor_pending_funding_locked = true;
43534355
}

lightning/src/ln/functional_tests.rs

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

38083808
confirm_transaction(&nodes[0], &tx);
38093809
let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
3810-
let chan_id;
3811-
assert_eq!(events_1.len(), 1);
3812-
match events_1[0] {
3813-
MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
3814-
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
3815-
chan_id = msg.channel_id;
3816-
},
3817-
_ => panic!("Unexpected event"),
3818-
}
3810+
assert!(events_1.is_empty());
38193811

38203812
reconnect_nodes(&nodes[0], &nodes[1], (false, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
38213813

@@ -3824,53 +3816,107 @@ fn test_funding_peer_disconnect() {
38243816

38253817
confirm_transaction(&nodes[1], &tx);
38263818
let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
3827-
assert_eq!(events_2.len(), 2);
3828-
let funding_locked = match events_2[0] {
3819+
assert!(events_2.is_empty());
3820+
3821+
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
3822+
let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
3823+
nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
3824+
let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
3825+
3826+
// nodes[0] hasn't yet received a funding_locked, so it only sends that on reconnect.
3827+
nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
3828+
let events_3 = nodes[0].node.get_and_clear_pending_msg_events();
3829+
assert_eq!(events_3.len(), 1);
3830+
let as_funding_locked = match events_3[0] {
3831+
MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
3832+
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
3833+
msg.clone()
3834+
},
3835+
_ => panic!("Unexpected event {:?}", events_3[0]),
3836+
};
3837+
3838+
// nodes[1] received nodes[0]'s funding_locked on the first reconnect above, so it should send
3839+
// announcement_signatures as well as channel_update.
3840+
nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reestablish);
3841+
let events_4 = nodes[1].node.get_and_clear_pending_msg_events();
3842+
assert_eq!(events_4.len(), 3);
3843+
let chan_id;
3844+
let bs_funding_locked = match events_4[0] {
38293845
MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
38303846
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
3847+
chan_id = msg.channel_id;
38313848
msg.clone()
38323849
},
3833-
_ => panic!("Unexpected event"),
3850+
_ => panic!("Unexpected event {:?}", events_4[0]),
38343851
};
3835-
let bs_announcement_sigs = match events_2[1] {
3852+
let bs_announcement_sigs = match events_4[1] {
38363853
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
38373854
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
38383855
msg.clone()
38393856
},
3840-
_ => panic!("Unexpected event"),
3857+
_ => panic!("Unexpected event {:?}", events_4[1]),
38413858
};
3859+
match events_4[2] {
3860+
MessageSendEvent::SendChannelUpdate { ref node_id, msg: _ } => {
3861+
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
3862+
},
3863+
_ => panic!("Unexpected event {:?}", events_4[2]),
3864+
}
38423865

3843-
reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
3866+
// Re-deliver nodes[0]'s funding_locked, which nodes[1] can safely ignore. It currently
3867+
// generates a duplicative announcement_signatures
3868+
nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &as_funding_locked);
3869+
let events_5 = nodes[1].node.get_and_clear_pending_msg_events();
3870+
assert_eq!(events_5.len(), 1);
3871+
match events_5[0] {
3872+
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
3873+
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
3874+
assert_eq!(*msg, bs_announcement_sigs);
3875+
},
3876+
_ => panic!("Unexpected event {:?}", events_5[0]),
3877+
};
38443878

3845-
nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &funding_locked);
3846-
nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
3847-
let events_3 = nodes[0].node.get_and_clear_pending_msg_events();
3848-
assert_eq!(events_3.len(), 2);
3849-
let as_announcement_sigs = match events_3[0] {
3879+
// When we deliver nodes[1]'s funding_locked, however, nodes[0] will generate its
3880+
// announcement_signatures.
3881+
nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &bs_funding_locked);
3882+
let events_6 = nodes[0].node.get_and_clear_pending_msg_events();
3883+
assert_eq!(events_6.len(), 1);
3884+
let as_announcement_sigs = match events_6[0] {
38503885
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
38513886
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
38523887
msg.clone()
38533888
},
3854-
_ => panic!("Unexpected event"),
3889+
_ => panic!("Unexpected event {:?}", events_6[0]),
38553890
};
3856-
let (as_announcement, as_update) = match events_3[1] {
3891+
3892+
// When we deliver nodes[1]'s announcement_signatures to nodes[0], nodes[0] should immediately
3893+
// broadcast the channel announcement globally, as well as re-send its (now-public)
3894+
// channel_update.
3895+
nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
3896+
let events_7 = nodes[0].node.get_and_clear_pending_msg_events();
3897+
assert_eq!(events_7.len(), 1);
3898+
let (chan_announcement, as_update) = match events_7[0] {
38573899
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
38583900
(msg.clone(), update_msg.clone())
38593901
},
3860-
_ => panic!("Unexpected event"),
3902+
_ => panic!("Unexpected event {:?}", events_7[0]),
38613903
};
38623904

3905+
// Finally, deliver nodes[0]'s announcement_signatures to nodes[1] and make sure it creates the
3906+
// same channel_announcement.
38633907
nodes[1].node.handle_announcement_signatures(&nodes[0].node.get_our_node_id(), &as_announcement_sigs);
3864-
let events_4 = nodes[1].node.get_and_clear_pending_msg_events();
3865-
assert_eq!(events_4.len(), 1);
3866-
let (_, bs_update) = match events_4[0] {
3908+
let events_8 = nodes[1].node.get_and_clear_pending_msg_events();
3909+
assert_eq!(events_8.len(), 1);
3910+
let bs_update = match events_8[0] {
38673911
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
3868-
(msg.clone(), update_msg.clone())
3912+
assert_eq!(*msg, chan_announcement);
3913+
update_msg.clone()
38693914
},
3870-
_ => panic!("Unexpected event"),
3915+
_ => panic!("Unexpected event {:?}", events_8[0]),
38713916
};
38723917

3873-
nodes[0].net_graph_msg_handler.handle_channel_announcement(&as_announcement).unwrap();
3918+
// Provide the channel announcement and public updates to the network graph
3919+
nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).unwrap();
38743920
nodes[0].net_graph_msg_handler.handle_channel_update(&bs_update).unwrap();
38753921
nodes[0].net_graph_msg_handler.handle_channel_update(&as_update).unwrap();
38763922

@@ -3918,14 +3964,14 @@ fn test_funding_peer_disconnect() {
39183964

39193965
reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
39203966

3921-
// as_announcement should be re-generated exactly by broadcast_node_announcement.
3967+
// The channel announcement should be re-generated exactly by broadcast_node_announcement.
39223968
nodes[0].node.broadcast_node_announcement([0, 0, 0], [0; 32], Vec::new());
39233969
let msgs = nodes[0].node.get_and_clear_pending_msg_events();
39243970
let mut found_announcement = false;
39253971
for event in msgs.iter() {
39263972
match event {
39273973
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, .. } => {
3928-
if *msg == as_announcement { found_announcement = true; }
3974+
if *msg == chan_announcement { found_announcement = true; }
39293975
},
39303976
MessageSendEvent::BroadcastNodeAnnouncement { .. } => {},
39313977
_ => panic!("Unexpected event"),

0 commit comments

Comments
 (0)