@@ -1512,6 +1512,17 @@ pub(crate) enum MonitorUpdateCompletionAction {
15121512 /// action is handled.
15131513 monitor_event_source: Option<MonitorEventSource>,
15141514 },
1515+ /// Indicates an [`events::Event`] should be surfaced to the user once the associated
1516+ /// [`ChannelMonitorUpdate`] has been durably persisted.
1517+ ///
1518+ /// This is used when `persistent_monitor_events` is enabled for forwarded payment claims.
1519+ /// Unlike [`Self::EmitEventOptionAndFreeOtherChannel`], this variant does not carry any
1520+ /// channel-unblocking information because persistent monitor events never add
1521+ /// [`RAAMonitorUpdateBlockingAction::ForwardedPaymentInboundClaim`] blockers.
1522+ EmitEventAndAckMonitorEvent {
1523+ event: events::Event,
1524+ monitor_event_source: Option<MonitorEventSource>,
1525+ },
15151526 /// Indicates that one or more [`MonitorEvent`]s should be acknowledged via
15161527 /// [`chain::Watch::ack_monitor_event`] once the associated [`ChannelMonitorUpdate`] has been
15171528 /// durably persisted.
@@ -1542,6 +1553,10 @@ impl_writeable_tlv_based_enum_upgradable!(MonitorUpdateCompletionAction,
15421553 (3, AckMonitorEvents) => {
15431554 (0, monitor_events_to_ack, required_vec),
15441555 },
1556+ (4, EmitEventAndAckMonitorEvent) => {
1557+ (0, event, upgradable_required),
1558+ (1, monitor_event_source, option),
1559+ },
15451560);
15461561
15471562/// Result of attempting to resume a channel after a monitor update completes while locks are held.
@@ -9798,20 +9813,48 @@ impl<
97989813 )
97999814 } else {
98009815 let event = make_payment_forwarded_event(htlc_claim_value_msat);
9801- if let Some(ref payment_forwarded) = event {
9802- debug_assert!(matches!(
9803- payment_forwarded,
9804- &events::Event::PaymentForwarded { .. }
9805- ));
9816+ if self.persistent_monitor_events {
9817+ match (event, monitor_event_source) {
9818+ // Typically monitor_event_source is None here. The usual flow is: receive
9819+ // update_fulfill_htlc from outbound edge peer, call claim_funds with
9820+ // monitor_event_source = None, generate event here. Then, preimage gets into
9821+ // outbound edge monitor, get a preimage monitor event, call claim_funds again and
9822+ // hit the duplicate claim flow above. However, in the case that the ChannelManager
9823+ // is outdated and we got here after restart from an un-acked preimage monitor event,
9824+ // we can end up here with monitor event source = Some.
9825+ (Some(ev), mes) => (
9826+ Some(MonitorUpdateCompletionAction::EmitEventAndAckMonitorEvent {
9827+ event: ev,
9828+ monitor_event_source: mes,
9829+ }),
9830+ None,
9831+ ),
9832+ (None, Some(mes)) => (
9833+ Some(MonitorUpdateCompletionAction::AckMonitorEvents {
9834+ monitor_events_to_ack: vec![mes],
9835+ }),
9836+ None,
9837+ ),
9838+ (None, None) => (None, None),
9839+ }
9840+ } else {
9841+ if let Some(ref payment_forwarded) = event {
9842+ debug_assert!(matches!(
9843+ payment_forwarded,
9844+ &events::Event::PaymentForwarded { .. }
9845+ ));
9846+ }
9847+ (
9848+ Some(
9849+ MonitorUpdateCompletionAction::EmitEventOptionAndFreeOtherChannel {
9850+ event,
9851+ downstream_counterparty_and_funding_outpoint: chan_to_release,
9852+ monitor_event_source,
9853+ },
9854+ ),
9855+ None,
9856+ )
98069857 }
9807- (
9808- Some(MonitorUpdateCompletionAction::EmitEventOptionAndFreeOtherChannel {
9809- event,
9810- downstream_counterparty_and_funding_outpoint: chan_to_release,
9811- monitor_event_source,
9812- }),
9813- None,
9814- )
98159858 }
98169859 },
98179860 );
@@ -10601,6 +10644,15 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1060110644 Some(blocking_action),
1060210645 );
1060310646 },
10647+ MonitorUpdateCompletionAction::EmitEventAndAckMonitorEvent {
10648+ event,
10649+ monitor_event_source,
10650+ } => {
10651+ if let Some(source) = monitor_event_source {
10652+ self.chain_monitor.ack_monitor_event(source);
10653+ }
10654+ self.pending_events.lock().unwrap().push_back((event, None));
10655+ },
1060410656 MonitorUpdateCompletionAction::AckMonitorEvents { monitor_events_to_ack } => {
1060510657 for source in monitor_events_to_ack {
1060610658 self.chain_monitor.ack_monitor_event(source);
0 commit comments