Skip to content

Commit 3c4a0c1

Browse files
authored
Merge pull request #750 from TheBlueMatt/2020-11-dup-chan-id-crash
Do not generate a channel-closed mon update for never-signed chans
2 parents 52673d4 + 36063ee commit 3c4a0c1

File tree

5 files changed

+210
-6
lines changed

5 files changed

+210
-6
lines changed

lightning/src/chain/chainmonitor.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@ where C::Target: chain::Filter,
194194
match monitors.get_mut(&funding_txo) {
195195
None => {
196196
log_error!(self.logger, "Failed to update channel monitor: no such monitor registered");
197+
198+
// We should never ever trigger this from within ChannelManager. Technically a
199+
// user could use this object with some proxying in between which makes this
200+
// possible, but in tests and fuzzing, this should be a panic.
201+
#[cfg(any(test, feature = "fuzztarget"))]
202+
panic!("ChannelManager generated a channel update for a channel that was not yet registered!");
203+
#[cfg(not(any(test, feature = "fuzztarget")))]
197204
Err(ChannelMonitorUpdateErr::PermanentFailure)
198205
},
199206
Some(orig_monitor) => {

lightning/src/ln/channel.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4016,11 +4016,23 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
40164016
_ => {}
40174017
}
40184018
}
4019+
let funding_txo = if let Some(funding_txo) = self.funding_txo {
4020+
// If we haven't yet exchanged funding signatures (ie channel_state < FundingSent),
4021+
// returning a channel monitor update here would imply a channel monitor update before
4022+
// we even registered the channel monitor to begin with, which is invalid.
4023+
// Thus, if we aren't actually at a point where we could conceivably broadcast the
4024+
// funding transaction, don't return a funding txo (which prevents providing the
4025+
// monitor update to the user, even if we return one).
4026+
// See test_duplicate_chan_id and test_pre_lockin_no_chan_closed_update for more.
4027+
if self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::ChannelFunded as u32 | ChannelState::ShutdownComplete as u32) != 0 {
4028+
Some(funding_txo.clone())
4029+
} else { None }
4030+
} else { None };
40194031

