@@ -58,12 +58,12 @@ use crate::events::{
5858use crate::events::{FundingInfo, PaidBolt12Invoice};
5959// Since this struct is returned in `list_channels` methods, expose it here in case users want to
6060// construct one themselves.
61- use crate::ln::channel::PendingV2Channel;
6261use crate::ln::channel::{
63- self, Channel, ChannelError, ChannelUpdateStatus, FundedChannel, InboundV1Channel,
62+ self, hold_time, Channel, ChannelError, ChannelUpdateStatus, FundedChannel, InboundV1Channel,
6463 OutboundV1Channel, ReconnectionMsg, ShutdownResult, UpdateFulfillCommitFetch,
6564 WithChannelContext,
6665};
66+ use crate::ln::channel::{duration_since_epoch, PendingV2Channel};
6767use crate::ln::channel_state::ChannelDetails;
6868use crate::ln::inbound_payment;
6969use crate::ln::msgs;
@@ -77,6 +77,7 @@ use crate::ln::onion_payment::{
7777 NextPacketDetails,
7878};
7979use crate::ln::onion_utils::{self};
80+ use crate::ln::onion_utils::{process_fulfill_attribution_data, AttributionData};
8081use crate::ln::onion_utils::{HTLCFailReason, LocalHTLCFailureReason};
8182use crate::ln::our_peer_storage::EncryptedOurPeerStorage;
8283#[cfg(test)]
@@ -7639,10 +7640,30 @@ where
76397640 pending_claim: PendingMPPClaimPointer(Arc::clone(pending_claim)),
76407641 }
76417642 });
7643+
7644+ // Create new attribution data as the final hop. Always report a zero hold time, because reporting a
7645+ // non-zero value will not make a difference in the penalty that may be applied by the sender. If there
7646+ // is a phantom hop, we need to double-process.
7647+ let attribution_data =
7648+ if let Some(phantom_secret) = htlc.prev_hop.phantom_shared_secret {
7649+ let attribution_data =
7650+ process_fulfill_attribution_data(None, &phantom_secret, 0);
7651+ Some(attribution_data)
7652+ } else {
7653+ None
7654+ };
7655+
7656+ let attribution_data = process_fulfill_attribution_data(
7657+ attribution_data.as_ref(),
7658+ &htlc.prev_hop.incoming_packet_shared_secret,
7659+ 0,
7660+ );
7661+
76427662 self.claim_funds_from_hop(
76437663 htlc.prev_hop,
76447664 payment_preimage,
76457665 payment_info.clone(),
7666+ Some(attribution_data),
76467667 |_, definitely_duplicate| {
76477668 debug_assert!(
76487669 !definitely_duplicate,
@@ -7687,7 +7708,8 @@ where
76877708 ) -> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
76887709 >(
76897710 &self, prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage,
7690- payment_info: Option<PaymentClaimDetails>, completion_action: ComplFunc,
7711+ payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
7712+ completion_action: ComplFunc,
76917713 ) {
76927714 let counterparty_node_id = prev_hop.counterparty_node_id.or_else(|| {
76937715 let short_to_chan_info = self.short_to_chan_info.read().unwrap();
@@ -7700,7 +7722,13 @@ where
77007722 channel_id: prev_hop.channel_id,
77017723 htlc_id: prev_hop.htlc_id,
77027724 };
7703- self.claim_mpp_part(htlc_source, payment_preimage, payment_info, completion_action)
7725+ self.claim_mpp_part(
7726+ htlc_source,
7727+ payment_preimage,
7728+ payment_info,
7729+ attribution_data,
7730+ completion_action,
7731+ )
77047732 }
77057733
77067734 fn claim_mpp_part<
@@ -7710,7 +7738,8 @@ where
77107738 ) -> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
77117739 >(
77127740 &self, prev_hop: HTLCClaimSource, payment_preimage: PaymentPreimage,
7713- payment_info: Option<PaymentClaimDetails>, completion_action: ComplFunc,
7741+ payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
7742+ completion_action: ComplFunc,
77147743 ) {
77157744 //TODO: Delay the claimed_funds relaying just like we do outbound relay!
77167745
@@ -7751,6 +7780,7 @@ where
77517780 prev_hop.htlc_id,
77527781 payment_preimage,
77537782 payment_info,
7783+ attribution_data,
77547784 &&logger,
77557785 );
77567786
@@ -7959,7 +7989,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
79597989 forwarded_htlc_value_msat: Option<u64>, skimmed_fee_msat: Option<u64>, from_onchain: bool,
79607990 startup_replay: bool, next_channel_counterparty_node_id: PublicKey,
79617991 next_channel_outpoint: OutPoint, next_channel_id: ChannelId,
7962- next_user_channel_id: Option<u128>,
7992+ next_user_channel_id: Option<u128>, attribution_data: Option<&AttributionData>,
7993+ send_timestamp: Option<Duration>,
79637994 ) {
79647995 match source {
79657996 HTLCSource::OutboundRoute {
@@ -7991,10 +8022,25 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
79918022 let prev_node_id = hop_data.counterparty_node_id;
79928023 let completed_blocker =
79938024 RAAMonitorUpdateBlockingAction::from_prev_hop_data(&hop_data);
8025+
8026+ // Obtain hold time, if available.
8027+ let now = duration_since_epoch();
8028+ let hold_time = hold_time(send_timestamp, now).unwrap_or(0);
8029+
8030+ // If attribution data was received from downstream, we shift it and get it ready for adding our hold
8031+ // time. Note that fulfilled HTLCs take a fast path to the incoming side. We don't need to wait for RAA
8032+ // to record the hold time like we do for failed HTLCs.
8033+ let attribution_data = process_fulfill_attribution_data(
8034+ attribution_data,
8035+ &hop_data.incoming_packet_shared_secret,
8036+ hold_time,
8037+ );
8038+
79948039 self.claim_funds_from_hop(
79958040 hop_data,
79968041 payment_preimage,
79978042 None,
8043+ Some(attribution_data),
79988044 |htlc_claim_value_msat, definitely_duplicate| {
79998045 let chan_to_release = Some(EventUnblockedChannel {
80008046 counterparty_node_id: next_channel_counterparty_node_id,
@@ -9553,7 +9599,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
95539599 ) -> Result<(), MsgHandleErrInternal> {
95549600 let funding_txo;
95559601 let next_user_channel_id;
9556- let (htlc_source, forwarded_htlc_value, skimmed_fee_msat) = {
9602+ let (htlc_source, forwarded_htlc_value, skimmed_fee_msat, send_timestamp ) = {
95579603 let per_peer_state = self.per_peer_state.read().unwrap();
95589604 let peer_state_mutex = per_peer_state.get(counterparty_node_id).ok_or_else(|| {
95599605 debug_assert!(false);
@@ -9608,6 +9654,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
96089654 funding_txo,
96099655 msg.channel_id,
96109656 Some(next_user_channel_id),
9657+ msg.attribution_data.as_ref(),
9658+ send_timestamp,
96119659 );
96129660
96139661 Ok(())
@@ -10429,6 +10477,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1042910477 "Claiming HTLC with preimage {} from our monitor",
1043010478 preimage
1043110479 );
10480+ // Claim the funds from the previous hop, if there is one. Because this is in response to a
10481+ // chain event, no attribution data is available.
1043210482 self.claim_funds_internal(
1043310483 htlc_update.source,
1043410484 preimage,
@@ -10440,6 +10490,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1044010490 funding_outpoint,
1044110491 channel_id,
1044210492 None,
10493+ None,
10494+ None,
1044310495 );
1044410496 } else {
1044510497 log_trace!(
@@ -16293,10 +16345,14 @@ where
1629316345 // Note that we don't need to pass the `payment_info` here - its
1629416346 // already (clearly) durably on disk in the `ChannelMonitor` so there's
1629516347 // no need to worry about getting it into others.
16348+ //
16349+ // We don't encode any attribution data, because the required onion shared secret isn't
16350+ // available here.
1629616351 channel_manager.claim_mpp_part(
1629716352 part.into(),
1629816353 payment_preimage,
1629916354 None,
16355+ None,
1630016356 |_, _| {
1630116357 (
1630216358 Some(MonitorUpdateCompletionAction::PaymentClaimed {
@@ -16441,6 +16497,7 @@ where
1644116497 // We use `downstream_closed` in place of `from_onchain` here just as a guess - we
1644216498 // don't remember in the `ChannelMonitor` where we got a preimage from, but if the
1644316499 // channel is closed we just assume that it probably came from an on-chain claim.
16500+ // The same holds for attribution data. We don't have any, so we pass an empty one.
1644416501 channel_manager.claim_funds_internal(
1644516502 source,
1644616503 preimage,
@@ -16452,6 +16509,8 @@ where
1645216509 downstream_funding,
1645316510 downstream_channel_id,
1645416511 None,
16512+ None,
16513+ None,
1645516514 );
1645616515 }
1645716516
0 commit comments