Skip to content

Commit 00bc5bc

Browse files
committed
Add hold times to update_fulfill_htlc
1 parent d6c9a98 commit 00bc5bc

File tree

11 files changed

+340
-59
lines changed

11 files changed

+340
-59
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: 68 additions & 35 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

@@ -466,6 +466,7 @@ enum HTLCUpdateAwaitingACK {
466466
},
467467
ClaimHTLC {
468468
payment_preimage: PaymentPreimage,
469+
attribution_data: Option<AttributionData>,
469470
htlc_id: u64,
470471
},
471472
FailHTLC {
@@ -1180,7 +1181,7 @@ pub(super) struct MonitorRestoreUpdates {
11801181
pub order: RAACommitmentOrder,
11811182
pub accepted_htlcs: Vec<(PendingHTLCInfo, u64)>,
11821183
pub failed_htlcs: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
1183-
pub finalized_claimed_htlcs: Vec<HTLCSource>,
1184+
pub finalized_claimed_htlcs: Vec<(HTLCSource, Option<AttributionData>)>,
11841185
pub pending_update_adds: Vec<msgs::UpdateAddHTLC>,
11851186
pub funding_broadcastable: Option<Transaction>,
11861187
pub channel_ready: Option<msgs::ChannelReady>,
@@ -2312,7 +2313,7 @@ where
23122313
// but need to handle this somehow or we run the risk of losing HTLCs!
23132314
monitor_pending_forwards: Vec<(PendingHTLCInfo, u64)>,
23142315
monitor_pending_failures: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
2315-
monitor_pending_finalized_fulfills: Vec<HTLCSource>,
2316+
monitor_pending_finalized_fulfills: Vec<(HTLCSource, Option<AttributionData>)>,
23162317
monitor_pending_update_adds: Vec<msgs::UpdateAddHTLC>,
23172318
monitor_pending_tx_signatures: Option<msgs::TxSignatures>,
23182319

@@ -6214,7 +6215,7 @@ where
62146215
assert!(!self.context.channel_state.can_generate_new_commitment());
62156216
let mon_update_id = self.context.latest_monitor_update_id; // Forget the ChannelMonitor update
62166217
let fulfill_resp =
6217-
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);
62186219
self.context.latest_monitor_update_id = mon_update_id;
62196220
if let UpdateFulfillFetch::NewClaim { update_blocked, .. } = fulfill_resp {
62206221
assert!(update_blocked); // The HTLC must have ended up in the holding cell.
@@ -6223,7 +6224,8 @@ where
62236224

62246225
fn get_update_fulfill_htlc<L: Deref>(
62256226
&mut self, htlc_id_arg: u64, payment_preimage_arg: PaymentPreimage,
6226-
payment_info: Option<PaymentClaimDetails>, logger: &L,
6227+
payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
6228+
logger: &L,
62276229
) -> UpdateFulfillFetch
62286230
where
62296231
L::Target: Logger,
@@ -6339,6 +6341,7 @@ where
63396341
self.context.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::ClaimHTLC {
63406342
payment_preimage: payment_preimage_arg,
63416343
htlc_id: htlc_id_arg,
6344+
attribution_data,
63426345
});
63436346
return UpdateFulfillFetch::NewClaim {
63446347
monitor_update,
@@ -6369,7 +6372,7 @@ where
63696372
);
63706373
htlc.state = InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(
63716374
payment_preimage_arg.clone(),
6372-
None,
6375+
attribution_data,
63736376
));
63746377
}
63756378

@@ -6378,13 +6381,20 @@ where
63786381

