Skip to content

Commit 0f1a4a0

Browse files
Ack monitor events on revoke_and_ack
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, when the HTLC was irrevocably failed via revoke_and_ack.
1 parent 9a9716d commit 0f1a4a0

2 files changed

Lines changed: 20 additions & 7 deletions

File tree

lightning/src/ln/channel.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8587,7 +8587,7 @@ where
85878587
(
85888588
Vec<(HTLCSource, PaymentHash)>,
85898589
Vec<(StaticInvoice, BlindedMessagePath)>,
8590-
Option<ChannelMonitorUpdate>,
8590+
Option<(ChannelMonitorUpdate, Vec<MonitorEventSource>)>,
85918591
),
85928592
ChannelError,
85938593
> {
@@ -8898,6 +8898,7 @@ where
88988898
} else {
88998899
"Blocked"
89008900
};
8901+
let mut monitor_events_to_ack = Vec::new();
89018902
macro_rules! return_with_htlcs_to_fail {
89028903
($htlcs_to_fail: expr) => {
89038904
if !release_monitor {
@@ -8906,18 +8907,21 @@ where
89068907
.push(PendingChannelMonitorUpdate { update: monitor_update });
89078908
return Ok(($htlcs_to_fail, static_invoices, None));
89088909
} else {
8909-
return Ok(($htlcs_to_fail, static_invoices, Some(monitor_update)));
8910+
let events_to_ack = core::mem::take(&mut monitor_events_to_ack);
8911+
return Ok((
8912+
$htlcs_to_fail,
8913+
static_invoices,
8914+
Some((monitor_update, events_to_ack)),
8915+
));
89108916
}
89118917
};
89128918
}
89138919

89148920
self.context.monitor_pending_update_adds.append(&mut pending_update_adds);
89158921

89168922
match self.maybe_free_holding_cell_htlcs(fee_estimator, logger) {
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) => {
8923+
(Some((mut additional_update, holding_cell_monitor_events_to_ack)), htlcs_to_fail) => {
8924+
monitor_events_to_ack = holding_cell_monitor_events_to_ack;
89218925
// free_holding_cell_htlcs may bump latest_monitor_id multiple times but we want them to be
89228926
// strictly increasing by one, so decrement it here.
89238927
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
@@ -12981,7 +12981,16 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1298112981
*counterparty_node_id);
1298212982
let (htlcs_to_fail, static_invoices, monitor_update_opt) = try_channel_entry!(self, peer_state,
1298312983
chan.revoke_and_ack(&msg, &self.fee_estimator, &&logger, mon_update_blocked), chan_entry);
12984-
if let Some(monitor_update) = monitor_update_opt {
12984+
if let Some((monitor_update, monitor_events_to_ack)) = monitor_update_opt {
12985+
if !monitor_events_to_ack.is_empty() {
12986+
peer_state
12987+
.monitor_update_blocked_actions
12988+
.entry(msg.channel_id)
12989+
.or_default()
12990+
.push(MonitorUpdateCompletionAction::AckMonitorEvents {
12991+
monitor_events_to_ack,
12992+
});
12993+
}
1298512994
let funding_txo = funding_txo_opt
1298612995
.expect("Funding outpoint must have been set for RAA handling to succeed");
1298712996
if let Some(data) = self.handle_new_monitor_update(

0 commit comments

Comments
 (0)