Skip to content

Commit 77e5ff7

Browse files
committed
Add AttributionData to OutboundHTLCOutcome::Success
AttributionData is needed as part of the outbound HTLC outcome when revoke_and_ack has happened and the AttributionData is decoded to get the hold times for inclusion in the PaymentPathSuccessful event.
1 parent 39a53a8 commit 77e5ff7

File tree

1 file changed

+48
-32
lines changed

1 file changed

+48
-32
lines changed

lightning/src/ln/channel.rs

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,11 @@ impl From<&OutboundHTLCState> for OutboundHTLCStateDetails {
348348
// the state yet.
349349
OutboundHTLCState::RemoteRemoved(_) =>
350350
OutboundHTLCStateDetails::Committed,
351-
OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) =>
351+
OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_, _)) =>
352352
OutboundHTLCStateDetails::AwaitingRemoteRevokeToRemoveSuccess,
353353
OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Failure(_)) =>
354354
OutboundHTLCStateDetails::AwaitingRemoteRevokeToRemoveFailure,
355-
OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) =>
355+
OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_, _)) =>
356356
OutboundHTLCStateDetails::AwaitingRemoteRevokeToRemoveSuccess,
357357
OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Failure(_)) =>
358358
OutboundHTLCStateDetails::AwaitingRemoteRevokeToRemoveFailure,
@@ -387,9 +387,9 @@ impl OutboundHTLCState {
387387
#[rustfmt::skip]
388388
fn preimage(&self) -> Option<PaymentPreimage> {
389389
match self {
390-
OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(preimage))
391-
| OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(preimage))
392-
| OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(preimage)) => {
390+
OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(preimage, _))
391+
| OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(preimage, _))
392+
| OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(preimage, _)) => {
393393
Some(*preimage)
394394
},
395395
_ => None,
@@ -402,14 +402,14 @@ 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),
405+
Success(PaymentPreimage, #[allow(dead_code)] Option<AttributionData>),
406406
Failure(HTLCFailReason),
407407
}
408408

409409
impl<'a> Into<Option<&'a HTLCFailReason>> for &'a OutboundHTLCOutcome {
410410
fn into(self) -> Option<&'a HTLCFailReason> {
411411
match self {
412-
OutboundHTLCOutcome::Success(_) => None,
412+
OutboundHTLCOutcome::Success(_, _) => None,
413413
OutboundHTLCOutcome::Failure(ref r) => Some(r),
414414
}
415415
}
@@ -4159,9 +4159,9 @@ where
41594159
// transaction).
41604160
let mut removed_outbound_total_msat = 0;
41614161
for ref htlc in self.pending_outbound_htlcs.iter() {
4162-
if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) = htlc.state {
4162+
if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_, _)) = htlc.state {
41634163
removed_outbound_total_msat += htlc.amount_msat;
4164-
} else if let OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) = htlc.state {
4164+
} else if let OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_, _)) = htlc.state {
41654165
removed_outbound_total_msat += htlc.amount_msat;
41664166
}
41674167
}
@@ -4424,9 +4424,9 @@ where
44244424

