Skip to content

Commit a024930

Browse files
committed
f - Attempt to handle channel monitor update error at shutdown
1 parent 353d295 commit a024930

File tree

1 file changed

+77
-32
lines changed

1 file changed

+77
-32
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
12591259
pub fn close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError> {
12601260
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
12611261

1262-
let (mut failed_htlcs, chan_option) = {
1262+
let mut error_to_handle = None;
1263+
let (counterparty_node_id, shutdown_msg, mut failed_htlcs, chan_option) = {
12631264
let mut channel_state_lock = self.channel_state.lock().unwrap();
12641265
let channel_state = &mut *channel_state_lock;
12651266
match channel_state.by_id.entry(channel_id.clone()) {
@@ -1273,35 +1274,57 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
12731274
}
12741275
};
12751276
let (shutdown_msg, monitor_update, failed_htlcs) = chan_entry.get_mut().get_shutdown(&self.keys_manager, &their_features)?;
1276-
channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
1277-
node_id: counterparty_node_id,
1278-
msg: shutdown_msg
1279-
});
1277+
1278+
// Update the monitor with the shutdown script if necessary.
12801279
if let Some(monitor_update) = monitor_update {
1281-
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
1282-
// TODO: How should this be handled?
1283-
unimplemented!();
1280+
if let Err(e) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
1281+
error_to_handle = Some(handle_monitor_err!(self, e, channel_state.short_to_id, chan_entry.get_mut(), RAACommitmentOrder::CommitmentFirst, false, false, Vec::new(), Vec::new(), chan_entry.key()));
12841282
}
12851283
}
1286-
if chan_entry.get().is_shutdown() {
1284+
1285+
// Clean up the channel mappings if necessary.
1286+
let remove_chan_entry = {
1287+
if chan_entry.get().is_shutdown() { true }
1288+
else if let Some((_, is_permanent)) = error_to_handle { is_permanent }
1289+
else { false }
1290+
};
1291+
let chan_option = if remove_chan_entry {
12871292
if let Some(short_id) = chan_entry.get().get_short_channel_id() {
12881293
channel_state.short_to_id.remove(&short_id);
12891294
}
1290-
(failed_htlcs, Some(chan_entry.remove_entry().1))
1291-
} else { (failed_htlcs, None) }
1295+
Some(chan_entry.remove_entry().1)
1296+
} else { None };
1297+
1298+
(counterparty_node_id, shutdown_msg, failed_htlcs, chan_option)
12921299
},
12931300
hash_map::Entry::Vacant(_) => return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()})
12941301
}
12951302
};
1303+
12961304
for htlc_source in failed_htlcs.drain(..) {
12971305
self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() });
12981306
}
1307+
1308+
// Handle any ChannelMonitorUpdateErr, exiting early if it resulted in a force close.
1309+
if let Some((error, is_permanent)) = error_to_handle {
1310+
let _ = handle_error!(self, error, counterparty_node_id);
1311+
if is_permanent {
1312+
return Ok(());
1313+
}
1314+
}
1315+
1316+
// Send the shutdown message since any ChannelMonitorUpdateErr would have been temporary.
1317+
let mut channel_state = self.channel_state.lock().unwrap();
1318+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
1319+
node_id: counterparty_node_id,
1320+
msg: shutdown_msg
1321+
});
1322+
12991323
let chan_update = if let Some(chan) = chan_option {
13001324
self.get_channel_update_for_broadcast(&chan).ok()
13011325
} else { None };
13021326

13031327
if let Some(update) = chan_update {
1304-
let mut channel_state = self.channel_state.lock().unwrap();
13051328
channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
13061329
msg: update
13071330
});
@@ -3172,7 +3195,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31723195
}
31733196

