Skip to content

Commit aadb03f

Browse files
committed
Add hold times to update_fulfill_htlc
1 parent f8c4577 commit aadb03f

File tree

11 files changed

+316
-44
lines changed

11 files changed

+316
-44
lines changed

fuzz/src/process_onion_failure.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
115115
let path = Path { hops, blinded_tail };
116116

117117
let htlc_source = HTLCSource::OutboundRoute {
118-
path,
118+
path: path.clone(),
119119
session_priv,
120120
first_hop_htlc_msat: 0,
121121
payment_id,
@@ -133,8 +133,19 @@ fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
133133
} else {
134134
None
135135
};
136-
let encrypted_packet = OnionErrorPacket { data: failure_data.into(), attribution_data };
136+
let encrypted_packet =
137+
OnionErrorPacket { data: failure_data.into(), attribution_data: attribution_data.clone() };
137138
lightning::ln::process_onion_failure(&secp_ctx, &logger, &htlc_source, encrypted_packet);
139+
140+
if let Some(attribution_data) = attribution_data {
141+
lightning::ln::process_onion_success(
142+
&secp_ctx,
143+
&logger,
144+
&path,
145+
&session_priv,
146+
attribution_data,
147+
);
148+
}
138149
}
139150

140151
/// Method that needs to be added manually, {name}_test

lightning-background-processor/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,6 +2732,7 @@ mod tests {
27322732
payment_id: PaymentId([42; 32]),
27332733
payment_hash: None,
27342734
path: path.clone(),
2735+
hold_times: None,
27352736
});
27362737
let event = $receive.expect("PaymentPathSuccessful not handled within deadline");
27372738
match event {

lightning/src/events/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,8 @@ pub enum Event {
10801080
///
10811081
/// May contain a closed channel if the HTLC sent along the path was fulfilled on chain.
10821082
path: Path,
1083+
/// The hold times as reported by each hop.
1084+
hold_times: Option<Vec<u32>>,
10831085
},
10841086
/// Indicates an outbound HTLC we sent failed, likely due to an intermediary node being unable to
10851087
/// handle the HTLC.
@@ -1816,13 +1818,19 @@ impl Writeable for Event {
18161818
(4, funding_info, required),
18171819
})
18181820
},
1819-
&Event::PaymentPathSuccessful { ref payment_id, ref payment_hash, ref path } => {
1821+
&Event::PaymentPathSuccessful {
1822+
ref payment_id,
1823+
ref payment_hash,
1824+
ref path,
1825+
ref hold_times,
1826+
} => {
18201827
13u8.write(writer)?;
18211828
write_tlv_fields!(writer, {
18221829
(0, payment_id, required),
18231830
(2, payment_hash, option),
18241831
(4, path.hops, required_vec),
18251832
(6, path.blinded_tail, option),
1833+
(8, hold_times, option),
18261834
})
18271835
},
18281836
&Event::PaymentFailed { ref payment_id, ref payment_hash, ref reason } => {
@@ -2311,11 +2319,13 @@ impl MaybeReadable for Event {
23112319
(2, payment_hash, option),
23122320
(4, path, required_vec),
23132321
(6, blinded_tail, option),
2322+
(8, hold_times, option),
23142323
});
23152324
Ok(Some(Event::PaymentPathSuccessful {
23162325
payment_id: payment_id.0.unwrap(),
23172326
payment_hash,
23182327
path: Path { hops: path, blinded_tail },
2328+
hold_times,
23192329
}))
23202330
};
23212331
f()