63796382
pub fn get_update_fulfill_htlc_and_commit<L: Deref>(
63806383
&mut self, htlc_id: u64, payment_preimage: PaymentPreimage,
6381-
payment_info: Option<PaymentClaimDetails>, logger: &L,
6384+
payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
6385+
logger: &L,
63826386
) -> UpdateFulfillCommitFetch
63836387
where
63846388
L::Target: Logger,
63856389
{
63866390
let release_cs_monitor = self.context.blocked_monitor_updates.is_empty();
6387-
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+
) {
63886398
UpdateFulfillFetch::NewClaim {
63896399
mut monitor_update,
63906400
htlc_value_msat,
@@ -6718,7 +6728,7 @@ where
67186728

67196729
pub fn update_fulfill_htlc(
67206730
&mut self, msg: &msgs::UpdateFulfillHTLC,
6721-
) -> Result<(HTLCSource, u64, Option<u64>), ChannelError> {
6731+
) -> Result<(HTLCSource, u64, Option<u64>, Option<Duration>), ChannelError> {
67226732
if self.context.channel_state.is_remote_stfu_sent()
67236733
|| self.context.channel_state.is_quiescent()
67246734
{
@@ -6739,9 +6749,11 @@ where
67396749

67406750
self.mark_outbound_htlc_removed(
67416751
msg.htlc_id,
6742-
OutboundHTLCOutcome::Success(msg.payment_preimage, None),
6752+
OutboundHTLCOutcome::Success(msg.payment_preimage, msg.attribution_data.clone()),
67436753
)
6744-
.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+
})
67456757
}
67466758

67476759
#[rustfmt::skip]
@@ -7277,7 +7289,11 @@ where
72777289
}
72787290
None
72797291
},
7280-
&HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, htlc_id, .. } => {
7292+
&HTLCUpdateAwaitingACK::ClaimHTLC {
7293+
ref payment_preimage,
7294+
htlc_id,
7295+
ref attribution_data,
7296+
} => {
72817297
// If an HTLC claim was previously added to the holding cell (via
72827298
// `get_update_fulfill_htlc`, then generating the claim message itself must
72837299
// not fail - any in between attempts to claim the HTLC will have resulted
@@ -7290,8 +7306,13 @@ where
72907306
// We do not bother to track and include `payment_info` here, however.
72917307
let mut additional_monitor_update =
72927308
if let UpdateFulfillFetch::NewClaim { monitor_update, .. } = self
7293-
.get_update_fulfill_htlc(htlc_id, *payment_preimage, None, logger)
7294-
{
7309+
.get_update_fulfill_htlc(
7310+
htlc_id,
7311+
*payment_preimage,
7312+
None,
7313+
attribution_data.clone(),
7314+
logger,
7315+
) {
72957316
monitor_update
72967317
} else {
72977318
unreachable!()
@@ -7533,8 +7554,11 @@ where
75337554
});
75347555
revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
75357556
},
7536-
OutboundHTLCOutcome::Success(..) => {
7537-
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));
75387562
// They fulfilled, so we sent them money
75397563
value_to_self_msat_diff -= htlc.amount_msat as i64;
75407564
},
@@ -8027,7 +8051,7 @@ where
80278051
&mut self, resend_raa: bool, resend_commitment: bool, resend_channel_ready: bool,
80288052
mut pending_forwards: Vec<(PendingHTLCInfo, u64)>,
80298053
mut pending_fails: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
8030-
mut pending_finalized_claimed_htlcs: Vec<HTLCSource>,
8054+
mut pending_finalized_claimed_htlcs: Vec<(HTLCSource, Option<AttributionData>)>,
80318055
) {
80328056
self.context.monitor_pending_revoke_and_ack |= resend_raa;
80338057
self.context.monitor_pending_commitment_signed |= resend_commitment;
@@ -12560,7 +12584,7 @@ where
1256012584
Vec::with_capacity(holding_cell_htlc_update_count);
1256112585
let mut holding_cell_blinding_points: Vec<Option<PublicKey>> =
1256212586
Vec::with_capacity(holding_cell_htlc_update_count);
12563-
let mut holding_cell_failure_attribution_data: Vec<Option<&AttributionData>> =
12587+
let mut holding_cell_attribution_data: Vec<Option<&AttributionData>> =
1256412588
Vec::with_capacity(holding_cell_htlc_update_count);
1256512589
// Vec of (htlc_id, failure_code, sha256_of_onion)
1256612590
let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
@@ -12586,19 +12610,25 @@ where
1258612610
holding_cell_skimmed_fees.push(skimmed_fee_msat);
1258712611
holding_cell_blinding_points.push(blinding_point);
1258812612
},
12589-
&HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, ref htlc_id } => {
12613+
&HTLCUpdateAwaitingACK::ClaimHTLC {
12614+
ref payment_preimage,
12615+
ref htlc_id,
12616+
ref attribution_data,
12617+
} => {
1259012618
1u8.write(writer)?;
1259112619
payment_preimage.write(writer)?;
1259212620
htlc_id.write(writer)?;
12621+
12622+
// Store the attribution data for later writing.
12623+
holding_cell_attribution_data.push(attribution_data.as_ref());
1259312624
},
1259412625
&HTLCUpdateAwaitingACK::FailHTLC { ref htlc_id, ref err_packet } => {
1259512626
2u8.write(writer)?;
1259612627
htlc_id.write(writer)?;
1259712628
err_packet.data.write(writer)?;
1259812629

1259912630
// Store the attribution data for later writing.
12600-
holding_cell_failure_attribution_data
12601-
.push(err_packet.attribution_data.as_ref());
12631+
holding_cell_attribution_data.push(err_packet.attribution_data.as_ref());
1260212632
},
1260312633
&HTLCUpdateAwaitingACK::FailMalformedHTLC {
1260412634
htlc_id,
@@ -12615,7 +12645,7 @@ where
1261512645

1261612646
// Push 'None' attribution data for FailMalformedHTLC, because FailMalformedHTLC uses the same
1261712647
// type 2 and is deserialized as a FailHTLC.
12618-
holding_cell_failure_attribution_data.push(None);
12648+
holding_cell_attribution_data.push(None);
1261912649
},
1262012650
}
1262112651
}
@@ -12819,7 +12849,7 @@ where
1281912849
(53, funding_tx_broadcast_safe_event_emitted, option), // Added in 0.0.124
1282012850
(54, self.pending_funding, optional_vec), // Added in 0.2
1282112851
(55, removed_htlc_attribution_data, optional_vec), // Added in 0.2
12822-
(57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
12852+
(57, holding_cell_attribution_data, optional_vec), // Added in 0.2
1282312853
(58, self.interactive_tx_signing_session, option), // Added in 0.2
1282412854
(59, self.funding.minimum_depth_override, option), // Added in 0.2
1282512855
(60, self.context.historical_scids, optional_vec), // Added in 0.2
@@ -12993,6 +13023,7 @@ where
1299313023
1 => HTLCUpdateAwaitingACK::ClaimHTLC {
1299413024
payment_preimage: Readable::read(reader)?,
1299513025
htlc_id: Readable::read(reader)?,
13026+
attribution_data: None,
1299613027
},
1299713028
2 => HTLCUpdateAwaitingACK::FailHTLC {
1299813029
htlc_id: Readable::read(reader)?,
@@ -13165,7 +13196,7 @@ where
1316513196
let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
1316613197

1316713198
let mut removed_htlc_attribution_data: Option<Vec<Option<AttributionData>>> = None;
13168-
let mut holding_cell_failure_attribution_data: Option<Vec<Option<AttributionData>>> = None;
13199+
let mut holding_cell_attribution_data: Option<Vec<Option<AttributionData>>> = None;
1316913200

1317013201
let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
1317113202
let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
@@ -13218,7 +13249,7 @@ where
1321813249
(53, funding_tx_broadcast_safe_event_emitted, option),
1321913250
(54, pending_funding, optional_vec), // Added in 0.2
1322013251
(55, removed_htlc_attribution_data, optional_vec),
13221-
(57, holding_cell_failure_attribution_data, optional_vec),
13252+
(57, holding_cell_attribution_data, optional_vec),
1322213253
(58, interactive_tx_signing_session, option), // Added in 0.2
1322313254
(59, minimum_depth_override, option), // Added in 0.2
1322413255
(60, historical_scids, optional_vec), // Added in 0.2
@@ -13350,18 +13381,17 @@ where
1335013381
}
1335113382
}
1335213383

