@@ -3718,14 +3718,23 @@ impl TrustedChannelFeatures {
37183718struct ClaimCompletionActionParams {
37193719 definitely_duplicate: bool,
37203720 inbound_htlc_value_msat: Option<u64>,
3721+ inbound_edge_closed: bool,
37213722}
37223723
37233724impl ClaimCompletionActionParams {
37243725 fn new_claim(inbound_htlc_value_msat: u64) -> Self {
3725- Self { definitely_duplicate: false, inbound_htlc_value_msat: Some(inbound_htlc_value_msat) }
3726+ Self {
3727+ definitely_duplicate: false,
3728+ inbound_htlc_value_msat: Some(inbound_htlc_value_msat),
3729+ inbound_edge_closed: false,
3730+ }
37263731 }
37273732 fn duplicate_claim() -> Self {
3728- Self { definitely_duplicate: true, inbound_htlc_value_msat: None }
3733+ Self {
3734+ definitely_duplicate: true,
3735+ inbound_htlc_value_msat: None,
3736+ inbound_edge_closed: false,
3737+ }
37293738 }
37303739}
37313740
@@ -9821,16 +9830,56 @@ impl<
98219830 monitor_event_id
98229831 .map(|event_id| MonitorEventSource { event_id, channel_id: next_channel_id }),
98239832 |claim_completion_action_params| {
9824- let ClaimCompletionActionParams { definitely_duplicate, inbound_htlc_value_msat } =
9825- claim_completion_action_params;
9833+ let ClaimCompletionActionParams {
9834+ definitely_duplicate,
9835+ inbound_htlc_value_msat,
9836+ inbound_edge_closed,
9837+ } = claim_completion_action_params;
98269838 let chan_to_release = EventUnblockedChannel {
98279839 counterparty_node_id: next_channel_counterparty_node_id,
98289840 funding_txo: next_channel_outpoint,
98299841 channel_id: next_channel_id,
98309842 blocking_action: completed_blocker,
98319843 };
98329844
9833- if definitely_duplicate && startup_replay {
9845+ if self.persistent_monitor_events {
9846+ let monitor_event_source = monitor_event_id.map(|event_id| {
9847+ MonitorEventSource { event_id, channel_id: next_channel_id }
9848+ });
9849+ // If persistent_monitor_events is enabled, then we'll get a MonitorEvent for this HTLC
9850+ // claim re-provided to us until we explicitly ack it.
9851+ // * If the inbound edge is closed, then we can ack it when we know the preimage is
9852+ // durably persisted there + the user has processed a `PaymentForwarded` event
9853+ // * If the inbound edge is open, then we'll ack the monitor event when HTLC has been
9854+ // irrevocably removed via revoke_and_ack. This prevents forgetting to claim the HTLC
9855+ // backwards if we lose the off-chain HTLC from the holding cell after a restart.
9856+ if definitely_duplicate {
9857+ if inbound_edge_closed {
9858+ if let Some(id) = monitor_event_source {
9859+ self.chain_monitor.ack_monitor_event(id);
9860+ }
9861+ }
9862+ (None, None)
9863+ } else if let Some(event) =
9864+ make_payment_forwarded_event(inbound_htlc_value_msat)
9865+ {
9866+ let preimage_update_action =
9867+ MonitorUpdateCompletionAction::EmitForwardEvent {
9868+ event,
9869+ post_event_ackable_monitor_event: inbound_edge_closed
9870+ .then_some(monitor_event_source)
9871+ .flatten(),
9872+ };
9873+ (Some(preimage_update_action), None)
9874+ } else if inbound_edge_closed {
9875+ let preimage_update_action = monitor_event_source.map(|src| {
9876+ MonitorUpdateCompletionAction::AckMonitorEvents { event_ids: vec![src] }
9877+ });
9878+ (preimage_update_action, None)
9879+ } else {
9880+ (None, None)
9881+ }
9882+ } else if definitely_duplicate && startup_replay {
98349883 // On startup we may get redundant claims which are related to
98359884 // monitor updates still in flight. In that case, we shouldn't
98369885 // immediately free, but instead let that monitor update complete
@@ -10163,6 +10212,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1016310212 let (action_opt, raa_blocker_opt) = completion_action(ClaimCompletionActionParams {
1016410213 definitely_duplicate: false,
1016510214 inbound_htlc_value_msat: None,
10215+ inbound_edge_closed: true,
1016610216 });
1016710217
1016810218 if let Some(raa_blocker) = raa_blocker_opt {
@@ -12866,16 +12916,25 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1286612916 chan.update_fulfill_htlc(&msg),
1286712917 chan_entry
1286812918 );
12869- let logger = WithChannelContext::from(&self.logger, &chan.context, None);
12870- for prev_hop in res.0.previous_hop_data() {
12871- log_trace!(logger,
12919+ // If persistent_monitor_events is enabled, we don't need to block preimage-removing
12920+ // monitor updates because we'll get the preimage from monitor events (that are
12921+ // guaranteed to be re-provided until they are explicitly acked) rather than from
12922+ // polling the monitor's internal state.
12923+ if !self.persistent_monitor_events {
12924+ let logger =
12925+ WithChannelContext::from(&self.logger, &chan.context, None);
12926+ for prev_hop in res.0.previous_hop_data() {
12927+ log_trace!(logger,
1287212928 "Holding the next revoke_and_ack until the preimage is durably persisted in the inbound edge's ChannelMonitor",
1287312929 );
12874- peer_state
12875- .actions_blocking_raa_monitor_updates
12876- .entry(msg.channel_id)
12877- .or_insert_with(Vec::new)
12878- .push(RAAMonitorUpdateBlockingAction::from_prev_hop_data(prev_hop));
12930+ peer_state
12931+ .actions_blocking_raa_monitor_updates
12932+ .entry(msg.channel_id)
12933+ .or_insert_with(Vec::new)
12934+ .push(RAAMonitorUpdateBlockingAction::from_prev_hop_data(
12935+ prev_hop,
12936+ ));
12937+ }
1287912938 }
1288012939
1288112940 // Note that we do not need to push an `actions_blocking_raa_monitor_updates`
@@ -13901,29 +13960,22 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1390113960 .channel_by_id
1390213961 .contains_key(&channel_id)
1390313962 });
13904- let we_are_sender =
13905- matches!(htlc_update.source, HTLCSource::OutboundRoute { .. });
13906- if from_onchain | we_are_sender {
13907- // Claim the funds from the previous hop, if there is one. In the future we can
13908- // store attribution data in the `ChannelMonitor` and provide it here.
13909- self.claim_funds_internal(
13910- htlc_update.source,
13911- preimage,
13912- htlc_update.htlc_value_msat,
13913- None,
13914- from_onchain,
13915- counterparty_node_id,
13916- funding_outpoint,
13917- channel_id,
13918- htlc_update.user_channel_id,
13919- None,
13920- None,
13921- Some(event_id),
13922- );
13923- }
13924- if !we_are_sender {
13925- self.chain_monitor.ack_monitor_event(monitor_event_source);
13926- }
13963+ // Claim the funds from the previous hop, if there is one. In the future we can
13964+ // store attribution data in the `ChannelMonitor` and provide it here.
13965+ self.claim_funds_internal(
13966+ htlc_update.source,
13967+ preimage,
13968+ htlc_update.htlc_value_msat,
13969+ None,
13970+ from_onchain,
13971+ counterparty_node_id,
13972+ funding_outpoint,
13973+ channel_id,
13974+ htlc_update.user_channel_id,
13975+ None,
13976+ None,
13977+ Some(event_id),
13978+ );
1392713979 } else {
1392813980 log_trace!(logger, "Failing HTLC from our monitor");
1392913981 let failure_reason = LocalHTLCFailureReason::OnChainTimeout;
@@ -20865,6 +20917,12 @@ impl<
2086520917 downstream_user_channel_id,
2086620918 ) in pending_claims_to_replay
2086720919 {
20920+ // If persistent_monitor_events is enabled, we don't need to explicitly reclaim HTLCs on
20921+ // startup because we can just wait for the relevant MonitorEvents to be re-provided to us
20922+ // during runtime.
20923+ if channel_manager.persistent_monitor_events {
20924+ continue;
20925+ }
2086820926 // We use `downstream_closed` in place of `from_onchain` here just as a guess - we
2086920927 // don't remember in the `ChannelMonitor` where we got a preimage from, but if the
2087020928 // channel is closed we just assume that it probably came from an on-chain claim.
0 commit comments