@@ -50,7 +50,7 @@ use crate::ln::chan_utils::{
50
50
#[cfg(splicing)]
51
51
use crate::ln::chan_utils::FUNDING_TRANSACTION_WITNESS_WEIGHT;
52
52
use crate::ln::chan_utils;
53
- use crate::ln::onion_utils::{HTLCFailReason};
53
+ use crate::ln::onion_utils::{HTLCFailReason, ATTRIBUTION_DATA_LEN };
54
54
use crate::chain::BestBlock;
55
55
use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator, fee_for_weight};
56
56
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
@@ -68,6 +68,7 @@ use crate::util::scid_utils::scid_from_parts;
68
68
69
69
use crate::io;
70
70
use crate::prelude::*;
71
+ use core::time::Duration;
71
72
use core::{cmp,mem,fmt};
72
73
use core::ops::Deref;
73
74
#[cfg(any(test, fuzzing, debug_assertions))]
@@ -323,6 +324,7 @@ struct OutboundHTLCOutput {
323
324
source: HTLCSource,
324
325
blinding_point: Option<PublicKey>,
325
326
skimmed_fee_msat: Option<u64>,
327
+ timestamp: Option<Duration>,
326
328
}
327
329
328
330
/// See AwaitingRemoteRevoke ChannelState for more info
@@ -4933,7 +4935,7 @@ trait FailHTLCContents {
4933
4935
impl FailHTLCContents for msgs::OnionErrorPacket {
4934
4936
type Message = msgs::UpdateFailHTLC;
4935
4937
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 }
4937
4939
}
4938
4940
fn to_inbound_htlc_state(self) -> InboundHTLCState {
4939
4941
InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(self))
@@ -6100,10 +6102,16 @@ impl<SP: Deref> FundedChannel<SP> where
6100
6102
false
6101
6103
} else { true }
6102
6104
});
6105
+ let now = duration_since_epoch();
6103
6106
pending_outbound_htlcs.retain(|htlc| {
6104
6107
if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) = &htlc.state {
6105
6108
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
+
6107
6115
revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
6108
6116
} else {
6109
6117
finalized_claimed_htlcs.push(htlc.source.clone());
@@ -6845,6 +6853,7 @@ impl<SP: Deref> FundedChannel<SP> where
6845
6853
channel_id: self.context.channel_id(),
6846
6854
htlc_id: htlc.htlc_id,
6847
6855
reason: err_packet.data.clone(),
6856
+ attribution_data: err_packet.attribution_data,
6848
6857
});
6849
6858
},
6850
6859
&InboundHTLCRemovalReason::FailMalformed((ref sha256_of_onion, ref failure_code)) => {
@@ -8671,6 +8680,7 @@ impl<SP: Deref> FundedChannel<SP> where
8671
8680
return Ok(None);
8672
8681
}
8673
8682
8683
+ let timestamp = duration_since_epoch();
8674
8684
self.context.pending_outbound_htlcs.push(OutboundHTLCOutput {
8675
8685
htlc_id: self.context.next_holder_htlc_id,
8676
8686
amount_msat,
@@ -8680,6 +8690,7 @@ impl<SP: Deref> FundedChannel<SP> where
8680
8690
source,
8681
8691
blinding_point,
8682
8692
skimmed_fee_msat,
8693
+ timestamp,
8683
8694
});
8684
8695
8685
8696
let res = msgs::UpdateAddHTLC {
@@ -10247,6 +10258,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10247
10258
dropped_inbound_htlcs += 1;
10248
10259
}
10249
10260
}
10261
+ let mut removed_htlc_failure_attribution_data: Vec<&Option<[u8; ATTRIBUTION_DATA_LEN]>> = Vec::new();
10250
10262
(self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
10251
10263
for htlc in self.context.pending_inbound_htlcs.iter() {
10252
10264
if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -10272,9 +10284,10 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10272
10284
&InboundHTLCState::LocalRemoved(ref removal_reason) => {
10273
10285
4u8.write(writer)?;
10274
10286
match removal_reason {
10275
- InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data }) => {
10287
+ InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data, attribution_data }) => {
10276
10288
0u8.write(writer)?;
10277
10289
data.write(writer)?;
10290
+ removed_htlc_failure_attribution_data.push(&attribution_data);
10278
10291
},
10279
10292
InboundHTLCRemovalReason::FailMalformed((hash, code)) => {
10280
10293
1u8.write(writer)?;
@@ -10336,10 +10349,11 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10336
10349
10337
10350
let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
10338
10351
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();
10339
10353
// Vec of (htlc_id, failure_code, sha256_of_onion)
10340
10354
let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
10341
10355
(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 () {
10343
10357
match update {
10344
10358
&HTLCUpdateAwaitingACK::AddHTLC {
10345
10359
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
10364
10378
2u8.write(writer)?;
10365
10379
htlc_id.write(writer)?;
10366
10380
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
+ }
10367
10388
}
10368
10389
&HTLCUpdateAwaitingACK::FailMalformedHTLC {
10369
10390
htlc_id, failure_code, sha256_of_onion
@@ -10547,6 +10568,8 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10547
10568
(49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
10548
10569
(51, is_manual_broadcast, option), // Added in 0.0.124
10549
10570
(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
10550
10573
});
10551
10574
10552
10575
Ok(())
@@ -10624,6 +10647,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10624
10647
let reason = match <u8 as Readable>::read(reader)? {
10625
10648
0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
10626
10649
data: Readable::read(reader)?,
10650
+ attribution_data: None,
10627
10651
}),
10628
10652
1 => InboundHTLCRemovalReason::FailMalformed(Readable::read(reader)?),
10629
10653
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
10664
10688
},
10665
10689
skimmed_fee_msat: None,
10666
10690
blinding_point: None,
10691
+ timestamp: None,
10667
10692
});
10668
10693
}
10669
10694
@@ -10688,6 +10713,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10688
10713
htlc_id: Readable::read(reader)?,
10689
10714
err_packet: OnionErrorPacket {
10690
10715
data: Readable::read(reader)?,
10716
+ attribution_data: None,
10691
10717
},
10692
10718
},
10693
10719
_ => return Err(DecodeError::InvalidValue),
@@ -10831,6 +10857,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10831
10857
let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
10832
10858
let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
10833
10859
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
+
10834
10863
let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
10835
10864
let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
10836
10865
@@ -10873,6 +10902,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10873
10902
(49, local_initiated_shutdown, option),
10874
10903
(51, is_manual_broadcast, option),
10875
10904
(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),
10876
10907
});
10877
10908
10878
10909
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
10954
10985
if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
10955
10986
}
10956
10987
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
+
10957
11020
if let Some(malformed_htlcs) = malformed_htlcs {
10958
11021
for (malformed_htlc_id, failure_code, sha256_of_onion) in malformed_htlcs {
10959
11022
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
11144
11207
}
11145
11208
}
11146
11209
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
+
11147
11222
#[cfg(test)]
11148
11223
mod tests {
11149
11224
use std::cmp;
@@ -11157,7 +11232,7 @@ mod tests {
11157
11232
use bitcoin::network::Network;
11158
11233
#[cfg(splicing)]
11159
11234
use bitcoin::Weight;
11160
- use crate::ln::onion_utils::INVALID_ONION_BLINDING;
11235
+ use crate::ln::onion_utils::{ATTRIBUTION_DATA_LEN, INVALID_ONION_BLINDING} ;
11161
11236
use crate::types::payment::{PaymentHash, PaymentPreimage};
11162
11237
use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
11163
11238
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
@@ -11378,6 +11453,7 @@ mod tests {
11378
11453
},
11379
11454
skimmed_fee_msat: None,
11380
11455
blinding_point: None,
11456
+ timestamp: None,
11381
11457
});
11382
11458
11383
11459
// Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
@@ -11762,6 +11838,7 @@ mod tests {
11762
11838
source: dummy_htlc_source.clone(),
11763
11839
skimmed_fee_msat: None,
11764
11840
blinding_point: None,
11841
+ timestamp: None,
11765
11842
};
11766
11843
let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
11767
11844
for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
@@ -11793,7 +11870,7 @@ mod tests {
11793
11870
htlc_id: 0,
11794
11871
};
11795
11872
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]) }
11797
11874
};
11798
11875
let dummy_holding_cell_malformed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailMalformedHTLC {
11799
11876
htlc_id, failure_code: INVALID_ONION_BLINDING, sha256_of_onion: [0; 32],
0 commit comments