Skip to content

Commit 9a9716d

Browse files
Ack monitor events on check_free_peer_holding_cells
Currently, the resolution of HTLCs (and decisions on when HTLCs can be forwarded) is the responsibility of Channel objects (a part of ChannelManager) until the channel is closed, and then the ChannelMonitor thereafter. This leads to some complexity around race conditions for HTLCs right around channel closure. Additionally, there is lots of complexity reconstructing the state of all HTLCs in the ChannelManager deserialization/loading logic. Instead, we want to do all resolution in ChannelMonitors (in response to ChannelMonitorUpdates) and pass them back to ChannelManager in the form of MonitorEvents (similar to how HTLCs are resolved after channels are closed). In order to have reliable resolution, we'll need to keep MonitorEvents around in the ChannelMonitor until the ChannelManager has finished processing them. This will simplify things - on restart instead of examining the set of HTLCs in monitors we can simply replay all the pending MonitorEvents. Here we build on recent commits by ACK'ing monitor events for forward failures once the monitor update that marks them as failed on the inbound edge is complete.
1 parent b8bb43b commit 9a9716d

2 files changed

Lines changed: 50 additions & 23 deletions

File tree

lightning/src/ln/channel.rs

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8331,7 +8331,7 @@ where
83318331
/// returns `(None, Vec::new())`.
83328332
pub fn maybe_free_holding_cell_htlcs<F: FeeEstimator, L: Logger>(
83338333
&mut self, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
8334-
) -> (Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>) {
8334+
) -> (Option<(ChannelMonitorUpdate, Vec<MonitorEventSource>)>, Vec<(HTLCSource, PaymentHash)>) {
83358335
if matches!(self.context.channel_state, ChannelState::ChannelReady(_))
83368336
&& self.context.channel_state.can_generate_new_commitment()
83378337
{
@@ -8345,7 +8345,7 @@ where
83458345
/// for our counterparty.
83468346
fn free_holding_cell_htlcs<F: FeeEstimator, L: Logger>(
83478347
&mut self, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
8348-
) -> (Option<ChannelMonitorUpdate>, Vec<(HTLCSource, PaymentHash)>) {
8348+
) -> (Option<(ChannelMonitorUpdate, Vec<MonitorEventSource>)>, Vec<(HTLCSource, PaymentHash)>) {
83498349
assert!(matches!(self.context.channel_state, ChannelState::ChannelReady(_)));
83508350
assert!(!self.context.channel_state.is_monitor_update_in_progress());
83518351
assert!(!self.context.channel_state.is_quiescent());
@@ -8375,6 +8375,7 @@ where
83758375
let mut update_fulfill_count = 0;
83768376
let mut update_fail_count = 0;
83778377
let mut htlcs_to_fail = Vec::new();
8378+
let mut monitor_events_to_ack = Vec::new();
83788379
for htlc_update in htlc_updates.drain(..) {
83798380
// Note that this *can* fail, though it should be due to rather-rare conditions on
83808381
// fee races with adding too many outputs which push our total payments just over
@@ -8470,31 +8471,41 @@ where
84708471
htlc_id,
84718472
ref err_packet,
84728473
monitor_event_source,
8473-
} => Some(
8474-
self.fail_htlc(
8475-
htlc_id,
8476-
err_packet.clone(),
8477-
false,
8478-
monitor_event_source,
8479-
logger,
8474+
} => {
8475+
if let Some(source) = monitor_event_source {
8476+
monitor_events_to_ack.push(source);
8477+
}
8478+
Some(
8479+
self.fail_htlc(
8480+
htlc_id,
8481+
err_packet.clone(),
8482+
false,
8483+
monitor_event_source,
8484+
logger,
8485+
)
8486+
.map(|fail_msg_opt| fail_msg_opt.map(|_| ())),
84808487
)
8481-
.map(|fail_msg_opt| fail_msg_opt.map(|_| ())),
8482-
),
8488+
},
84838489
&HTLCUpdateAwaitingACK::FailMalformedHTLC {
84848490
htlc_id,
84858491
failure_code,
84868492
sha256_of_onion,
84878493
monitor_event_source,
8488-
} => Some(
8489-
self.fail_htlc(
8490-
htlc_id,
8491-
(sha256_of_onion, failure_code),
8492-
false,
8493-
monitor_event_source,
8494-
logger,
8494+
} => {
8495+
if let Some(source) = monitor_event_source {
8496+
monitor_events_to_ack.push(source);
8497+
}
8498+
Some(
8499+
self.fail_htlc(
8500+
htlc_id,
8501+
(sha256_of_onion, failure_code),
8502+
false,
8503+
monitor_event_source,
8504+
logger,
8505+
)
8506+
.map(|fail_msg_opt| fail_msg_opt.map(|_| ())),
84958507
)
8496-
.map(|fail_msg_opt| fail_msg_opt.map(|_| ())),
8497-
),
8508+
},
84988509
};
84998510
if let Some(res) = fail_htlc_res {
85008511
match res {
@@ -8546,7 +8557,11 @@ where
85468557
Vec::new(),
85478558
logger,
85488559
);
8549-
(self.push_ret_blockable_mon_update(monitor_update), htlcs_to_fail)
8560+
(
8561+
self.push_ret_blockable_mon_update(monitor_update)
8562+
.map(|upd| (upd, monitor_events_to_ack)),
8563+
htlcs_to_fail,
8564+
)
85508565
} else {
85518566
(None, Vec::new())
85528567
}
@@ -8899,7 +8914,10 @@ where
88998914
self.context.monitor_pending_update_adds.append(&mut pending_update_adds);
89008915

89018916
match self.maybe_free_holding_cell_htlcs(fee_estimator, logger) {
8902-
(Some(mut additional_update), htlcs_to_fail) => {
8917+
// TODO: Thread monitor_events_to_ack through the revoke_and_ack return
8918+
// value so the ChannelManager can attach an AckMonitorEvents completion
8919+
// action to this monitor update.
8920+
(Some((mut additional_update, _monitor_events_to_ack)), htlcs_to_fail) => {
89038921
// free_holding_cell_htlcs may bump latest_monitor_id multiple times but we want them to be
89048922
// strictly increasing by one, so decrement it here.
89058923
self.context.latest_monitor_update_id = monitor_update.update_id;

lightning/src/ln/channelmanager.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13782,7 +13782,16 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1378213782
);
1378313783
if monitor_opt.is_some() || !holding_cell_failed_htlcs.is_empty() {
1378413784
let update_res = monitor_opt
13785-
.map(|monitor_update| {
13785+
.map(|(monitor_update, monitor_events_to_ack)| {
13786+
if !monitor_events_to_ack.is_empty() {
13787+
peer_state
13788+
.monitor_update_blocked_actions
13789+
.entry(*chan_id)
13790+
.or_default()
13791+
.push(MonitorUpdateCompletionAction::AckMonitorEvents {
13792+
monitor_events_to_ack,
13793+
});
13794+
}
1378613795
self.handle_new_monitor_update(
1378713796
&mut peer_state.in_flight_monitor_updates,
1378813797
&mut peer_state.monitor_update_blocked_actions,

0 commit comments

Comments
 (0)