@@ -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, AttributionData };
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
+ send_timestamp: Option<Duration>,
326
328
}
327
329
328
330
/// See AwaitingRemoteRevoke ChannelState for more info
@@ -4982,7 +4984,7 @@ trait FailHTLCContents {
4982
4984
impl FailHTLCContents for msgs::OnionErrorPacket {
4983
4985
type Message = msgs::UpdateFailHTLC;
4984
4986
fn to_message(self, htlc_id: u64, channel_id: ChannelId) -> Self::Message {
4985
- msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data }
4987
+ msgs::UpdateFailHTLC { htlc_id, channel_id, reason: self.data, attribution_data: self.attribution_data }
4986
4988
}
4987
4989
fn to_inbound_htlc_state(self) -> InboundHTLCState {
4988
4990
InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(self))
@@ -6148,10 +6150,16 @@ impl<SP: Deref> FundedChannel<SP> where
6148
6150
false
6149
6151
} else { true }
6150
6152
});
6153
+ let now = duration_since_epoch();
6151
6154
pending_outbound_htlcs.retain(|htlc| {
6152
6155
if let &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) = &htlc.state {
6153
6156
log_trace!(logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}", &htlc.payment_hash);
6154
- if let OutboundHTLCOutcome::Failure(reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
6157
+ if let OutboundHTLCOutcome::Failure(mut reason) = outcome.clone() { // We really want take() here, but, again, non-mut ref :(
6158
+ if let (Some(timestamp), Some(now)) = (htlc.send_timestamp, now) {
6159
+ let hold_time = u32::try_from(now.saturating_sub(timestamp).as_millis()).unwrap_or(u32::MAX);
6160
+ reason.set_hold_time(hold_time);
6161
+ }
6162
+
6155
6163
revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
6156
6164
} else {
6157
6165
finalized_claimed_htlcs.push(htlc.source.clone());
@@ -6897,6 +6905,7 @@ impl<SP: Deref> FundedChannel<SP> where
6897
6905
channel_id: self.context.channel_id(),
6898
6906
htlc_id: htlc.htlc_id,
6899
6907
reason: err_packet.data.clone(),
6908
+ attribution_data: err_packet.attribution_data.clone(),
6900
6909
});
6901
6910
},
6902
6911
&InboundHTLCRemovalReason::FailMalformed((ref sha256_of_onion, ref failure_code)) => {
@@ -8723,6 +8732,13 @@ impl<SP: Deref> FundedChannel<SP> where
8723
8732
return Ok(None);
8724
8733
}
8725
8734
8735
+ // Record the approximate time when the HTLC is sent to the peer. This timestamp is later used to calculate the
8736
+ // htlc hold time for reporting back to the sender. There is some freedom to report a time including or
8737
+ // excluding our own processing time. What we choose here doesn't matter all that much, because it will probably
8738
+ // just shift sender-applied penalties between our incoming and outgoing side. So we choose measuring points
8739
+ // that are simple to implement, and we do it on the outgoing side because then the failure message that encodes
8740
+ // the hold time still needs to be built in channel manager.
8741
+ let send_timestamp = duration_since_epoch();
8726
8742
self.context.pending_outbound_htlcs.push(OutboundHTLCOutput {
8727
8743
htlc_id: self.context.next_holder_htlc_id,
8728
8744
amount_msat,
@@ -8732,6 +8748,7 @@ impl<SP: Deref> FundedChannel<SP> where
8732
8748
source,
8733
8749
blinding_point,
8734
8750
skimmed_fee_msat,
8751
+ send_timestamp,
8735
8752
});
8736
8753
8737
8754
let res = msgs::UpdateAddHTLC {
@@ -10305,6 +10322,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10305
10322
dropped_inbound_htlcs += 1;
10306
10323
}
10307
10324
}
10325
+ let mut removed_htlc_failure_attribution_data: Vec<&Option<AttributionData>> = Vec::new();
10308
10326
(self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
10309
10327
for htlc in self.context.pending_inbound_htlcs.iter() {
10310
10328
if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -10330,9 +10348,10 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10330
10348
&InboundHTLCState::LocalRemoved(ref removal_reason) => {
10331
10349
4u8.write(writer)?;
10332
10350
match removal_reason {
10333
- InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data }) => {
10351
+ InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket { data, attribution_data }) => {
10334
10352
0u8.write(writer)?;
10335
10353
data.write(writer)?;
10354
+ removed_htlc_failure_attribution_data.push(&attribution_data);
10336
10355
},
10337
10356
InboundHTLCRemovalReason::FailMalformed((hash, code)) => {
10338
10357
1u8.write(writer)?;
@@ -10392,11 +10411,13 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10392
10411
pending_outbound_blinding_points.push(htlc.blinding_point);
10393
10412
}
10394
10413
10395
- let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::new();
10396
- let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::new();
10414
+ let holding_cell_htlc_update_count = self.context.holding_cell_htlc_updates.len();
10415
+ let mut holding_cell_skimmed_fees: Vec<Option<u64>> = Vec::with_capacity(holding_cell_htlc_update_count);
10416
+ let mut holding_cell_blinding_points: Vec<Option<PublicKey>> = Vec::with_capacity(holding_cell_htlc_update_count);
10417
+ let mut holding_cell_failure_attribution_data: Vec<Option<&AttributionData>> = Vec::with_capacity(holding_cell_htlc_update_count);
10397
10418
// Vec of (htlc_id, failure_code, sha256_of_onion)
10398
10419
let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
10399
- (self.context.holding_cell_htlc_updates.len() as u64).write(writer)?;
10420
+ (holding_cell_htlc_update_count as u64).write(writer)?;
10400
10421
for update in self.context.holding_cell_htlc_updates.iter() {
10401
10422
match update {
10402
10423
&HTLCUpdateAwaitingACK::AddHTLC {
@@ -10422,6 +10443,9 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10422
10443
2u8.write(writer)?;
10423
10444
htlc_id.write(writer)?;
10424
10445
err_packet.data.write(writer)?;
10446
+
10447
+ // Store the attribution data for later writing.
10448
+ holding_cell_failure_attribution_data.push(err_packet.attribution_data.as_ref());
10425
10449
}
10426
10450
&HTLCUpdateAwaitingACK::FailMalformedHTLC {
10427
10451
htlc_id, failure_code, sha256_of_onion
@@ -10433,6 +10457,10 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10433
10457
2u8.write(writer)?;
10434
10458
htlc_id.write(writer)?;
10435
10459
Vec::<u8>::new().write(writer)?;
10460
+
10461
+ // Push 'None' attribution data for FailMalformedHTLC, because FailMalformedHTLC uses the same
10462
+ // type 2 and is deserialized as a FailHTLC.
10463
+ holding_cell_failure_attribution_data.push(None);
10436
10464
}
10437
10465
}
10438
10466
}
@@ -10605,6 +10633,8 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10605
10633
(49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
10606
10634
(51, is_manual_broadcast, option), // Added in 0.0.124
10607
10635
(53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
10636
+ (55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
10637
+ (57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
10608
10638
});
10609
10639
10610
10640
Ok(())
@@ -10682,6 +10712,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10682
10712
let reason = match <u8 as Readable>::read(reader)? {
10683
10713
0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
10684
10714
data: Readable::read(reader)?,
10715
+ attribution_data: None,
10685
10716
}),
10686
10717
1 => InboundHTLCRemovalReason::FailMalformed(Readable::read(reader)?),
10687
10718
2 => InboundHTLCRemovalReason::Fulfill(Readable::read(reader)?),
@@ -10722,6 +10753,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10722
10753
},
10723
10754
skimmed_fee_msat: None,
10724
10755
blinding_point: None,
10756
+ send_timestamp: None,
10725
10757
});
10726
10758
}
10727
10759
@@ -10746,6 +10778,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10746
10778
htlc_id: Readable::read(reader)?,
10747
10779
err_packet: OnionErrorPacket {
10748
10780
data: Readable::read(reader)?,
10781
+ attribution_data: None,
10749
10782
},
10750
10783
},
10751
10784
_ => return Err(DecodeError::InvalidValue),
@@ -10889,6 +10922,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10889
10922
let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
10890
10923
let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
10891
10924
10925
+ let mut removed_htlc_failure_attribution_data: Option<Vec<Option<AttributionData>>> = None;
10926
+ let mut holding_cell_failure_attribution_data: Option<Vec<Option<AttributionData>>> = None;
10927
+
10892
10928
let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
10893
10929
let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
10894
10930
@@ -10931,6 +10967,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
10931
10967
(49, local_initiated_shutdown, option),
10932
10968
(51, is_manual_broadcast, option),
10933
10969
(53, funding_tx_broadcast_safe_event_emitted, option),
10970
+ (55, removed_htlc_failure_attribution_data, optional_vec),
10971
+ (57, holding_cell_failure_attribution_data, optional_vec),
10934
10972
});
10935
10973
10936
10974
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -11012,6 +11050,38 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11012
11050
if iter.next().is_some() { return Err(DecodeError::InvalidValue) }
11013
11051
}
11014
11052
11053
+ if let Some(attribution_data_list) = removed_htlc_failure_attribution_data {
11054
+ let mut removed_htlc_relay_failures =
11055
+ pending_inbound_htlcs.iter_mut().filter_map(|status|
11056
+ if let InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(ref mut packet)) = &mut status.state {
11057
+ Some(&mut packet.attribution_data)
11058
+ } else {
11059
+ None
11060
+ }
11061
+ );
11062
+
11063
+ for attribution_data in attribution_data_list {
11064
+ *removed_htlc_relay_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
11065
+ }
11066
+ if removed_htlc_relay_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
11067
+ }
11068
+
11069
+ if let Some(attribution_data_list) = holding_cell_failure_attribution_data {
11070
+ let mut holding_cell_failures =
11071
+ holding_cell_htlc_updates.iter_mut().filter_map(|upd|
11072
+ if let HTLCUpdateAwaitingACK::FailHTLC { err_packet: OnionErrorPacket { ref mut attribution_data, .. }, .. } = upd {
11073
+ Some(attribution_data)
11074
+ } else {
11075
+ None
11076
+ }
11077
+ );
11078
+
11079
+ for attribution_data in attribution_data_list {
11080
+ *holding_cell_failures.next().ok_or(DecodeError::InvalidValue)? = attribution_data;
11081
+ }
11082
+ if holding_cell_failures.next().is_some() { return Err(DecodeError::InvalidValue); }
11083
+ }
11084
+
11015
11085
if let Some(malformed_htlcs) = malformed_htlcs {
11016
11086
for (malformed_htlc_id, failure_code, sha256_of_onion) in malformed_htlcs {
11017
11087
let htlc_idx = holding_cell_htlc_updates.iter().position(|htlc| {
@@ -11201,6 +11271,18 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11201
11271
}
11202
11272
}
11203
11273
11274
+ fn duration_since_epoch() -> Option<Duration> {
11275
+ #[cfg(not(feature = "std"))]
11276
+ let now = None;
11277
+
11278
+ #[cfg(feature = "std")]
11279
+ let now = Some(std::time::SystemTime::now()
11280
+ .duration_since(std::time::SystemTime::UNIX_EPOCH)
11281
+ .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"));
11282
+
11283
+ now
11284
+ }
11285
+
11204
11286
#[cfg(test)]
11205
11287
mod tests {
11206
11288
use std::cmp;
@@ -11214,7 +11296,7 @@ mod tests {
11214
11296
use bitcoin::network::Network;
11215
11297
#[cfg(splicing)]
11216
11298
use bitcoin::Weight;
11217
- use crate::ln::onion_utils::INVALID_ONION_BLINDING;
11299
+ use crate::ln::onion_utils::{AttributionData, INVALID_ONION_BLINDING} ;
11218
11300
use crate::types::payment::{PaymentHash, PaymentPreimage};
11219
11301
use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
11220
11302
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
@@ -11436,6 +11518,7 @@ mod tests {
11436
11518
},
11437
11519
skimmed_fee_msat: None,
11438
11520
blinding_point: None,
11521
+ send_timestamp: None,
11439
11522
});
11440
11523
11441
11524
// Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
@@ -11820,6 +11903,7 @@ mod tests {
11820
11903
source: dummy_htlc_source.clone(),
11821
11904
skimmed_fee_msat: None,
11822
11905
blinding_point: None,
11906
+ send_timestamp: None,
11823
11907
};
11824
11908
let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
11825
11909
for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
@@ -11851,7 +11935,7 @@ mod tests {
11851
11935
htlc_id: 0,
11852
11936
};
11853
11937
let dummy_holding_cell_failed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailHTLC {
11854
- htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42] }
11938
+ htlc_id, err_packet: msgs::OnionErrorPacket { data: vec![42], attribution_data: Some(AttributionData::new()) }
11855
11939
};
11856
11940
let dummy_holding_cell_malformed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailMalformedHTLC {
11857
11941
htlc_id, failure_code: INVALID_ONION_BLINDING, sha256_of_onion: [0; 32],
@@ -12133,6 +12217,7 @@ mod tests {
12133
12217
source: HTLCSource::dummy(),
12134
12218
skimmed_fee_msat: None,
12135
12219
blinding_point: None,
12220
+ send_timestamp: None,
12136
12221
};
12137
12222
out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).to_byte_array();
12138
12223
out
@@ -12147,6 +12232,7 @@ mod tests {
12147
12232
source: HTLCSource::dummy(),
12148
12233
skimmed_fee_msat: None,
12149
12234
blinding_point: None,
12235
+ send_timestamp: None,
12150
12236
};
12151
12237
out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).to_byte_array();
12152
12238
out
@@ -12559,6 +12645,7 @@ mod tests {
12559
12645
source: HTLCSource::dummy(),
12560
12646
skimmed_fee_msat: None,
12561
12647
blinding_point: None,
12648
+ send_timestamp: None,
12562
12649
};
12563
12650
out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
12564
12651
out
@@ -12573,6 +12660,7 @@ mod tests {
12573
12660
source: HTLCSource::dummy(),
12574
12661
skimmed_fee_msat: None,
12575
12662
blinding_point: None,
12663
+ send_timestamp: None,
12576
12664
};
12577
12665
out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
12578
12666
out
0 commit comments