lightning/src/ln/async_payments_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ fn async_receive_flow_success() {
445445
let args = PassAlongPathArgs::new(&nodes[0], route[0], amt_msat, payment_hash, ev)
446446
.with_payment_preimage(keysend_preimage);
447447
do_pass_along_path(args);
448-
let res =
448+
let (res, _) =
449449
claim_payment_along_route(ClaimAlongRouteArgs::new(&nodes[0], route, keysend_preimage));
450450
assert!(res.is_some());
451451
assert_eq!(res, Some(PaidBolt12Invoice::StaticInvoice(static_invoice)));

lightning/src/ln/channel.rs

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ impl OutboundHTLCState {
402402
enum OutboundHTLCOutcome {
403403
/// We started always filling in the preimages here in 0.0.105, and the requirement
404404
/// that the preimages always be filled in was added in 0.2.
405-
Success(PaymentPreimage, #[allow(dead_code)] Option<AttributionData>),
405+
Success(PaymentPreimage, Option<AttributionData>),
406406
Failure(HTLCFailReason),
407407
}
408408

@@ -1181,7 +1181,7 @@ pub(super) struct MonitorRestoreUpdates {
11811181
pub order: RAACommitmentOrder,
11821182
pub accepted_htlcs: Vec<(PendingHTLCInfo, u64)>,
11831183
pub failed_htlcs: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
1184-
pub finalized_claimed_htlcs: Vec<HTLCSource>,
1184+
pub finalized_claimed_htlcs: Vec<(HTLCSource, Option<AttributionData>)>,
11851185
pub pending_update_adds: Vec<msgs::UpdateAddHTLC>,
11861186
pub funding_broadcastable: Option<Transaction>,
11871187
pub channel_ready: Option<msgs::ChannelReady>,
@@ -2313,7 +2313,7 @@ where
23132313
// but need to handle this somehow or we run the risk of losing HTLCs!
23142314
monitor_pending_forwards: Vec<(PendingHTLCInfo, u64)>,
23152315
monitor_pending_failures: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
2316-
monitor_pending_finalized_fulfills: Vec<HTLCSource>,
2316+
monitor_pending_finalized_fulfills: Vec<(HTLCSource, Option<AttributionData>)>,
23172317
monitor_pending_update_adds: Vec<msgs::UpdateAddHTLC>,
23182318
monitor_pending_tx_signatures: Option<msgs::TxSignatures>,
23192319

@@ -6215,7 +6215,7 @@ where
62156215
assert!(!self.context.channel_state.can_generate_new_commitment());
62166216
let mon_update_id = self.context.latest_monitor_update_id; // Forget the ChannelMonitor update
62176217
let fulfill_resp =
6218-
self.get_update_fulfill_htlc(htlc_id_arg, payment_preimage_arg, None, logger);
6218+
self.get_update_fulfill_htlc(htlc_id_arg, payment_preimage_arg, None, None, logger);
62196219
self.context.latest_monitor_update_id = mon_update_id;
62206220
if let UpdateFulfillFetch::NewClaim { update_blocked, .. } = fulfill_resp {
62216221
assert!(update_blocked); // The HTLC must have ended up in the holding cell.
@@ -6224,7 +6224,8 @@ where
62246224

62256225
fn get_update_fulfill_htlc<L: Deref>(
62266226
&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage,
6227-
payment_info: Option<PaymentClaimDetails>, logger: &L,
6227+
payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
6228+
logger: &L,
62286229
) -> UpdateFulfillFetch
62296230
where
62306231
L::Target: Logger,
@@ -6340,7 +6341,7 @@ where
63406341
self.context.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::ClaimHTLC {
63416342
payment_preimage: payment_preimage_arg,
63426343
htlc_id: htlc_id_arg,
6343-
attribution_data: None,
6344+
attribution_data,
63446345
});
63456346
return UpdateFulfillFetch::NewClaim {
63466347
monitor_update,
@@ -6371,7 +6372,7 @@ where
63716372
);
63726373
htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(
63736374
payment_preimage_arg.clone(),
6374-
None,
6375+
attribution_data,
63756376
));
63766377
}
63776378

@@ -6380,13 +6381,20 @@ where
63806381

63816382
pub fn get_update_fulfill_htlc_and_commit<L: Deref>(
63826383
&mut self, htlc_id: u64, payment_preimage: PaymentPreimage,
6383-
payment_info: Option<PaymentClaimDetails>, logger: &L,
6384+
payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
6385+
logger: &L,
63846386
) -> UpdateFulfillCommitFetch
63856387
where
63866388
L::Target: Logger,
63876389
{
63886390
let release_cs_monitor = self.context.blocked_monitor_updates.is_empty();
6389-
match self.get_update_fulfill_htlc(htlc_id, payment_preimage, payment_info, logger) {
6391+
match self.get_update_fulfill_htlc(
6392+
htlc_id,
6393+
payment_preimage,
6394+
payment_info,
6395+
attribution_data,
6396+
logger,
6397+
) {
63906398
UpdateFulfillFetch::NewClaim {
63916399
mut monitor_update,
63926400
htlc_value_msat,
@@ -6720,7 +6728,7 @@ where
67206728

67216729
pub fn update_fulfill_htlc(
67226730
&mut self, msg: &msgs::UpdateFulfillHTLC,
6723-
) -> Result<(HTLCSource, u64, Option<u64>), ChannelError> {
6731+
) -> Result<(HTLCSource, u64, Option<u64>, Option<Duration>), ChannelError> {
67246732
if self.context.channel_state.is_remote_stfu_sent()
67256733
|| self.context.channel_state.is_quiescent()
67266734
{
@@ -6741,9 +6749,11 @@ where
67416749

67426750
self.mark_outbound_htlc_removed(
67436751
msg.htlc_id,
6744-
OutboundHTLCOutcome::Success(msg.payment_preimage, None),
6752+
OutboundHTLCOutcome::Success(msg.payment_preimage, msg.attribution_data.clone()),
67456753
)
6746-
.map(|htlc| (htlc.source.clone(), htlc.amount_msat, htlc.skimmed_fee_msat))
6754+
.map(|htlc| {
6755+
(htlc.source.clone(), htlc.amount_msat, htlc.skimmed_fee_msat, htlc.send_timestamp)
6756+
})
67476757
}
67486758

67496759
#[rustfmt::skip]
@@ -7279,7 +7289,11 @@ where
72797289
}
72807290
None
72817291
},
7282-
&HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => {
7292+
&HTLCUpdateAwaitingACK::ClaimHTLC {
7293+
ref payment_preimage,
7294+
htlc_id,
7295+
ref attribution_data,
7296+
} => {
72837297
// If an HTLC claim was previously added to the holding cell (via
72847298
// `get_update_fulfill_htlc`, then generating the claim message itself must
72857299
// not fail - any in between attempts to claim the HTLC will have resulted
@@ -7292,8 +7306,13 @@ where
72927306
// We do not bother to track and include `payment_info` here, however.
72937307
let mut additional_monitor_update =
72947308
if let UpdateFulfillFetch::NewClaim { monitor_update, .. } = self
7295-
.get_update_fulfill_htlc(htlc_id, *payment_preimage, None, logger)
7296-
{
7309+
.get_update_fulfill_htlc(
7310+
htlc_id,
7311+
*payment_preimage,
7312+
None,
7313+
attribution_data.clone(),
7314+
logger,
7315+
) {
72977316
monitor_update
72987317
} else {
72997318
unreachable!()
@@ -7535,8 +7554,11 @@ where
75357554
});
75367555
revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
75377556
},
7538-
OutboundHTLCOutcome::Success(..) => {
7539-
finalized_claimed_htlcs.push(htlc.source.clone());
7557+
OutboundHTLCOutcome::Success(_, attribution_data) => {
7558+
// Even though a fast track was taken for fulfilled HTLCs to the incoming side, we still
7559+
// pass along attribution data here so that we can include hold time information in the
7560+
// final PaymentPathSuccessful events.
7561+
finalized_claimed_htlcs.push((htlc.source.clone(), attribution_data));
75407562
// They fulfilled, so we sent them money
75417563
value_to_self_msat_diff -= htlc.amount_msat as i64;
75427564
},
@@ -8029,7 +8051,7 @@ where
80298051
&mut self, resend_raa: bool, resend_commitment: bool, resend_channel_ready: bool,
80308052
mut pending_forwards: Vec<(PendingHTLCInfo, u64)>,
80318053
mut pending_fails: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
8032-
mut pending_finalized_claimed_htlcs: Vec<HTLCSource>,
8054+
mut pending_finalized_claimed_htlcs: Vec<(HTLCSource, Option<AttributionData>)>,
80338055
) {
80348056
self.context.monitor_pending_revoke_and_ack |= resend_raa;
80358057
self.context.monitor_pending_commitment_signed |= resend_commitment;
@@ -13593,7 +13615,7 @@ where
1359313615
}
1359413616
}
1359513617

13596-
fn duration_since_epoch() -> Option<Duration> {
13618+
pub(crate) fn duration_since_epoch() -> Option<Duration> {
1359713619
#[cfg(not(feature = "std"))]
1359813620
let now = None;
1359913621

@@ -13607,7 +13629,9 @@ fn duration_since_epoch() -> Option<Duration> {
1360713629
now
1360813630
}
1360913631

13610-
fn get_hold_time(send_timestamp: Option<Duration>, now: Option<Duration>) -> Option<u32> {
13632+
pub(crate) fn get_hold_time(
13633+
send_timestamp: Option<Duration>, now: Option<Duration>,
13634+
) -> Option<u32> {
1361113635
send_timestamp.and_then(|t| {
1361213636
now.map(|now| {
1361313637
let elapsed = now.saturating_sub(t).as_millis() / HOLD_TIME_UNIT_MILLIS;

0 commit comments

Comments
 (0)