40204032
self.channel_state = ChannelState::ShutdownComplete as u32;
40214033
self.update_time_counter += 1;
40224034
self.latest_monitor_update_id += 1;
4023-
(self.funding_txo.clone(), ChannelMonitorUpdate {
4035+
(funding_txo, ChannelMonitorUpdate {
40244036
update_id: self.latest_monitor_update_id,
40254037
updates: vec![ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast }],
40264038
}, dropped_outbound_htlcs)

lightning/src/ln/channelmanager.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2363,7 +2363,12 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
23632363
// channel, not the temporary_channel_id. This is compatible with ourselves, but the
23642364
// spec is somewhat ambiguous here. Not a huge deal since we'll send error messages for
23652365
// any messages referencing a previously-closed channel anyway.
2366-
return Err(MsgHandleErrInternal::from_finish_shutdown("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id, chan.force_shutdown(true), None));
2366+
// We do not do a force-close here as that would generate a monitor update for
2367+
// a monitor that we didn't manage to store (and that we don't care about - we
2368+
// don't respond with the funding_signed so the channel can never go on chain).
2369+
let (_funding_txo_option, _monitor_update, failed_htlcs) = chan.force_shutdown(true);
2370+
assert!(failed_htlcs.is_empty());
2371+
return Err(MsgHandleErrInternal::send_err_msg_no_close("ChannelMonitor storage failure".to_owned(), funding_msg.channel_id));
23672372
},
23682373
ChannelMonitorUpdateErr::TemporaryFailure => {
23692374
// There's no problem signing a counterparty's funding transaction if our monitor

lightning/src/ln/functional_test_utils.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,11 @@ pub fn create_announced_chan_between_nodes<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'
487487

488488
pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, channel_value: u64, push_msat: u64, a_flags: InitFeatures, b_flags: InitFeatures) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
489489
let chan_announcement = create_chan_between_nodes_with_value(&nodes[a], &nodes[b], channel_value, push_msat, a_flags, b_flags);
490+
update_nodes_with_chan_announce(nodes, a, b, &chan_announcement.0, &chan_announcement.1, &chan_announcement.2);
491+
(chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
492+
}
490493

494+
pub fn update_nodes_with_chan_announce<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, ann: &msgs::ChannelAnnouncement, upd_1: &msgs::ChannelUpdate, upd_2: &msgs::ChannelUpdate) {
491495
nodes[a].node.broadcast_node_announcement([0, 0, 0], [0; 32], Vec::new());
492496
let a_events = nodes[a].node.get_and_clear_pending_msg_events();
493497
assert_eq!(a_events.len(), 1);
@@ -509,13 +513,12 @@ pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a
509513
};
510514

511515
for node in nodes {
512-
assert!(node.net_graph_msg_handler.handle_channel_announcement(&chan_announcement.0).unwrap());
513-
node.net_graph_msg_handler.handle_channel_update(&chan_announcement.1).unwrap();
514-
node.net_graph_msg_handler.handle_channel_update(&chan_announcement.2).unwrap();
516+
assert!(node.net_graph_msg_handler.handle_channel_announcement(ann).unwrap());
517+
node.net_graph_msg_handler.handle_channel_update(upd_1).unwrap();
518+
node.net_graph_msg_handler.handle_channel_update(upd_2).unwrap();
515519
node.net_graph_msg_handler.handle_node_announcement(&a_node_announcement).unwrap();
516520
node.net_graph_msg_handler.handle_node_announcement(&b_node_announcement).unwrap();
517521
}
518-
(chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
519522
}
520523

521524
macro_rules! check_spends {

lightning/src/ln/functional_tests.rs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8457,6 +8457,43 @@ fn test_concurrent_monitor_claim() {
84578457
}
84588458
}
84598459

8460+
#[test]
8461+
fn test_pre_lockin_no_chan_closed_update() {
8462+
// Test that if a peer closes a channel in response to a funding_created message we don't
8463+
// generate a channel update (as the channel cannot appear on chain without a funding_signed
8464+
// message).
8465+
//
8466+
// Doing so would imply a channel monitor update before the initial channel monitor
8467+
// registration, violating our API guarantees.
8468+
//
8469+
// Previously, full_stack_target managed to hit this case by opening then closing a channel,
8470+
// then opening a second channel with the same funding output as the first (which is not
8471+
// rejected because the first channel does not exist in the ChannelManager) and closing it
8472+
// before receiving funding_signed.
8473+
let chanmon_cfgs = create_chanmon_cfgs(2);
8474+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
8475+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
8476+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
8477+
8478+
// Create an initial channel
8479+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
8480+
let mut open_chan_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
8481+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_msg);
8482+
let accept_chan_msg = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
8483+
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_chan_msg);
8484+
8485+
// Move the first channel through the funding flow...
8486+
let (temporary_channel_id, _tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42);
8487+
8488+
nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_output);
8489+
check_added_monitors!(nodes[0], 0);
8490+
8491+
let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
8492+
let channel_id = ::chain::transaction::OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index }.to_channel_id();
8493+
nodes[0].node.handle_error(&nodes[1].node.get_our_node_id(), &msgs::ErrorMessage { channel_id, data: "Hi".to_owned() });
8494+
assert!(nodes[0].chain_monitor.added_monitors.lock().unwrap().is_empty());
8495+
}
8496+
84608497
#[test]
84618498
fn test_htlc_no_detection() {
84628499
// This test is a mutation to underscore the detection logic bug we had
@@ -8687,3 +8724,143 @@ fn test_onchain_htlc_settlement_after_close() {
86878724
do_test_onchain_htlc_settlement_after_close(true, false);
86888725
do_test_onchain_htlc_settlement_after_close(false, false);
86898726
}
8727+
8728+
#[test]
8729+
fn test_duplicate_chan_id() {
8730+
// Test that if a given peer tries to open a channel with the same channel_id as one that is
8731+
// already open we reject it and keep the old channel.
8732+
//
8733+
// Previously, full_stack_target managed to figure out that if you tried to open two channels
8734+
// with the same funding output (ie post-funding channel_id), we'd create a monitor update for
8735+
// the existing channel when we detect the duplicate new channel, screwing up our monitor
8736+
// updating logic for the existing channel.
8737+
let chanmon_cfgs = create_chanmon_cfgs(2);
8738+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
8739+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
8740+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
8741+
8742+
// Create an initial channel
8743+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
8744+
let mut open_chan_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
8745+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_msg);
8746+
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
8747+
8748+
// Try to create a second channel with the same temporary_channel_id as the first and check
8749+
// that it is rejected.
8750+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_msg);
8751+
{
8752+
let events = nodes[1].node.get_and_clear_pending_msg_events();
8753+
assert_eq!(events.len(), 1);
8754+
match events[0] {
8755+
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
8756+
// Technically, at this point, nodes[1] would be justified in thinking both the
8757+
// first (valid) and second (invalid) channels are closed, given they both have
8758+
// the same non-temporary channel_id. However, currently we do not, so we just
8759+
// move forward with it.
8760+
assert_eq!(msg.channel_id, open_chan_msg.temporary_channel_id);
8761+
assert_eq!(node_id, nodes[0].node.get_our_node_id());
8762+
},
8763+
_ => panic!("Unexpected event"),
8764+
}
8765+
}
8766+
8767+
// Move the first channel through the funding flow...
8768+
let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42);
8769+
8770+
nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_output);
8771+
check_added_monitors!(nodes[0], 0);
8772+
8773+
let mut funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
8774+
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
8775+
{
8776+
let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
8777+
assert_eq!(added_monitors.len(), 1);
8778+
assert_eq!(added_monitors[0].0, funding_output);
8779+
added_monitors.clear();
8780+
}
8781+
let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
8782+
8783+
let funding_outpoint = ::chain::transaction::OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index };
8784+
let channel_id = funding_outpoint.to_channel_id();
8785+
8786+
// Now we have the first channel past funding_created (ie it has a txid-based channel_id, not a
8787+
// temporary one).
8788+
8789+
// First try to open a second channel with a temporary channel id equal to the txid-based one.
8790+
// Technically this is allowed by the spec, but we don't support it and there's little reason
8791+
// to. Still, it shouldn't cause any other issues.
8792+
open_chan_msg.temporary_channel_id = channel_id;
8793+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_msg);
8794+
{
8795+
let events = nodes[1].node.get_and_clear_pending_msg_events();
8796+
assert_eq!(events.len(), 1);
8797+
match events[0] {
8798+
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
8799+
// Technically, at this point, nodes[1] would be justified in thinking both
8800+
// channels are closed, but currently we do not, so we just move forward with it.
8801+
assert_eq!(msg.channel_id, open_chan_msg.temporary_channel_id);
8802+
assert_eq!(node_id, nodes[0].node.get_our_node_id());
8803+
},
8804+
_ => panic!("Unexpected event"),
8805+
}
8806+
}
8807+
8808+
// Now try to create a second channel which has a duplicate funding output.
8809+
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
8810+
let open_chan_2_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
8811+
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_2_msg);
8812+
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
8813+
create_funding_transaction(&nodes[0], 100000, 42); // Get and check the FundingGenerationReady event
8814+
8815+
let funding_created = {
8816+
let mut a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
8817+
let mut as_chan = a_channel_lock.by_id.get_mut(&open_chan_2_msg.temporary_channel_id).unwrap();
8818+
let logger = test_utils::TestLogger::new();
8819+
as_chan.get_outbound_funding_created(funding_outpoint, &&logger).unwrap()
8820+
};
8821+
check_added_monitors!(nodes[0], 0);
8822+
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
8823+
// At this point we'll try to add a duplicate channel monitor, which will be rejected, but
8824+
// still needs to be cleared here.
8825+
check_added_monitors!(nodes[1], 1);
8826+
8827+
// ...still, nodes[1] will reject the duplicate channel.
8828+
{
8829+
let events = nodes[1].node.get_and_clear_pending_msg_events();
8830+
assert_eq!(events.len(), 1);
8831+
match events[0] {
8832+
MessageSendEvent::HandleError { action: ErrorAction::SendErrorMessage { ref msg }, node_id } => {
8833+
// Technically, at this point, nodes[1] would be justified in thinking both
8834+
// channels are closed, but currently we do not, so we just move forward with it.
8835+
assert_eq!(msg.channel_id, channel_id);
8836+
assert_eq!(node_id, nodes[0].node.get_our_node_id());
8837+
},
8838+
_ => panic!("Unexpected event"),
8839+
}
8840+
}
8841+
8842+
// finally, finish creating the original channel and send a payment over it to make sure
8843+
// everything is functional.
8844+
nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed_msg);
8845+
{
8846+
let mut added_monitors = nodes[0].chain_monitor.added_monitors.lock().unwrap();
8847+
assert_eq!(added_monitors.len(), 1);
8848+
assert_eq!(added_monitors[0].0, funding_output);
8849+
added_monitors.clear();
8850+
}
8851+
8852+
let events_4 = nodes[0].node.get_and_clear_pending_events();
8853+
assert_eq!(events_4.len(), 1);
8854+
match events_4[0] {
8855+
Event::FundingBroadcastSafe { ref funding_txo, user_channel_id } => {
8856+
assert_eq!(user_channel_id, 42);
8857+
assert_eq!(*funding_txo, funding_output);
8858+
},
8859+
_ => panic!("Unexpected event"),
8860+
};
8861+
8862+
let (funding_locked, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
8863+
let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked);
8864+
update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update);
8865+
send_payment(&nodes[0], &[&nodes[1]], 8000000, 8_000_000);
8866+
}

0 commit comments

Comments
 (0)