13353-
if let Some(attribution_data_list) = holding_cell_failure_attribution_data {
13384+
if let Some(attribution_data_list) = holding_cell_attribution_data {
1335413385
let mut holding_cell_failures =
13355-
holding_cell_htlc_updates.iter_mut().filter_map(|upd| {
13356-
if let HTLCUpdateAwaitingACK::FailHTLC {
13386+
holding_cell_htlc_updates.iter_mut().filter_map(|upd| match upd {
13387+
HTLCUpdateAwaitingACK::FailHTLC {
1335713388
err_packet: OnionErrorPacket { ref mut attribution_data, .. },
1335813389
..
13359-
} = upd
13360-
{
13390+
} => Some(attribution_data),
13391+
HTLCUpdateAwaitingACK::ClaimHTLC { attribution_data, .. } => {
1336113392
Some(attribution_data)
13362-
} else {
13363-
None
13364-
}
13393+
},
13394+
_ => None,
1336513395
});
1336613396

1336713397
for attribution_data in attribution_data_list {
@@ -13578,7 +13608,7 @@ where
1357813608
}
1357913609
}
1358013610

13581-
fn duration_since_epoch() -> Option<Duration> {
13611+
pub(crate) fn duration_since_epoch() -> Option<Duration> {
1358213612
#[cfg(not(feature = "std"))]
1358313613
let now = None;
1358413614

@@ -13592,7 +13622,9 @@ fn duration_since_epoch() -> Option<Duration> {
1359213622
now
1359313623
}
1359413624

13595-
fn get_hold_time(send_timestamp: Option<Duration>, now: Option<Duration>) -> Option<u32> {
13625+
pub(crate) fn get_hold_time(
13626+
send_timestamp: Option<Duration>, now: Option<Duration>,
13627+
) -> Option<u32> {
1359613628
send_timestamp.and_then(|t| {
1359713629
now.map(|now| {
1359813630
let elapsed = now.saturating_sub(t).as_millis() / HOLD_TIME_UNIT_MILLIS;
@@ -14359,6 +14391,7 @@ mod tests {
1435914391
let dummy_holding_cell_claim_htlc = HTLCUpdateAwaitingACK::ClaimHTLC {
1436014392
payment_preimage: PaymentPreimage([42; 32]),
1436114393
htlc_id: 0,
14394+
attribution_data: None,
1436214395
};
1436314396
let dummy_holding_cell_failed_htlc = |htlc_id| HTLCUpdateAwaitingACK::FailHTLC {
1436414397
htlc_id,

0 commit comments

Comments
 (0)