@@ -50,7 +50,7 @@ use crate::ln::chan_utils::{
5050#[cfg(splicing)]
5151use crate::ln::chan_utils::FUNDING_TRANSACTION_WITNESS_WEIGHT;
5252use crate::ln::chan_utils;
53- use crate::ln::onion_utils::{HTLCFailReason};
53+ use crate::ln::onion_utils::{HTLCFailReason, ATTRIBUTION_DATA_LEN };
5454use crate::chain::BestBlock;
5555use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator, fee_for_weight};
5656use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
@@ -68,6 +68,7 @@ use crate::util::scid_utils::scid_from_parts;
6868
6969use crate::io;
7070use crate::prelude::*;
71+ use core::time::Duration;
7172use core::{cmp,mem,fmt};
7273use core::ops::Deref;
7374#[cfg(any(test, fuzzing, debug_assertions))]
@@ -323,6 +324,7 @@ struct OutboundHTLCOutput {
323324 source: HTLCSource,
324325 blinding_point: Option<PublicKey>,
325326 skimmed_fee_msat: Option<u64>,
327+ timestamp: Option<Duration>,
326328}
327329
328330/// See AwaitingRemoteRevoke ChannelState for more info
@@ -4933,7 +4935,7 @@ trait FailHTLCContents {
49334935impl FailHTLCContents for msgs::OnionErrorPacket {
49344936 type Message = msgs::UpdateFailHTLC;
49354937 fn to_message(self, htlc_id: u64, channel_id: ChannelId) -> Self::Message {
4936- msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data }
4938+ msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data, attribution_data: self.attribution_data }
49374939 }
49384940 fn to_inbound_htlc_state(self) -> InboundHTLCState {
49394941 InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(self))
@@ -6100,10 +6102,16 @@ impl<SP: Deref> FundedChannel<SP> where
61006102 false
61016103 } else { true }
61026104 });
6105+ let now = duration_since_epoch();
61036106 pending_outbound_htlcs.retain(|htlc| {
61046107 if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) = &htlc.state {
61056108 log_trace!(logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}", &htlc.payment_hash);
6106- if let OutboundHTLCOutcome::Failure(reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
6109+ if let OutboundHTLCOutcome::Failure(mut reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
6110+ if let (Some(timestamp), Some(now)) = (htlc.timestamp, now) {
6111+ let hold_time = u32::try_from((now - timestamp).as_millis()).unwrap_or(u32::MAX);
6112+ reason.set_hold_time(hold_time);
6113+ }
6114+
61076115 revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
61086116 } else {
61096117 finalized_claimed_htlcs.push(htlc.source.clone());
@@ -6845,6 +6853,7 @@ impl<SP: Deref> FundedChannel<SP> where
68456853 channel_id: self.context.channel_id(),
68466854 htlc_id: htlc.htlc_id,
68476855 reason: err_packet.data.clone(),
6856+ attribution_data: err_packet.attribution_data,
68486857 });
68496858 },
68506859 &InboundHTLCRemovalReason::FailMalformed((ref sha256_of_onion, ref failure_code)) => {
@@ -8671,6 +8680,7 @@ impl<SP: Deref> FundedChannel<SP> where
86718680 return Ok(None);
86728681 }
86738682
8683+ let timestamp = duration_since_epoch();
86748684 self.context.pending_outbound_htlcs.push(OutboundHTLCOutput {
86758685 htlc_id: self.context.next_holder_htlc_id,
86768686 amount_msat,
@@ -8680,6 +8690,7 @@ impl<SP: Deref> FundedChannel<SP> where
86808690 source,
86818691 blinding_point,
86828692 skimmed_fee_msat,
8693+ timestamp,
86838694 });
86848695
86858696 let res = msgs::UpdateAddHTLC {
@@ -10247,6 +10258,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1024710258 dropped_inbound_htlcs += 1;
1024810259 }
1024910260 }
10261+ let mut removed_htlc_failure_attribution_data: Vec<&Option<[u8; ATTRIBUTION_DATA_LEN]>> = Vec::new();
1025010262 (self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
1025110263 for htlc in self.context.pending_inbound_htlcs.iter() {
1025210264 if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -10272,9 +10284,10 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1027210284 &InboundHTLCState::LocalRemoved(ref removal_reason) => {
1027310285 4u8.write(writer)?;
1027410286 match removal_reason {
10275- InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data }) => {
10287+ InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data, attribution_data }) => {
1027610288 0u8.write(writer)?;
1027710289 data.write(writer)?;
10290+ removed_htlc_failure_attribution_data.push(&attribution_data);
1027810291 },
1027910292 InboundHTLCRemovalReason::FailMalformed((hash, code)) => {
1028010293 1u8.write(writer)?;
@@ -10336,10 +10349,11 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1033610349
1033710350 let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
1033810351 let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::new();
10352+ let mut holding_cell_failure_attribution_data: Vec<(u32, [u8; ATTRIBUTION_DATA_LEN])> = Vec::new();
1033910353 // Vec of (htlc_id, failure_code, sha256_of_onion)
1034010354 let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
1034110355 (self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
10342- for update in self.context.holding_cell_htlc_updates.iter() {
10356+ for (i, update) in self.context.holding_cell_htlc_updates.iter().enumerate () {
1034310357 match update {
1034410358 &HTLCUpdateAwaitingACK::AddHTLC {
1034510359 ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet,
@@ -10364,6 +10378,13 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1036410378 2u8.write(writer)?;
1036510379 htlc_id.write(writer)?;
1036610380 err_packet.data.write(writer)?;
10381+
10382+ // Store the attribution data for later writing. Include the holding cell htlc update index because
10383+ // FailMalformedHTLC is stored with the same type 2 and we wouldn't be able to distinguish the two
10384+ // when reading back in.
10385+ if let Some(attribution_data ) = err_packet.attribution_data {
10386+ holding_cell_failure_attribution_data.push((i as u32, attribution_data));
10387+ }
1036710388 }
1036810389 &HTLCUpdateAwaitingACK::FailMalformedHTLC {
1036910390 htlc_id, failure_code, sha256_of_onion
@@ -10547,6 +10568,8 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1054710568 (49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
1054810569 (51, is_manual_broadcast, option), // Added in 0.0.124
1054910570 (53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
10571+ (55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
10572+ (57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
1055010573 });
1055110574
1055210575 Ok(())
@@ -10624,6 +10647,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1062410647 let reason = match <u8 as Readable>::read(reader)? {
1062510648 0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
1062610649 data: Readable::read(reader)?,
10650+ attribution_data: None,
1062710651 }),
1062810652 1 => InboundHTLCRemovalReason::FailMalformed(Readable::read(reader)?),
1062910653 2 => InboundHTLCRemovalReason::Fulfill(Readable::read(reader)?),
@@ -10664,6 +10688,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1066410688 },
1066510689 skimmed_fee_msat: None,
1066610690 blinding_point: None,
10691+ timestamp: None,
1066710692 });
1066810693 }
1066910694
@@ -10688,6 +10713,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1068810713 htlc_id: Readable::read(reader)?,
1068910714 err_packet: OnionErrorPacket {
1069010715 data: Readable::read(reader)?,
10716+ attribution_data: None,
1069110717 },
1069210718 },
1069310719 _ => return Err(DecodeError::InvalidValue),
@@ -10831,6 +10857,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1083110857 let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1083210858 let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1083310859
10860+ let mut removed_htlc_failure_attribution_data: Option<Vec<Option<[u8; ATTRIBUTION_DATA_LEN]>>> = None;
10861+ let mut holding_cell_failure_attribution_data: Option<Vec<(u32, [u8; ATTRIBUTION_DATA_LEN])>> = None;
10862+
1083410863 let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
1083510864 let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
1083610865
@@ -10873,6 +10902,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1087310902 (49, local_initiated_shutdown, option),
1087410903 (51, is_manual_broadcast, option),
1087510904 (53, funding_tx_broadcast_safe_event_emitted, option),
10905+ (55, removed_htlc_failure_attribution_data, optional_vec),
10906+ (57, holding_cell_failure_attribution_data, optional_vec),
1087610907 });
1087710908
1087810909 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -10954,6 +10985,38 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1095410985 if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
1095510986 }
1095610987
10988+ if let Some(attribution_datas) = removed_htlc_failure_attribution_data {
10989+ let mut removed_htlc_relay_failures =
10990+ pending_inbound_htlcs.iter_mut().filter_map(|status|
10991+ if let InboundHTLCState::LocalRemoved(ref mut reason) = &mut status.state {
10992+ if let InboundHTLCRemovalReason::FailRelay(ref mut packet) = reason {
10993+ Some(&mut packet.attribution_data)
10994+ } else {
10995+ None
10996+ }
10997+ } else {
10998+ None
10999+ }
11000+ );
11001+
11002+ for attribution_data in attribution_datas {
11003+ *removed_htlc_relay_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
11004+ }
11005+ if removed_htlc_relay_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
11006+ }
11007+
11008+ if let Some(attribution_datas) = holding_cell_failure_attribution_data {
11009+ for (i, attribution_data) in attribution_datas {
11010+ let update = holding_cell_htlc_updates.get_mut(i as usize).ok_or(DecodeError::InvalidValue)?;
11011+
11012+ if let HTLCUpdateAwaitingACK::FailHTLC { htlc_id: _, ref mut err_packet } = update {
11013+ err_packet.attribution_data = Some(attribution_data);
11014+ } else {
11015+ return Err(DecodeError::InvalidValue);
11016+ }
11017+ }
11018+ }
11019+
1095711020 if let Some(malformed_htlcs) = malformed_htlcs {
1095811021 for (malformed_htlc_id, failure_code, sha256_of_onion) in malformed_htlcs {
1095911022 let htlc_idx = holding_cell_htlc_updates.iter().position(|htlc| {
@@ -11144,6 +11207,18 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1114411207 }
1114511208}
1114611209
11210+ fn duration_since_epoch() -> Option<Duration> {
11211+ #[cfg(not(feature = "std"))]
11212+ let now = None;
11213+
11214+ #[cfg(feature = "std")]
11215+ let now = Some(std::time::SystemTime::now()
11216+ .duration_since(std::time::SystemTime::UNIX_EPOCH)
11217+ .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"));
11218+
11219+ now
11220+ }
11221+
1114711222#[cfg(test)]
1114811223mod tests {
1114911224 use std::cmp;
@@ -11157,7 +11232,7 @@ mod tests {
1115711232 use bitcoin::network::Network;
1115811233 #[cfg(splicing)]
1115911234 use bitcoin::Weight;
11160- use crate::ln::onion_utils::INVALID_ONION_BLINDING;
11235+ use crate::ln::onion_utils::{ATTRIBUTION_DATA_LEN, INVALID_ONION_BLINDING} ;
1116111236 use crate::types::payment::{PaymentHash, PaymentPreimage};
1116211237 use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
1116311238 use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
@@ -11378,6 +11453,7 @@ mod tests {
1137811453 },
1137911454 skimmed_fee_msat: None,
1138011455 blinding_point: None,
11456+ timestamp: None,
1138111457 });
1138211458
1138311459 // Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
@@ -11762,6 +11838,7 @@ mod tests {
1176211838 source: dummy_htlc_source.clone(),
1176311839 skimmed_fee_msat: None,
1176411840 blinding_point: None,
11841+ timestamp: None,
1176511842 };
1176611843 let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
1176711844 for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
@@ -11793,7 +11870,7 @@ mod tests {
1179311870 htlc_id: 0,
1179411871 };
1179511872 let dummy_holding_cell_failed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailHTLC {
11796- htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42] }
11873+ htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42], attribution_data: Some([1; ATTRIBUTION_DATA_LEN]) }
1179711874 };
1179811875 let dummy_holding_cell_malformed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailMalformedHTLC {
1179911876 htlc_id, failure_code: INVALID_ONION_BLINDING, sha256_of_onion: [0; 32],
@@ -12084,6 +12161,7 @@ mod tests {
1208412161 source: HTLCSource::dummy(),
1208512162 skimmed_fee_msat: None,
1208612163 blinding_point: None,
12164+ timestamp: None,
1208712165 };
1208812166 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).to_byte_array();
1208912167 out
@@ -12098,6 +12176,7 @@ mod tests {
1209812176 source: HTLCSource::dummy(),
1209912177 skimmed_fee_msat: None,
1210012178 blinding_point: None,
12179+ timestamp: None,
1210112180 };
1210212181 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).to_byte_array();
1210312182 out
@@ -12510,6 +12589,7 @@ mod tests {
1251012589 source: HTLCSource::dummy(),
1251112590 skimmed_fee_msat: None,
1251212591 blinding_point: None,
12592+ timestamp: None,
1251312593 };
1251412594 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
1251512595 out
@@ -12524,6 +12604,7 @@ mod tests {
1252412604 source: HTLCSource::dummy(),
1252512605 skimmed_fee_msat: None,
1252612606 blinding_point: None,
12607+ timestamp: None,
1252712608 };
1252812609 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
1252912610 out
0 commit comments