44254425
let mut removed_outbound_total_msat = 0;
44264426
for ref htlc in self.pending_outbound_htlcs.iter() {
4427-
if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) = htlc.state {
4427+
if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_, _)) = htlc.state {
44284428
removed_outbound_total_msat += htlc.amount_msat;
4429-
} else if let OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) = htlc.state {
4429+
} else if let OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_, _)) = htlc.state {
44304430
removed_outbound_total_msat += htlc.amount_msat;
44314431
}
44324432
}
@@ -6694,7 +6694,7 @@ where
66946694
fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, outcome: OutboundHTLCOutcome) -> Result<&OutboundHTLCOutput, ChannelError> {
66956695
for htlc in self.context.pending_outbound_htlcs.iter_mut() {
66966696
if htlc.htlc_id == htlc_id {
6697-
if let OutboundHTLCOutcome::Success(ref payment_preimage) = outcome {
6697+
if let OutboundHTLCOutcome::Success(ref payment_preimage, ..) = outcome {
66986698
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array());
66996699
if payment_hash != htlc.payment_hash {
67006700
return Err(ChannelError::close(format!("Remote tried to fulfill HTLC ({}) with an incorrect preimage", htlc_id)));
@@ -6738,7 +6738,7 @@ where
67386738

67396739
self.mark_outbound_htlc_removed(
67406740
msg.htlc_id,
6741-
OutboundHTLCOutcome::Success(msg.payment_preimage),
6741+
OutboundHTLCOutcome::Success(msg.payment_preimage, None),
67426742
)
67436743
.map(|htlc| (htlc.source.clone(), htlc.amount_msat, htlc.skimmed_fee_msat))
67446744
}
@@ -7078,9 +7078,9 @@ where
70787078
log_trace!(logger, "Updating HTLC {} to AwaitingRemoteRevokeToRemove due to commitment_signed in channel {}.",
70797079
&htlc.payment_hash, &self.context.channel_id);
70807080
// Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
7081-
let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]));
7081+
let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]), None);
70827082
mem::swap(outcome, &mut reason);
7083-
if let OutboundHTLCOutcome::Success(preimage) = reason {
7083+
if let OutboundHTLCOutcome::Success(preimage, _) = reason {
70847084
// If a user (a) receives an HTLC claim using LDK 0.0.104 or before, then (b)
70857085
// upgrades to LDK 0.0.114 or later before the HTLC is fully resolved, we could
70867086
// have a `Success(None)` reason. In this case we could forget some HTLC
@@ -7525,16 +7525,18 @@ where
75257525
&htlc.payment_hash
75267526
);
75277527
// We really want take() here, but, again, non-mut ref :(
7528-
if let OutboundHTLCOutcome::Failure(mut reason) = outcome.clone() {
7529-
get_hold_time(htlc.send_timestamp, now).map(|hold_time| {
7530-
reason.set_hold_time(hold_time);
7531-
});
7532-
7533-
revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
7534-
} else {
7535-
finalized_claimed_htlcs.push(htlc.source.clone());
7536-
// They fulfilled, so we sent them money
7537-
value_to_self_msat_diff -= htlc.amount_msat as i64;
7528+
match outcome.clone() {
7529+
OutboundHTLCOutcome::Failure(mut reason) => {
7530+
get_hold_time(htlc.send_timestamp, now).map(|hold_time| {
7531+
reason.set_hold_time(hold_time);
7532+
});
7533+
revoked_htlcs.push((htlc.source.clone(), htlc.payment_hash, reason));
7534+
},
7535+
OutboundHTLCOutcome::Success(..) => {
7536+
finalized_claimed_htlcs.push(htlc.source.clone());
7537+
// They fulfilled, so we sent them money
7538+
value_to_self_msat_diff -= htlc.amount_msat as i64;
7539+
},
75387540
}
75397541
false
75407542
} else {
@@ -7618,7 +7620,7 @@ where
76187620
{
76197621
log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", &htlc.payment_hash);
76207622
// Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
7621-
let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]));
7623+
let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]), None);
76227624
mem::swap(outcome, &mut reason);
76237625
htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(reason);
76247626
require_commitment = true;
@@ -10748,7 +10750,7 @@ where
1074810750
if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut outcome) = &mut htlc.state {
1074910751
log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", &htlc.payment_hash);
1075010752
// Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
10751-
let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]));
10753+
let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]), None);
1075210754
mem::swap(outcome, &mut reason);
1075310755
htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(reason);
1075410756
}
@@ -12504,6 +12506,7 @@ where
1250412506
// The elements of this vector will always be `Some` starting in 0.2,
1250512507
// but we still serialize the option to maintain backwards compatibility
1250612508
let mut preimages: Vec<Option<&PaymentPreimage>> = vec![];
12509+
let mut success_attribution_data = vec![];
1250712510
let mut pending_outbound_skimmed_fees: Vec<Option<u64>> = Vec::new();
1250812511
let mut pending_outbound_blinding_points: Vec<Option<PublicKey>> = Vec::new();
1250912512

