@@ -49,7 +49,7 @@ use crate::ln::chan_utils::{
4949 ClosingTransaction, commit_tx_fee_sat,
5050};
5151use crate::ln::chan_utils;
52- use crate::ln::onion_utils::{HTLCFailReason};
52+ use crate::ln::onion_utils::{HTLCFailReason, ATTRIBUTION_DATA_LEN };
5353use crate::chain::BestBlock;
5454use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator, fee_for_weight};
5555use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
@@ -67,8 +67,11 @@ use crate::util::scid_utils::scid_from_parts;
6767
6868use crate::io;
6969use crate::prelude::*;
70+ use core::time::Duration;
7071use core::{cmp,mem,fmt};
7172use core::ops::Deref;
73+ #[cfg(feature = "std")]
74+ use std::time::SystemTime;
7275#[cfg(any(test, fuzzing, debug_assertions))]
7376use crate::sync::Mutex;
7477use crate::sign::type_resolver::ChannelSignerType;
@@ -322,6 +325,7 @@ struct OutboundHTLCOutput {
322325 source: HTLCSource,
323326 blinding_point: Option<PublicKey>,
324327 skimmed_fee_msat: Option<u64>,
328+ timestamp: Option<Duration>,
325329}
326330
327331/// See AwaitingRemoteRevoke ChannelState for more info
@@ -4856,7 +4860,7 @@ trait FailHTLCContents {
48564860impl FailHTLCContents for msgs::OnionErrorPacket {
48574861 type Message = msgs::UpdateFailHTLC;
48584862 fn to_message(self, htlc_id: u64, channel_id: ChannelId) -> Self::Message {
4859- msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data }
4863+ msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data, attribution_data: self.attribution_data }
48604864 }
48614865 fn to_inbound_htlc_state(self) -> InboundHTLCState {
48624866 InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(self))
@@ -6034,10 +6038,16 @@ impl<SP: Deref> FundedChannel<SP> where
60346038 false
60356039 } else { true }
60366040 });
6041+ let now = duration_since_epoch();
60376042 pending_outbound_htlcs.retain(|htlc| {
60386043 if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) = &htlc.state {
60396044 log_trace!(logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}", &htlc.payment_hash);
6040- if let OutboundHTLCOutcome::Failure(reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
6045+ if let OutboundHTLCOutcome::Failure(mut reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
6046+ if let (Some(timestamp), Some(now)) = (htlc.timestamp, now) {
6047+ let hold_time = u32::try_from((now - timestamp).as_millis()).unwrap_or(u32::MAX);
6048+ reason.set_hold_time(hold_time);
6049+ }
6050+
60416051 revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
60426052 } else {
60436053 finalized_claimed_htlcs.push(htlc.source.clone());
@@ -6779,6 +6789,7 @@ impl<SP: Deref> FundedChannel<SP> where
67796789 channel_id: self.context.channel_id(),
67806790 htlc_id: htlc.htlc_id,
67816791 reason: err_packet.data.clone(),
6792+ attribution_data: err_packet.attribution_data,
67826793 });
67836794 },
67846795 &InboundHTLCRemovalReason::FailMalformed((ref sha256_of_onion, ref failure_code)) => {
@@ -8471,6 +8482,7 @@ impl<SP: Deref> FundedChannel<SP> where
84718482 return Ok(None);
84728483 }
84738484
8485+ let timestamp = duration_since_epoch();
84748486 self.context.pending_outbound_htlcs.push(OutboundHTLCOutput {
84758487 htlc_id: self.context.next_holder_htlc_id,
84768488 amount_msat,
@@ -8480,6 +8492,7 @@ impl<SP: Deref> FundedChannel<SP> where
84808492 source,
84818493 blinding_point,
84828494 skimmed_fee_msat,
8495+ timestamp,
84838496 });
84848497
84858498 let res = msgs::UpdateAddHTLC {
@@ -10037,6 +10050,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1003710050 dropped_inbound_htlcs += 1;
1003810051 }
1003910052 }
10053+ let mut removed_htlc_failure_attribution_data: Vec<&Option<[u8; ATTRIBUTION_DATA_LEN]>> = Vec::new();
1004010054 (self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
1004110055 for htlc in self.context.pending_inbound_htlcs.iter() {
1004210056 if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -10062,9 +10076,10 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1006210076 &InboundHTLCState::LocalRemoved(ref removal_reason) => {
1006310077 4u8.write(writer)?;
1006410078 match removal_reason {
10065- InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data }) => {
10079+ InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data, attribution_data }) => {
1006610080 0u8.write(writer)?;
1006710081 data.write(writer)?;
10082+ removed_htlc_failure_attribution_data.push(&attribution_data);
1006810083 },
1006910084 InboundHTLCRemovalReason::FailMalformed((hash, code)) => {
1007010085 1u8.write(writer)?;
@@ -10126,10 +10141,11 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1012610141
1012710142 let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
1012810143 let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::new();
10144+ let mut holding_cell_failure_attribution_data: Vec<(u32, [u8; ATTRIBUTION_DATA_LEN])> = Vec::new();
1012910145 // Vec of (htlc_id, failure_code, sha256_of_onion)
1013010146 let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
1013110147 (self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
10132- for update in self.context.holding_cell_htlc_updates.iter() {
10148+ for (i, update) in self.context.holding_cell_htlc_updates.iter().enumerate () {
1013310149 match update {
1013410150 &HTLCUpdateAwaitingACK::AddHTLC {
1013510151 ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet,
@@ -10154,6 +10170,13 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1015410170 2u8.write(writer)?;
1015510171 htlc_id.write(writer)?;
1015610172 err_packet.data.write(writer)?;
10173+
10174+ // Store the attribution data for later writing. Include the holding cell htlc update index because
10175+ // FailMalformedHTLC is stored with the same type 2 and we wouldn't be able to distinguish the two
10176+ // when reading back in.
10177+ if let Some(attribution_data ) = err_packet.attribution_data {
10178+ holding_cell_failure_attribution_data.push((i as u32, attribution_data));
10179+ }
1015710180 }
1015810181 &HTLCUpdateAwaitingACK::FailMalformedHTLC {
1015910182 htlc_id, failure_code, sha256_of_onion
@@ -10337,6 +10360,8 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1033710360 (49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
1033810361 (51, is_manual_broadcast, option), // Added in 0.0.124
1033910362 (53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
10363+ (55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
10364+ (57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
1034010365 });
1034110366
1034210367 Ok(())
@@ -10414,6 +10439,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1041410439 let reason = match <u8 as Readable>::read(reader)? {
1041510440 0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
1041610441 data: Readable::read(reader)?,
10442+ attribution_data: None,
1041710443 }),
1041810444 1 => InboundHTLCRemovalReason::FailMalformed(Readable::read(reader)?),
1041910445 2 => InboundHTLCRemovalReason::Fulfill(Readable::read(reader)?),
@@ -10454,6 +10480,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1045410480 },
1045510481 skimmed_fee_msat: None,
1045610482 blinding_point: None,
10483+ timestamp: None,
1045710484 });
1045810485 }
1045910486
@@ -10478,6 +10505,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1047810505 htlc_id: Readable::read(reader)?,
1047910506 err_packet: OnionErrorPacket {
1048010507 data: Readable::read(reader)?,
10508+ attribution_data: None,
1048110509 },
1048210510 },
1048310511 _ => return Err(DecodeError::InvalidValue),
@@ -10621,6 +10649,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1062110649 let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1062210650 let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1062310651
10652+ let mut removed_htlc_failure_attribution_data: Option<Vec<Option<[u8; ATTRIBUTION_DATA_LEN]>>> = None;
10653+ let mut holding_cell_failure_attribution_data: Option<Vec<(u32, [u8; ATTRIBUTION_DATA_LEN])>> = None;
10654+
1062410655 let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
1062510656 let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
1062610657
@@ -10663,6 +10694,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1066310694 (49, local_initiated_shutdown, option),
1066410695 (51, is_manual_broadcast, option),
1066510696 (53, funding_tx_broadcast_safe_event_emitted, option),
10697+ (55, removed_htlc_failure_attribution_data, optional_vec),
10698+ (57, holding_cell_failure_attribution_data, optional_vec),
1066610699 });
1066710700
1066810701 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -10744,6 +10777,38 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1074410777 if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
1074510778 }
1074610779
10780+ if let Some(attribution_datas) = removed_htlc_failure_attribution_data {
10781+ let mut removed_htlc_relay_failures =
10782+ pending_inbound_htlcs.iter_mut().filter_map(|status|
10783+ if let InboundHTLCState::LocalRemoved(ref mut reason) = &mut status.state {
10784+ if let InboundHTLCRemovalReason::FailRelay(ref mut packet) = reason {
10785+ Some(&mut packet.attribution_data)
10786+ } else {
10787+ None
10788+ }
10789+ } else {
10790+ None
10791+ }
10792+ );
10793+
10794+ for attribution_data in attribution_datas {
10795+ *removed_htlc_relay_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
10796+ }
10797+ if removed_htlc_relay_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
10798+ }
10799+
10800+ if let Some(attribution_datas) = holding_cell_failure_attribution_data {
10801+ for (i, attribution_data) in attribution_datas {
10802+ let update = holding_cell_htlc_updates.get_mut(i as usize).ok_or(DecodeError::InvalidValue)?;
10803+
10804+ if let HTLCUpdateAwaitingACK::FailHTLC { htlc_id: _, ref mut err_packet } = update {
10805+ err_packet.attribution_data = Some(attribution_data);
10806+ } else {
10807+ return Err(DecodeError::InvalidValue);
10808+ }
10809+ }
10810+ }
10811+
1074710812 if let Some(malformed_htlcs) = malformed_htlcs {
1074810813 for (malformed_htlc_id, failure_code, sha256_of_onion) in malformed_htlcs {
1074910814 let htlc_idx = holding_cell_htlc_updates.iter().position(|htlc| {
@@ -10932,6 +10997,18 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1093210997 }
1093310998}
1093410999
11000+ fn duration_since_epoch() -> Option<Duration> {
11001+ #[cfg(not(feature = "std"))]
11002+ let now = None;
11003+
11004+ #[cfg(feature = "std")]
11005+ let now = Some(std::time::SystemTime::now()
11006+ .duration_since(std::time::SystemTime::UNIX_EPOCH)
11007+ .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"));
11008+
11009+ now
11010+ }
11011+
1093511012#[cfg(test)]
1093611013mod tests {
1093711014 use std::cmp;
@@ -10941,7 +11018,7 @@ mod tests {
1094111018 use bitcoin::transaction::{Transaction, TxOut, Version};
1094211019 use bitcoin::opcodes;
1094311020 use bitcoin::network::Network;
10944- use crate::ln::onion_utils::INVALID_ONION_BLINDING;
11021+ use crate::ln::onion_utils::{ATTRIBUTION_DATA_LEN, INVALID_ONION_BLINDING} ;
1094511022 use crate::types::payment::{PaymentHash, PaymentPreimage};
1094611023 use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
1094711024 use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
@@ -11162,6 +11239,7 @@ mod tests {
1116211239 },
1116311240 skimmed_fee_msat: None,
1116411241 blinding_point: None,
11242+ timestamp: None,
1116511243 });
1116611244
1116711245 // Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
@@ -11546,6 +11624,7 @@ mod tests {
1154611624 source: dummy_htlc_source.clone(),
1154711625 skimmed_fee_msat: None,
1154811626 blinding_point: None,
11627+ timestamp: None,
1154911628 };
1155011629 let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
1155111630 for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
@@ -11577,7 +11656,7 @@ mod tests {
1157711656 htlc_id: 0,
1157811657 };
1157911658 let dummy_holding_cell_failed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailHTLC {
11580- htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42] }
11659+ htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42], attribution_data: Some([1; ATTRIBUTION_DATA_LEN]) }
1158111660 };
1158211661 let dummy_holding_cell_malformed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailMalformedHTLC {
1158311662 htlc_id, failure_code: INVALID_ONION_BLINDING, sha256_of_onion: [0; 32],
0 commit comments