@@ -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
@@ -4929,7 +4931,7 @@ trait FailHTLCContents {
49294931impl FailHTLCContents for msgs::OnionErrorPacket {
49304932 type Message = msgs::UpdateFailHTLC;
49314933 fn to_message(self, htlc_id: u64, channel_id: ChannelId) -> Self::Message {
4932- msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data }
4934+ msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data, attribution_data: self.attribution_data }
49334935 }
49344936 fn to_inbound_htlc_state(self) -> InboundHTLCState {
49354937 InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(self))
@@ -6095,10 +6097,16 @@ impl<SP: Deref> FundedChannel<SP> where
60956097 false
60966098 } else { true }
60976099 });
6100+ let now = duration_since_epoch();
60986101 pending_outbound_htlcs.retain(|htlc| {
60996102 if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) = &htlc.state {
61006103 log_trace!(logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}", &htlc.payment_hash);
6101- if let OutboundHTLCOutcome::Failure(reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
6104+ if let OutboundHTLCOutcome::Failure(mut reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
6105+ if let (Some(timestamp), Some(now)) = (htlc.timestamp, now) {
6106+ let hold_time = u32::try_from((now - timestamp).as_millis()).unwrap_or(u32::MAX);
6107+ reason.set_hold_time(hold_time);
6108+ }
6109+
61026110 revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
61036111 } else {
61046112 finalized_claimed_htlcs.push(htlc.source.clone());
@@ -6840,6 +6848,7 @@ impl<SP: Deref> FundedChannel<SP> where
68406848 channel_id: self.context.channel_id(),
68416849 htlc_id: htlc.htlc_id,
68426850 reason: err_packet.data.clone(),
6851+ attribution_data: err_packet.attribution_data,
68436852 });
68446853 },
68456854 &InboundHTLCRemovalReason::FailMalformed((ref sha256_of_onion, ref failure_code)) => {
@@ -8666,6 +8675,7 @@ impl<SP: Deref> FundedChannel<SP> where
86668675 return Ok(None);
86678676 }
86688677
8678+ let timestamp = duration_since_epoch();
86698679 self.context.pending_outbound_htlcs.push(OutboundHTLCOutput {
86708680 htlc_id: self.context.next_holder_htlc_id,
86718681 amount_msat,
@@ -8675,6 +8685,7 @@ impl<SP: Deref> FundedChannel<SP> where
86758685 source,
86768686 blinding_point,
86778687 skimmed_fee_msat,
8688+ timestamp,
86788689 });
86798690
86808691 let res = msgs::UpdateAddHTLC {
@@ -10242,6 +10253,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1024210253 dropped_inbound_htlcs += 1;
1024310254 }
1024410255 }
10256+ let mut removed_htlc_failure_attribution_data: Vec<&Option<[u8; ATTRIBUTION_DATA_LEN]>> = Vec::new();
1024510257 (self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
1024610258 for htlc in self.context.pending_inbound_htlcs.iter() {
1024710259 if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -10267,9 +10279,10 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1026710279 &InboundHTLCState::LocalRemoved(ref removal_reason) => {
1026810280 4u8.write(writer)?;
1026910281 match removal_reason {
10270- InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data }) => {
10282+ InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data, attribution_data }) => {
1027110283 0u8.write(writer)?;
1027210284 data.write(writer)?;
10285+ removed_htlc_failure_attribution_data.push(&attribution_data);
1027310286 },
1027410287 InboundHTLCRemovalReason::FailMalformed((hash, code)) => {
1027510288 1u8.write(writer)?;
@@ -10331,10 +10344,11 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1033110344
1033210345 let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
1033310346 let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::new();
10347+ let mut holding_cell_failure_attribution_data: Vec<(u32, [u8; ATTRIBUTION_DATA_LEN])> = Vec::new();
1033410348 // Vec of (htlc_id, failure_code, sha256_of_onion)
1033510349 let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
1033610350 (self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
10337- for update in self.context.holding_cell_htlc_updates.iter() {
10351+ for (i, update) in self.context.holding_cell_htlc_updates.iter().enumerate () {
1033810352 match update {
1033910353 &HTLCUpdateAwaitingACK::AddHTLC {
1034010354 ref amount_msat, ref cltv_expiry, ref payment_hash, ref source, ref onion_routing_packet,
@@ -10359,6 +10373,13 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1035910373 2u8.write(writer)?;
1036010374 htlc_id.write(writer)?;
1036110375 err_packet.data.write(writer)?;
10376+
10377+ // Store the attribution data for later writing. Include the holding cell htlc update index because
10378+ // FailMalformedHTLC is stored with the same type 2 and we wouldn't be able to distinguish the two
10379+ // when reading back in.
10380+ if let Some(attribution_data ) = err_packet.attribution_data {
10381+ holding_cell_failure_attribution_data.push((i as u32, attribution_data));
10382+ }
1036210383 }
1036310384 &HTLCUpdateAwaitingACK::FailMalformedHTLC {
1036410385 htlc_id, failure_code, sha256_of_onion
@@ -10542,6 +10563,8 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1054210563 (49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
1054310564 (51, is_manual_broadcast, option), // Added in 0.0.124
1054410565 (53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
10566+ (55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
10567+ (57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
1054510568 });
1054610569
1054710570 Ok(())
@@ -10619,6 +10642,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1061910642 let reason = match <u8 as Readable>::read(reader)? {
1062010643 0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
1062110644 data: Readable::read(reader)?,
10645+ attribution_data: None,
1062210646 }),
1062310647 1 => InboundHTLCRemovalReason::FailMalformed(Readable::read(reader)?),
1062410648 2 => InboundHTLCRemovalReason::Fulfill(Readable::read(reader)?),
@@ -10659,6 +10683,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1065910683 },
1066010684 skimmed_fee_msat: None,
1066110685 blinding_point: None,
10686+ timestamp: None,
1066210687 });
1066310688 }
1066410689
@@ -10683,6 +10708,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1068310708 htlc_id: Readable::read(reader)?,
1068410709 err_packet: OnionErrorPacket {
1068510710 data: Readable::read(reader)?,
10711+ attribution_data: None,
1068610712 },
1068710713 },
1068810714 _ => return Err(DecodeError::InvalidValue),
@@ -10826,6 +10852,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1082610852 let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1082710853 let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1082810854
10855+ let mut removed_htlc_failure_attribution_data: Option<Vec<Option<[u8; ATTRIBUTION_DATA_LEN]>>> = None;
10856+ let mut holding_cell_failure_attribution_data: Option<Vec<(u32, [u8; ATTRIBUTION_DATA_LEN])>> = None;
10857+
1082910858 let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
1083010859 let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
1083110860
@@ -10868,6 +10897,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1086810897 (49, local_initiated_shutdown, option),
1086910898 (51, is_manual_broadcast, option),
1087010899 (53, funding_tx_broadcast_safe_event_emitted, option),
10900+ (55, removed_htlc_failure_attribution_data, optional_vec),
10901+ (57, holding_cell_failure_attribution_data, optional_vec),
1087110902 });
1087210903
1087310904 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -10949,6 +10980,38 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1094910980 if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
1095010981 }
1095110982
10983+ if let Some(attribution_datas) = removed_htlc_failure_attribution_data {
10984+ let mut removed_htlc_relay_failures =
10985+ pending_inbound_htlcs.iter_mut().filter_map(|status|
10986+ if let InboundHTLCState::LocalRemoved(ref mut reason) = &mut status.state {
10987+ if let InboundHTLCRemovalReason::FailRelay(ref mut packet) = reason {
10988+ Some(&mut packet.attribution_data)
10989+ } else {
10990+ None
10991+ }
10992+ } else {
10993+ None
10994+ }
10995+ );
10996+
10997+ for attribution_data in attribution_datas {
10998+ *removed_htlc_relay_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
10999+ }
11000+ if removed_htlc_relay_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
11001+ }
11002+
11003+ if let Some(attribution_datas) = holding_cell_failure_attribution_data {
11004+ for (i, attribution_data) in attribution_datas {
11005+ let update = holding_cell_htlc_updates.get_mut(i as usize).ok_or(DecodeError::InvalidValue)?;
11006+
11007+ if let HTLCUpdateAwaitingACK::FailHTLC { htlc_id: _, ref mut err_packet } = update {
11008+ err_packet.attribution_data = Some(attribution_data);
11009+ } else {
11010+ return Err(DecodeError::InvalidValue);
11011+ }
11012+ }
11013+ }
11014+
1095211015 if let Some(malformed_htlcs) = malformed_htlcs {
1095311016 for (malformed_htlc_id, failure_code, sha256_of_onion) in malformed_htlcs {
1095411017 let htlc_idx = holding_cell_htlc_updates.iter().position(|htlc| {
@@ -11139,6 +11202,18 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1113911202 }
1114011203}
1114111204
11205+ fn duration_since_epoch() -> Option<Duration> {
11206+ #[cfg(not(feature = "std"))]
11207+ let now = None;
11208+
11209+ #[cfg(feature = "std")]
11210+ let now = Some(std::time::SystemTime::now()
11211+ .duration_since(std::time::SystemTime::UNIX_EPOCH)
11212+ .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"));
11213+
11214+ now
11215+ }
11216+
1114211217#[cfg(test)]
1114311218mod tests {
1114411219 use std::cmp;
@@ -11152,7 +11227,7 @@ mod tests {
1115211227 use bitcoin::network::Network;
1115311228 #[cfg(splicing)]
1115411229 use bitcoin::Weight;
11155- use crate::ln::onion_utils::INVALID_ONION_BLINDING;
11230+ use crate::ln::onion_utils::{ATTRIBUTION_DATA_LEN, INVALID_ONION_BLINDING} ;
1115611231 use crate::types::payment::{PaymentHash, PaymentPreimage};
1115711232 use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
1115811233 use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
@@ -11374,6 +11449,7 @@ mod tests {
1137411449 },
1137511450 skimmed_fee_msat: None,
1137611451 blinding_point: None,
11452+ timestamp: None,
1137711453 });
1137811454
1137911455 // Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
@@ -11758,6 +11834,7 @@ mod tests {
1175811834 source: dummy_htlc_source.clone(),
1175911835 skimmed_fee_msat: None,
1176011836 blinding_point: None,
11837+ timestamp: None,
1176111838 };
1176211839 let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
1176311840 for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
@@ -11789,7 +11866,7 @@ mod tests {
1178911866 htlc_id: 0,
1179011867 };
1179111868 let dummy_holding_cell_failed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailHTLC {
11792- htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42] }
11869+ htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42], attribution_data: Some([1; ATTRIBUTION_DATA_LEN]) }
1179311870 };
1179411871 let dummy_holding_cell_malformed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailMalformedHTLC {
1179511872 htlc_id, failure_code: INVALID_ONION_BLINDING, sha256_of_onion: [0; 32],
@@ -12080,6 +12157,7 @@ mod tests {
1208012157 source: HTLCSource::dummy(),
1208112158 skimmed_fee_msat: None,
1208212159 blinding_point: None,
12160+ timestamp: None,
1208312161 };
1208412162 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).to_byte_array();
1208512163 out
@@ -12094,6 +12172,7 @@ mod tests {
1209412172 source: HTLCSource::dummy(),
1209512173 skimmed_fee_msat: None,
1209612174 blinding_point: None,
12175+ timestamp: None,
1209712176 };
1209812177 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).to_byte_array();
1209912178 out
@@ -12506,6 +12585,7 @@ mod tests {
1250612585 source: HTLCSource::dummy(),
1250712586 skimmed_fee_msat: None,
1250812587 blinding_point: None,
12588+ timestamp: None,
1250912589 };
1251012590 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
1251112591 out
@@ -12520,6 +12600,7 @@ mod tests {
1252012600 source: HTLCSource::dummy(),
1252112601 skimmed_fee_msat: None,
1252212602 blinding_point: None,
12603+ timestamp: None,
1252312604 };
1252412605 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
1252512606 out
0 commit comments