@@ -181,6 +181,7 @@ pub(super) enum HTLCForwardInfo {
181181pub(crate) struct HTLCPreviousHopData {
182182	// Note that this may be an outbound SCID alias for the associated channel.
183183	short_channel_id: u64,
184+ 	user_channel_id: Option<u128>,
184185	htlc_id: u64,
185186	incoming_packet_shared_secret: [u8; 32],
186187	phantom_shared_secret: Option<[u8; 32]>,
@@ -221,6 +222,17 @@ struct ClaimableHTLC {
221222	counterparty_skimmed_fee_msat: Option<u64>,
222223}
223224
225+ impl From<&ClaimableHTLC> for events::ClaimedHTLC {
226+ 	fn from(val: &ClaimableHTLC) -> Self {
227+ 		events::ClaimedHTLC {
228+ 			channel_id: val.prev_hop.outpoint.to_channel_id(),
229+ 			user_channel_id: val.prev_hop.user_channel_id.unwrap_or(0),
230+ 			cltv_expiry: val.cltv_expiry,
231+ 			value_msat: val.value,
232+ 		}
233+ 	}
234+ }
235+ 
224236/// A payment identifier used to uniquely identify a payment to LDK.
225237///
226238/// This is not exported to bindings users as we just use [u8; 32] directly
@@ -496,11 +508,15 @@ struct ClaimingPayment {
496508	amount_msat: u64,
497509	payment_purpose: events::PaymentPurpose,
498510	receiver_node_id: PublicKey,
511+ 	htlcs: Vec<events::ClaimedHTLC>,
512+ 	sender_intended_value: Option<u64>,
499513}
500514impl_writeable_tlv_based!(ClaimingPayment, {
501515	(0, amount_msat, required),
502516	(2, payment_purpose, required),
503517	(4, receiver_node_id, required),
518+ 	(5, htlcs, optional_vec),
519+ 	(7, sender_intended_value, option),
504520});
505521
506522struct ClaimablePayment {
@@ -3781,6 +3797,7 @@ where
37813797		if let PendingHTLCRouting::Forward { short_channel_id, .. } = payment.forward_info.routing {
37823798			let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
37833799				short_channel_id: payment.prev_short_channel_id,
3800+ 				user_channel_id: Some(payment.prev_user_channel_id),
37843801				outpoint: payment.prev_funding_outpoint,
37853802				htlc_id: payment.prev_htlc_id,
37863803				incoming_packet_shared_secret: payment.forward_info.incoming_shared_secret,
@@ -3828,6 +3845,7 @@ where
38283845
38293846												let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
38303847													short_channel_id: prev_short_channel_id,
3848+ 													user_channel_id: Some(prev_user_channel_id),
38313849													outpoint: prev_funding_outpoint,
38323850													htlc_id: prev_htlc_id,
38333851													incoming_packet_shared_secret: incoming_shared_secret,
@@ -3932,7 +3950,7 @@ where
39323950							for forward_info in pending_forwards.drain(..) {
39333951								match forward_info {
39343952									HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
3935- 										prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id: _ ,
3953+ 										prev_short_channel_id, prev_htlc_id, prev_funding_outpoint, prev_user_channel_id,
39363954										forward_info: PendingHTLCInfo {
39373955											incoming_shared_secret, payment_hash, outgoing_amt_msat, outgoing_cltv_value,
39383956											routing: PendingHTLCRouting::Forward { onion_packet, .. }, skimmed_fee_msat, ..
@@ -3941,6 +3959,7 @@ where
39413959										log_trace!(self.logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", prev_short_channel_id, log_bytes!(payment_hash.0), short_chan_id);
39423960										let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
39433961											short_channel_id: prev_short_channel_id,
3962+ 											user_channel_id: Some(prev_user_channel_id),
39443963											outpoint: prev_funding_outpoint,
39453964											htlc_id: prev_htlc_id,
39463965											incoming_packet_shared_secret: incoming_shared_secret,
@@ -4022,6 +4041,7 @@ where
40224041								let claimable_htlc = ClaimableHTLC {
40234042									prev_hop: HTLCPreviousHopData {
40244043										short_channel_id: prev_short_channel_id,
4044+ 										user_channel_id: Some(prev_user_channel_id),
40254045										outpoint: prev_funding_outpoint,
40264046										htlc_id: prev_htlc_id,
40274047										incoming_packet_shared_secret: incoming_shared_secret,
@@ -4051,6 +4071,7 @@ where
40514071										);
40524072										failed_forwards.push((HTLCSource::PreviousHopData(HTLCPreviousHopData {
40534073												short_channel_id: $htlc.prev_hop.short_channel_id,
4074+ 												user_channel_id: $htlc.prev_hop.user_channel_id,
40544075												outpoint: prev_funding_outpoint,
40554076												htlc_id: $htlc.prev_hop.htlc_id,
40564077												incoming_packet_shared_secret: $htlc.prev_hop.incoming_packet_shared_secret,
@@ -4782,7 +4803,7 @@ where
47824803					&self.pending_events, &self.logger)
47834804				{ self.push_pending_forwards_ev(); }
47844805			},
4785- 			HTLCSource::PreviousHopData(HTLCPreviousHopData { ref short_channel_id, ref htlc_id, ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint }) => {
4806+ 			HTLCSource::PreviousHopData(HTLCPreviousHopData { ref short_channel_id, ref htlc_id, ref incoming_packet_shared_secret, ref phantom_shared_secret, ref outpoint, ..  }) => {
47864807				log_trace!(self.logger, "Failing HTLC with payment_hash {} backwards from us with {:?}", log_bytes!(payment_hash.0), onion_error);
47874808				let err_packet = onion_error.get_encrypted_failure_packet(incoming_packet_shared_secret, phantom_shared_secret);
47884809
@@ -4869,9 +4890,11 @@ where
48694890					}
48704891				}
48714892
4893+ 				let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
4894+ 				let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat);
48724895				let dup_purpose = claimable_payments.pending_claiming_payments.insert(payment_hash,
48734896					ClaimingPayment { amount_msat: payment.htlcs.iter().map(|source| source.value).sum(),
4874- 					payment_purpose: payment.purpose, receiver_node_id,
4897+ 					payment_purpose: payment.purpose, receiver_node_id, htlcs, sender_intended_value 
48754898				});
48764899				if dup_purpose.is_some() {
48774900					debug_assert!(false, "Shouldn't get a duplicate pending claim event ever");
@@ -5129,9 +5152,20 @@ where
51295152			match action {
51305153				MonitorUpdateCompletionAction::PaymentClaimed { payment_hash } => {
51315154					let payment = self.claimable_payments.lock().unwrap().pending_claiming_payments.remove(&payment_hash);
5132- 					if let Some(ClaimingPayment { amount_msat, payment_purpose: purpose, receiver_node_id }) = payment {
5155+ 					if let Some(ClaimingPayment {
5156+ 						amount_msat,
5157+ 						payment_purpose: purpose,
5158+ 						receiver_node_id,
5159+ 						htlcs,
5160+ 						sender_intended_value: sender_intended_total_msat,
5161+ 					}) = payment {
51335162						self.pending_events.lock().unwrap().push_back((events::Event::PaymentClaimed {
5134- 							payment_hash, purpose, amount_msat, receiver_node_id: Some(receiver_node_id),
5163+ 							payment_hash,
5164+ 							purpose,
5165+ 							amount_msat,
5166+ 							receiver_node_id: Some(receiver_node_id),
5167+ 							htlcs,
5168+ 							sender_intended_total_msat,
51355169						}, None));
51365170					}
51375171				},
@@ -6006,6 +6040,7 @@ where
60066040										log_info!(self.logger, "Failed to forward incoming HTLC: detected duplicate intercepted payment over short channel id {}", scid);
60076041										let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
60086042											short_channel_id: prev_short_channel_id,
6043+ 											user_channel_id: Some(prev_user_channel_id),
60096044											outpoint: prev_funding_outpoint,
60106045											htlc_id: prev_htlc_id,
60116046											incoming_packet_shared_secret: forward_info.incoming_shared_secret,
@@ -7124,6 +7159,7 @@ where
71247159				if height >= htlc.forward_info.outgoing_cltv_value - HTLC_FAIL_BACK_BUFFER {
71257160					let prev_hop_data = HTLCSource::PreviousHopData(HTLCPreviousHopData {
71267161						short_channel_id: htlc.prev_short_channel_id,
7162+ 						user_channel_id: Some(htlc.prev_user_channel_id),
71277163						htlc_id: htlc.prev_htlc_id,
71287164						incoming_packet_shared_secret: htlc.forward_info.incoming_shared_secret,
71297165						phantom_shared_secret: None,
@@ -7899,7 +7935,8 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
78997935	(1, phantom_shared_secret, option),
79007936	(2, outpoint, required),
79017937	(4, htlc_id, required),
7902- 	(6, incoming_packet_shared_secret, required)
7938+ 	(6, incoming_packet_shared_secret, required),
7939+ 	(7, user_channel_id, option),
79037940});
79047941
79057942impl Writeable for ClaimableHTLC {
@@ -9147,7 +9184,7 @@ where
91479184							.expect("Failed to get node_id for phantom node recipient");
91489185						receiver_node_id = Some(phantom_pubkey)
91499186					}
9150- 					for claimable_htlc in payment.htlcs {
9187+ 					for claimable_htlc in & payment.htlcs {
91519188						claimable_amt_msat += claimable_htlc.value;
91529189
91539190						// Add a holding-cell claim of the payment to the Channel, which should be
@@ -9183,6 +9220,8 @@ where
91839220						payment_hash,
91849221						purpose: payment.purpose,
91859222						amount_msat: claimable_amt_msat,
9223+ 						htlcs: payment.htlcs.iter().map(events::ClaimedHTLC::from).collect(),
9224+ 						sender_intended_total_msat: payment.htlcs.first().map(|htlc| htlc.total_msat),
91869225					}, None));
91879226				}
91889227			}
0 commit comments