31743197
fn internal_shutdown(&self, counterparty_node_id: &PublicKey, their_features: &InitFeatures, msg: &msgs::Shutdown) -> Result<(), MsgHandleErrInternal> {
3175-
let (mut dropped_htlcs, chan_option) = {
3198+
let mut error_to_handle = None;
3199+
let (shutdown, closing_signed, mut dropped_htlcs, chan_option) = {
31763200
let mut channel_state_lock = self.channel_state.lock().unwrap();
31773201
let channel_state = &mut *channel_state_lock;
31783202

@@ -3181,41 +3205,62 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
31813205
if chan_entry.get().get_counterparty_node_id() != *counterparty_node_id {
31823206
return Err(MsgHandleErrInternal::send_err_msg_no_close("Got a message for a channel from the wrong node!".to_owned(), msg.channel_id));
31833207
}
3208+
31843209
let (shutdown, closing_signed, monitor_update, dropped_htlcs) = try_chan_entry!(self, chan_entry.get_mut().shutdown(&self.fee_estimator, &self.keys_manager, &their_features, &msg), channel_state, chan_entry);
3185-
if let Some(msg) = shutdown {
3186-
channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
3187-
node_id: counterparty_node_id.clone(),
3188-
msg,
3189-
});
3190-
}
3191-
if let Some(msg) = closing_signed {
3192-
channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned {
3193-
node_id: counterparty_node_id.clone(),
3194-
msg,
3195-
});
3196-
}
3210+
3211+
// Update the monitor with the shutdown script if necessary.
31973212
if let Some(monitor_update) = monitor_update {
3198-
if let Err(_) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
3199-
// TODO: How should this be handled?
3200-
unimplemented!();
3213+
if let Err(e) = self.chain_monitor.update_channel(chan_entry.get().get_funding_txo().unwrap(), monitor_update) {
3214+
error_to_handle = Some(handle_monitor_err!(self, e, channel_state.short_to_id, chan_entry.get_mut(), RAACommitmentOrder::CommitmentFirst, false, false, Vec::new(), Vec::new(), chan_entry.key()));
32013215
}
32023216
}
3203-
if chan_entry.get().is_shutdown() {
3217+
3218+
// Clean up the channel mappings if necessary.
3219+
let remove_chan_entry = {
3220+
if chan_entry.get().is_shutdown() { true }
3221+
else if let Some((_, is_permanent)) = error_to_handle { is_permanent }
3222+
else { false }
3223+
};
3224+
let chan_option = if remove_chan_entry {
32043225
if let Some(short_id) = chan_entry.get().get_short_channel_id() {
32053226
channel_state.short_to_id.remove(&short_id);
32063227
}
3207-
(dropped_htlcs, Some(chan_entry.remove_entry().1))
3208-
} else { (dropped_htlcs, None) }
3228+
Some(chan_entry.remove_entry().1)
3229+
} else { None };
3230+
3231+
(shutdown, closing_signed, dropped_htlcs, chan_option)
32093232
},
32103233
hash_map::Entry::Vacant(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("Failed to find corresponding channel".to_owned(), msg.channel_id))
32113234
}
32123235
};
32133236
for htlc_source in dropped_htlcs.drain(..) {
32143237
self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() });
32153238
}
3239+
3240+
// Handle any ChannelMonitorUpdateErr, exiting early if it resulted in a force close.
3241+
if let Some((error, is_permanent)) = error_to_handle {
3242+
let _ = handle_error!(self, error, *counterparty_node_id);
3243+
if is_permanent {
3244+
return Ok(());
3245+
}
3246+
}
3247+
3248+
// Send the shutdown message since any ChannelMonitorUpdateErr would have been temporary.
3249+
let mut channel_state = self.channel_state.lock().unwrap();
3250+
if let Some(msg) = shutdown {
3251+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown {
3252+
node_id: *counterparty_node_id,
3253+
msg,
3254+
});
3255+
}
3256+
if let Some(msg) = closing_signed {
3257+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendClosingSigned {
3258+
node_id: *counterparty_node_id,
3259+
msg,
3260+
});
3261+
}
32163262
if let Some(chan) = chan_option {
32173263
if let Ok(update) = self.get_channel_update_for_broadcast(&chan) {
3218-
let mut channel_state = self.channel_state.lock().unwrap();
32193264
channel_state.pending_msg_events.push(events::MessageSendEvent::BroadcastChannelUpdate {
32203265
msg: update
32213266
});

0 commit comments

Comments
 (0)