@@ -801,6 +801,7 @@ pub(super) enum RAACommitmentOrder {
801
801
}
802
802
803
803
/// Information about a payment which is currently being claimed.
804
+ #[derive(Clone, Debug, PartialEq, Eq)]
804
805
struct ClaimingPayment {
805
806
amount_msat: u64,
806
807
payment_purpose: events::PaymentPurpose,
@@ -1072,12 +1073,36 @@ struct MPPClaimHTLCSource {
1072
1073
htlc_id: u64,
1073
1074
}
1074
1075
1076
+ impl_writeable_tlv_based!(MPPClaimHTLCSource, {
1077
+ (0, counterparty_node_id, required),
1078
+ (2, funding_txo, required),
1079
+ (4, channel_id, required),
1080
+ (6, htlc_id, required),
1081
+ });
1082
+
1075
1083
#[derive(Debug)]
1076
1084
pub(crate) struct PendingMPPClaim {
1077
1085
channels_without_preimage: Vec<MPPClaimHTLCSource>,
1078
1086
channels_with_preimage: Vec<MPPClaimHTLCSource>,
1079
1087
}
1080
1088
1089
+ #[derive(Clone, Debug, PartialEq, Eq)]
1090
+ /// When we're claiming a(n MPP) payment, we want to store information about thay payment in the
1091
+ /// [`ChannelMonitor`] so that we can replay the claim without any information from the
1092
+ /// [`ChannelManager`] at all. This struct stores that information with enough to replay claims
1093
+ /// against all MPP parts as well as generate an [`Event::PaymentClaimed`].
1094
+ pub(crate) struct PaymentClaimDetails {
1095
+ mpp_parts: Vec<MPPClaimHTLCSource>,
1096
+ /// Use [`ClaimingPayment`] as a stable source of all the fields we need to generate the
1097
+ /// [`Event::PaymentClaimed`].
1098
+ claiming_payment: ClaimingPayment,
1099
+ }
1100
+
1101
+ impl_writeable_tlv_based!(PaymentClaimDetails, {
1102
+ (0, mpp_parts, required_vec),
1103
+ (2, claiming_payment, required),
1104
+ });
1105
+
1081
1106
#[derive(Clone)]
1082
1107
pub(crate) struct PendingMPPClaimPointer(Arc<Mutex<PendingMPPClaim>>);
1083
1108
@@ -6675,6 +6700,7 @@ where
6675
6700
6676
6701
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
6677
6702
6703
+ let claiming_payment;
6678
6704
let sources = {
6679
6705
let mut claimable_payments = self.claimable_payments.lock().unwrap();
6680
6706
if let Some(payment) = claimable_payments.claimable_payments.remove(&payment_hash) {
@@ -6689,7 +6715,7 @@ where
6689
6715
}
6690
6716
6691
6717
let payment_id = payment.inbound_payment_id(&self.inbound_payment_id_secret);
6692
- let claiming_payment = claimable_payments.pending_claiming_payments
6718
+ claiming_payment = claimable_payments.pending_claiming_payments
6693
6719
.entry(payment_hash)
6694
6720
.and_modify(|_| {
6695
6721
debug_assert!(false, "Shouldn't get a duplicate pending claim event ever");
@@ -6708,7 +6734,7 @@ where
6708
6734
onion_fields: payment.onion_fields,
6709
6735
payment_id: Some(payment_id),
6710
6736
}
6711
- });
6737
+ }).clone() ;
6712
6738
6713
6739
if let Some(RecipientOnionFields { ref custom_tlvs, .. }) = claiming_payment.onion_fields {
6714
6740
if !custom_tlvs_known && custom_tlvs.iter().any(|(typ, _)| typ % 2 == 0) {
@@ -6772,26 +6798,27 @@ where
6772
6798
return;
6773
6799
}
6774
6800
if valid_mpp {
6801
+ let mpp_parts: Vec<_> = sources.iter().filter_map(|htlc| {
6802
+ if let Some(cp_id) = htlc.prev_hop.counterparty_node_id {
6803
+ Some(MPPClaimHTLCSource {
6804
+ counterparty_node_id: cp_id,
6805
+ funding_txo: htlc.prev_hop.outpoint,
6806
+ channel_id: htlc.prev_hop.channel_id,
6807
+ htlc_id: htlc.prev_hop.htlc_id,
6808
+ })
6809
+ } else {
6810
+ None
6811
+ }
6812
+ }).collect();
6775
6813
let pending_mpp_claim_ptr_opt = if sources.len() > 1 {
6776
- let channels_without_preimage = sources.iter().filter_map(|htlc| {
6777
- if let Some(cp_id) = htlc.prev_hop.counterparty_node_id {
6778
- Some(MPPClaimHTLCSource {
6779
- counterparty_node_id: cp_id,
6780
- funding_txo: htlc.prev_hop.outpoint,
6781
- channel_id: htlc.prev_hop.channel_id,
6782
- htlc_id: htlc.prev_hop.htlc_id,
6783
- })
6784
- } else {
6785
- None
6786
- }
6787
- }).collect();
6788
6814
Some(Arc::new(Mutex::new(PendingMPPClaim {
6789
- channels_without_preimage,
6815
+ channels_without_preimage: mpp_parts.clone() ,
6790
6816
channels_with_preimage: Vec::new(),
6791
6817
})))
6792
6818
} else {
6793
6819
None
6794
6820
};
6821
+ let payment_info = Some(PaymentClaimDetails { mpp_parts, claiming_payment });
6795
6822
for htlc in sources {
6796
6823
let this_mpp_claim = pending_mpp_claim_ptr_opt.as_ref().and_then(|pending_mpp_claim|
6797
6824
if let Some(cp_id) = htlc.prev_hop.counterparty_node_id {
@@ -6807,7 +6834,7 @@ where
6807
6834
}
6808
6835
});
6809
6836
self.claim_funds_from_hop(
6810
- htlc.prev_hop, payment_preimage,
6837
+ htlc.prev_hop, payment_preimage, payment_info.clone(),
6811
6838
|_, definitely_duplicate| {
6812
6839
debug_assert!(!definitely_duplicate, "We shouldn't claim duplicatively from a payment");
6813
6840
(Some(MonitorUpdateCompletionAction::PaymentClaimed { payment_hash, pending_mpp_claim: this_mpp_claim }), raa_blocker)
@@ -6837,7 +6864,7 @@ where
6837
6864
ComplFunc: FnOnce(Option<u64>, bool) -> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>)
6838
6865
>(
6839
6866
&self, prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage,
6840
- completion_action: ComplFunc,
6867
+ payment_info: Option<PaymentClaimDetails>, completion_action: ComplFunc,
6841
6868
) {
6842
6869
//TODO: Delay the claimed_funds relaying just like we do outbound relay!
6843
6870
@@ -6871,7 +6898,8 @@ where
6871
6898
if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() {
6872
6899
let counterparty_node_id = chan.context.get_counterparty_node_id();
6873
6900
let logger = WithChannelContext::from(&self.logger, &chan.context, None);
6874
- let fulfill_res = chan.get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage, &&logger);
6901
+ let fulfill_res =
6902
+ chan.get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage, payment_info, &&logger);
6875
6903
6876
6904
match fulfill_res {
6877
6905
UpdateFulfillCommitFetch::NewClaim { htlc_value_msat, monitor_update } => {
@@ -6959,6 +6987,7 @@ where
6959
6987
counterparty_node_id: None,
6960
6988
updates: vec![ChannelMonitorUpdateStep::PaymentPreimage {
6961
6989
payment_preimage,
6990
+ payment_info,
6962
6991
}],
6963
6992
channel_id: Some(prev_hop.channel_id),
6964
6993
};
@@ -7069,7 +7098,7 @@ where
7069
7098
let completed_blocker = RAAMonitorUpdateBlockingAction::from_prev_hop_data(&hop_data);
7070
7099
#[cfg(debug_assertions)]
7071
7100
let claiming_chan_funding_outpoint = hop_data.outpoint;
7072
- self.claim_funds_from_hop(hop_data, payment_preimage,
7101
+ self.claim_funds_from_hop(hop_data, payment_preimage, None,
7073
7102
|htlc_claim_value_msat, definitely_duplicate| {
7074
7103
let chan_to_release =
7075
7104
if let Some(node_id) = next_channel_counterparty_node_id {
@@ -7105,7 +7134,7 @@ where
7105
7134
if *funding_txo == claiming_chan_funding_outpoint {
7106
7135
assert!(update.updates.iter().any(|upd|
7107
7136
if let ChannelMonitorUpdateStep::PaymentPreimage {
7108
- payment_preimage: update_preimage
7137
+ payment_preimage: update_preimage, ..
7109
7138
} = upd {
7110
7139
payment_preimage == *update_preimage
7111
7140
} else { false }
0 commit comments