@@ -12529,16 +12532,18 @@ where
1252912532
},
1253012533
&OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref outcome) => {
1253112534
3u8.write(writer)?;
12532-
if let OutboundHTLCOutcome::Success(preimage) = outcome {
12535+
if let OutboundHTLCOutcome::Success(preimage, attribution_data) = outcome {
1253312536
preimages.push(Some(preimage));
12537+
success_attribution_data.push(attribution_data);
1253412538
}
1253512539
let reason: Option<&HTLCFailReason> = outcome.into();
1253612540
reason.write(writer)?;
1253712541
},
1253812542
&OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) => {
1253912543
4u8.write(writer)?;
12540-
if let OutboundHTLCOutcome::Success(preimage) = outcome {
12544+
if let OutboundHTLCOutcome::Success(preimage, attribution_data) = outcome {
1254112545
preimages.push(Some(preimage));
12546+
success_attribution_data.push(attribution_data);
1254212547
}
1254312548
let reason: Option<&HTLCFailReason> = outcome.into();
1254412549
reason.write(writer)?;
@@ -12816,6 +12821,7 @@ where
1281612821
(58, self.interactive_tx_signing_session, option), // Added in 0.2
1281712822
(59, self.funding.minimum_depth_override, option), // Added in 0.2
1281812823
(60, self.context.historical_scids, optional_vec), // Added in 0.2
12824+
(61, success_attribution_data, optional_vec),
1281912825
});
1282012826

1282112827
Ok(())
@@ -12937,7 +12943,7 @@ where
1293712943
let outcome = match option {
1293812944
Some(r) => OutboundHTLCOutcome::Failure(r),
1293912945
// Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
12940-
None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
12946+
None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]), None),
1294112947
};
1294212948
OutboundHTLCState::RemoteRemoved(outcome)
1294312949
},
@@ -12946,7 +12952,7 @@ where
1294612952
let outcome = match option {
1294712953
Some(r) => OutboundHTLCOutcome::Failure(r),
1294812954
// Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
12949-
None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
12955+
None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]), None),
1295012956
};
1295112957
OutboundHTLCState::AwaitingRemoteRevokeToRemove(outcome)
1295212958
},
@@ -12955,7 +12961,7 @@ where
1295512961
let outcome = match option {
1295612962
Some(r) => OutboundHTLCOutcome::Failure(r),
1295712963
// Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
12958-
None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
12964+
None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]), None),
1295912965
};
1296012966
OutboundHTLCState::AwaitingRemovedRemoteRevoke(outcome)
1296112967
},
@@ -13130,6 +13136,7 @@ where
1313013136
// Starting in 0.2, all the elements in this vector will be `Some`, but they are still
1313113137
// serialized as options to maintain backwards compatibility
1313213138
let mut preimages: Vec<Option<PaymentPreimage>> = Vec::new();
13139+
let mut success_attribution_data: Option<Vec<Option<AttributionData>>> = None;
1313313140

1313413141
// If we read an old Channel, for simplicity we just treat it as "we never sent an
1313513142
// AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
@@ -13215,23 +13222,32 @@ where
1321513222
(58, interactive_tx_signing_session, option), // Added in 0.2
1321613223
(59, minimum_depth_override, option), // Added in 0.2
1321713224
(60, historical_scids, optional_vec), // Added in 0.2
13225+
(61, success_attribution_data, optional_vec),
1321813226
});
1321913227

1322013228
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
1322113229

1322213230
let mut iter = preimages.into_iter();
13231+
let mut success_attribution_data_iter = success_attribution_data.map(Vec::into_iter);
1322313232
for htlc in pending_outbound_htlcs.iter_mut() {
1322413233
match &mut htlc.state {
1322513234
OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(
1322613235
ref mut preimage,
13236+
ref mut attribution_data,
1322713237
))
1322813238
| OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(
1322913239
ref mut preimage,
13240+
ref mut attribution_data,
1323013241
)) => {
1323113242
// This variant was initialized like this further above
1323213243
debug_assert_eq!(preimage, &PaymentPreimage([0u8; 32]));
1323313244
// Flatten and unwrap the preimage; they are always set starting in 0.2.
1323413245
*preimage = iter.next().flatten().ok_or(DecodeError::InvalidValue)?;
13246+
13247+
*attribution_data = success_attribution_data_iter
13248+
.as_mut()
13249+
.and_then(Iterator::next)
13250+
.ok_or(DecodeError::InvalidValue)?;
1323513251
},
1323613252
_ => {},
1323713253
}

0 commit comments

Comments
 (0)