@@ -3712,14 +3712,23 @@ impl TrustedChannelFeatures {
37123712struct ClaimCompletionActionParams {
37133713 definitely_duplicate: bool,
37143714 inbound_htlc_value_msat: Option<u64>,
3715+ inbound_edge_closed: bool,
37153716}
37163717
37173718impl ClaimCompletionActionParams {
37183719 fn new_claim(inbound_htlc_value_msat: u64) -> Self {
3719- Self { definitely_duplicate: false, inbound_htlc_value_msat: Some(inbound_htlc_value_msat) }
3720+ Self {
3721+ definitely_duplicate: false,
3722+ inbound_htlc_value_msat: Some(inbound_htlc_value_msat),
3723+ inbound_edge_closed: false,
3724+ }
37203725 }
37213726 fn duplicate_claim() -> Self {
3722- Self { definitely_duplicate: true, inbound_htlc_value_msat: None }
3727+ Self {
3728+ definitely_duplicate: true,
3729+ inbound_htlc_value_msat: None,
3730+ inbound_edge_closed: false,
3731+ }
37233732 }
37243733}
37253734
@@ -9815,16 +9824,56 @@ impl<
98159824 monitor_event_id
98169825 .map(|event_id| MonitorEventSource { event_id, channel_id: next_channel_id }),
98179826 |claim_completion_action_params| {
9818- let ClaimCompletionActionParams { definitely_duplicate, inbound_htlc_value_msat } =
9819- claim_completion_action_params;
9827+ let ClaimCompletionActionParams {
9828+ definitely_duplicate,
9829+ inbound_htlc_value_msat,
9830+ inbound_edge_closed,
9831+ } = claim_completion_action_params;
98209832 let chan_to_release = EventUnblockedChannel {
98219833 counterparty_node_id: next_channel_counterparty_node_id,
98229834 funding_txo: next_channel_outpoint,
98239835 channel_id: next_channel_id,
98249836 blocking_action: completed_blocker,
98259837 };
98269838
9827- if definitely_duplicate && startup_replay {
9839+ if self.persistent_monitor_events {
9840+ let monitor_event_source = monitor_event_id.map(|event_id| {
9841+ MonitorEventSource { event_id, channel_id: next_channel_id }
9842+ });
9843+ // If persistent_monitor_events is enabled, then we'll get a MonitorEvent for this HTLC
9844+ // claim re-provided to us until we explicitly ack it.
9845+ // * If the inbound edge is closed, then we can ack it when we know the preimage is
9846+ // durably persisted there + the user has processed a `PaymentForwarded` event
9847+ // * If the inbound edge is open, then we'll ack the monitor event when HTLC has been
9848+ // irrevocably removed via revoke_and_ack. This prevents forgetting to claim the HTLC
9849+ // backwards if we lose the off-chain HTLC from the holding cell after a restart.
9850+ if definitely_duplicate {
9851+ if inbound_edge_closed {
9852+ if let Some(id) = monitor_event_source {
9853+ self.chain_monitor.ack_monitor_event(id);
9854+ }
9855+ }
9856+ (None, None)
9857+ } else if let Some(event) =
9858+ make_payment_forwarded_event(inbound_htlc_value_msat)
9859+ {
9860+ let preimage_update_action =
9861+ MonitorUpdateCompletionAction::EmitForwardEvent {
9862+ event,
9863+ post_event_ackable_monitor_event: inbound_edge_closed
9864+ .then_some(monitor_event_source)
9865+ .flatten(),
9866+ };
9867+ (Some(preimage_update_action), None)
9868+ } else if inbound_edge_closed {
9869+ let preimage_update_action = monitor_event_source.map(|src| {
9870+ MonitorUpdateCompletionAction::AckMonitorEvents { event_ids: vec![src] }
9871+ });
9872+ (preimage_update_action, None)
9873+ } else {
9874+ (None, None)
9875+ }
9876+ } else if definitely_duplicate && startup_replay {
98289877 // On startup we may get redundant claims which are related to
98299878 // monitor updates still in flight. In that case, we shouldn't
98309879 // immediately free, but instead let that monitor update complete
@@ -10157,6 +10206,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1015710206 let (action_opt, raa_blocker_opt) = completion_action(ClaimCompletionActionParams {
1015810207 definitely_duplicate: false,
1015910208 inbound_htlc_value_msat: None,
10209+ inbound_edge_closed: true,
1016010210 });
1016110211
1016210212 if let Some(raa_blocker) = raa_blocker_opt {
@@ -12860,16 +12910,25 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1286012910 chan.update_fulfill_htlc(&msg),
1286112911 chan_entry
1286212912 );
12863- let logger = WithChannelContext::from(&self.logger, &chan.context, None);
12864- for prev_hop in res.0.previous_hop_data() {
12865- log_trace!(logger,
12913+ // If persistent_monitor_events is enabled, we don't need to block preimage-removing
12914+ // monitor updates because we'll get the preimage from monitor events (that are
12915+ // guaranteed to be re-provided until they are explicitly acked) rather than from
12916+ // polling the monitor's internal state.
12917+ if !self.persistent_monitor_events {
12918+ let logger =
12919+ WithChannelContext::from(&self.logger, &chan.context, None);
12920+ for prev_hop in res.0.previous_hop_data() {
12921+ log_trace!(logger,
1286612922 "Holding the next revoke_and_ack until the preimage is durably persisted in the inbound edge's ChannelMonitor",
1286712923 );
12868- peer_state
12869- .actions_blocking_raa_monitor_updates
12870- .entry(msg.channel_id)
12871- .or_insert_with(Vec::new)
12872- .push(RAAMonitorUpdateBlockingAction::from_prev_hop_data(prev_hop));
12924+ peer_state
12925+ .actions_blocking_raa_monitor_updates
12926+ .entry(msg.channel_id)
12927+ .or_insert_with(Vec::new)
12928+ .push(RAAMonitorUpdateBlockingAction::from_prev_hop_data(
12929+ prev_hop,
12930+ ));
12931+ }
1287312932 }
1287412933
1287512934 // Note that we do not need to push an `actions_blocking_raa_monitor_updates`
@@ -13895,29 +13954,22 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1389513954 .channel_by_id
1389613955 .contains_key(&channel_id)
1389713956 });
13898- let we_are_sender =
13899- matches!(htlc_update.source, HTLCSource::OutboundRoute { .. });
13900- if from_onchain | we_are_sender {
13901- // Claim the funds from the previous hop, if there is one. In the future we can
13902- // store attribution data in the `ChannelMonitor` and provide it here.
13903- self.claim_funds_internal(
13904- htlc_update.source,
13905- preimage,
13906- htlc_update.htlc_value_msat,
13907- None,
13908- from_onchain,
13909- counterparty_node_id,
13910- funding_outpoint,
13911- channel_id,
13912- htlc_update.user_channel_id,
13913- None,
13914- None,
13915- Some(event_id),
13916- );
13917- }
13918- if !we_are_sender {
13919- self.chain_monitor.ack_monitor_event(monitor_event_source);
13920- }
13957+ // Claim the funds from the previous hop, if there is one. In the future we can
13958+ // store attribution data in the `ChannelMonitor` and provide it here.
13959+ self.claim_funds_internal(
13960+ htlc_update.source,
13961+ preimage,
13962+ htlc_update.htlc_value_msat,
13963+ None,
13964+ from_onchain,
13965+ counterparty_node_id,
13966+ funding_outpoint,
13967+ channel_id,
13968+ htlc_update.user_channel_id,
13969+ None,
13970+ None,
13971+ Some(event_id),
13972+ );
1392113973 } else {
1392213974 log_trace!(logger, "Failing HTLC from our monitor");
1392313975 let failure_reason = LocalHTLCFailureReason::OnChainTimeout;
@@ -20859,6 +20911,12 @@ impl<
2085920911 downstream_user_channel_id,
2086020912 ) in pending_claims_to_replay
2086120913 {
20914+ // If persistent_monitor_events is enabled, we don't need to explicitly reclaim HTLCs on
20915+ // startup because we can just wait for the relevant MonitorEvents to be re-provided to us
20916+ // during runtime.
20917+ if channel_manager.persistent_monitor_events {
20918+ continue;
20919+ }
2086220920 // We use `downstream_closed` in place of `from_onchain` here just as a guess - we
2086320921 // don't remember in the `ChannelMonitor` where we got a preimage from, but if the
2086420922 // channel is closed we just assume that it probably came from an on-chain claim.
0 commit comments