ln/refactor: move MPP information into separate struct to ClaimableHTLC
What changed, and why it matters
This commit is a straightforward internal code reorganization in the Lightning Dev Kit's channel manager. It groups fields that describe individual parts of a multi-path payment (MPP) into a new struct called MppPart, which is then embedded inside the existing ClaimableHTLC struct. The change does not alter behavior, fix a bug, or introduce a security boundary; it only moves data around to make future trampoline-forwarding work easier.
No security action required. Treat as normal code-review/merge for maintainability.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors ClaimableHTLC in lightning/src/ln/channelmanager.rs by extracting prev_hop, cltv_expiry, value, sender_intended_value, timer_ticks, and total_value_received into a new MppPart struct. ClaimableHTLC now contains an mpp_part: MppPart plus onion_payload and counterparty_skimmed_fee_msat. All usages are updated to access fields through mpp_part, and the Ord/PartialOrd implementation is delegated. Serialization/deserialization is adjusted to read/write the same TLV fields into the nested struct. No logic, validation, or cryptographic behavior is changed.
Changed components
lightning/src/ln/channelmanager.rsClaimableHTLC structnew MppPart structMPP payment accumulation logicClaimableHTLC serialization/deserializationInspect captured patch +125 / −91
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index 9b627d4..dd91f3c 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -520,9 +520,8 @@ enum OnionPayload {
Spontaneous(PaymentPreimage),
}
-/// HTLCs that are to us and can be failed/claimed by the user
#[derive(PartialEq, Eq)]
-struct ClaimableHTLC {
+struct MppPart {
prev_hop: HTLCPreviousHopData,
cltv_expiry: u32,
/// The amount (in msats) of this MPP part
@@ -530,11 +529,34 @@ struct ClaimableHTLC {
/// The amount (in msats) that the sender intended to be sent in this MPP
/// part (used for validating total MPP amount)
sender_intended_value: u64,
- onion_payload: OnionPayload,
timer_ticks: u8,
/// The total value received for a payment (sum of all MPP parts if the payment is a MPP).
/// Gets set to the amount reported when pushing [`Event::PaymentClaimable`].
total_value_received: Option<u64>,
+}
+
+impl PartialOrd for MppPart {
+ fn partial_cmp(&self, other: &MppPart) -> Option<cmp::Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for MppPart {
+ fn cmp(&self, other: &MppPart) -> cmp::Ordering {
+ let res = (self.prev_hop.channel_id, self.prev_hop.htlc_id)
+ .cmp(&(other.prev_hop.channel_id, other.prev_hop.htlc_id));
+ if res.is_eq() {
+ debug_assert!(self == other, "MppParts from the same source should be identical");
+ }
+ res
+ }
+}
+
+/// Represents an incoming HTLC that can be claimed or failed by the user.
+#[derive(PartialEq, Eq)]
+struct ClaimableHTLC {
+ mpp_part: MppPart,
+ onion_payload: OnionPayload,
/// The extra fee our counterparty skimmed off the top of this HTLC.
counterparty_skimmed_fee_msat: Option<u64>,
}
@@ -542,11 +564,11 @@ struct ClaimableHTLC {
impl From<&ClaimableHTLC> for events::ClaimedHTLC {
fn from(val: &ClaimableHTLC) -> Self {
events::ClaimedHTLC {
- counterparty_node_id: val.prev_hop.counterparty_node_id,
- channel_id: val.prev_hop.channel_id,
- user_channel_id: val.prev_hop.user_channel_id.unwrap_or(0),
- cltv_expiry: val.cltv_expiry,
- value_msat: val.value,
+ counterparty_node_id: val.mpp_part.prev_hop.counterparty_node_id,
+ channel_id: val.mpp_part.prev_hop.channel_id,
+ user_channel_id: val.mpp_part.prev_hop.user_channel_id.unwrap_or(0),
+ cltv_expiry: val.mpp_part.cltv_expiry,
+ value_msat: val.mpp_part.value,
counterparty_skimmed_fee_msat: val.counterparty_skimmed_fee_msat.unwrap_or(0),
}
}
@@ -559,12 +581,7 @@ impl PartialOrd for ClaimableHTLC {
}
impl Ord for ClaimableHTLC {
fn cmp(&self, other: &ClaimableHTLC) -> cmp::Ordering {
- let res = (self.prev_hop.channel_id, self.prev_hop.htlc_id)
- .cmp(&(other.prev_hop.channel_id, other.prev_hop.htlc_id));
- if res.is_eq() {
- debug_assert!(self == other, "ClaimableHTLCs from the same source should be identical");
- }
- res
+ self.mpp_part.cmp(&other.mpp_part)
}
}
@@ -1216,7 +1233,9 @@ impl ClaimablePayment {
fn inbound_payment_id(&self, secret: &[u8; 32]) -> PaymentId {
PaymentId::for_inbound_from_htlcs(
secret,
- self.htlcs.iter().map(|htlc| (htlc.prev_hop.channel_id, htlc.prev_hop.htlc_id)),
+ self.htlcs
+ .iter()
+ .map(|htlc| (htlc.mpp_part.prev_hop.channel_id, htlc.mpp_part.prev_hop.htlc_id)),
)
}
@@ -1226,7 +1245,7 @@ impl ClaimablePayment {
fn receiving_channel_ids(&self) -> Vec<(ChannelId, Option<u128>)> {
self.htlcs
.iter()
- .map(|htlc| (htlc.prev_hop.channel_id, htlc.prev_hop.user_channel_id))
+ .map(|htlc| (htlc.mpp_part.prev_hop.channel_id, htlc.mpp_part.prev_hop.user_channel_id))
.collect()
}
}
@@ -1323,7 +1342,7 @@ impl ClaimablePayments {
let mut receiver_node_id = node_signer.get_node_id(Recipient::Node)
.expect("Failed to get node_id for node recipient");
for htlc in payment.htlcs.iter() {
- if htlc.prev_hop.phantom_shared_secret.is_some() {
+ if htlc.mpp_part.prev_hop.phantom_shared_secret.is_some() {
let phantom_pubkey = node_signer.get_node_id(Recipient::PhantomNode)
.expect("Failed to get node_id for phantom node recipient");
receiver_node_id = phantom_pubkey;
@@ -1352,15 +1371,15 @@ impl ClaimablePayments {
// Pick an "arbitrary" channel to block RAAs on until the `PaymentSent`
// event is processed, specifically the last channel to get claimed.
let durable_preimage_channel = payment.htlcs.last().map_or(None, |htlc| {
- if let Some(node_id) = htlc.prev_hop.counterparty_node_id {
- Some((htlc.prev_hop.outpoint, node_id, htlc.prev_hop.channel_id))
+ if let Some(node_id) = htlc.mpp_part.prev_hop.counterparty_node_id {
+ Some((htlc.mpp_part.prev_hop.outpoint, node_id, htlc.mpp_part.prev_hop.channel_id))
} else {
None
}
});
debug_assert!(durable_preimage_channel.is_some());
ClaimingPayment {
- amount_msat: payment.htlcs.iter().map(|source| source.value).sum(),
+ amount_msat: payment.htlcs.iter().map(|source| source.mpp_part.value).sum(),
payment_purpose: payment.purpose,
receiver_node_id,
htlcs,
@@ -8315,15 +8334,17 @@ impl<
},
};
let claimable_htlc = ClaimableHTLC {
- prev_hop,
- // We differentiate the received value from the sender intended value
- // if possible so that we don't prematurely mark MPP payments complete
- // if routing nodes overpay
- value: incoming_amt_msat.unwrap_or(outgoing_amt_msat),
- sender_intended_value: outgoing_amt_msat,
- timer_ticks: 0,
- total_value_received: None,
- cltv_expiry,
+ mpp_part: MppPart {
+ prev_hop,
+ cltv_expiry,
+ // We differentiate the received value from the sender intended value
+ // if possible so that we don't prematurely mark MPP payments complete
+ // if routing nodes overpay
+ value: incoming_amt_msat.unwrap_or(outgoing_amt_msat),
+ sender_intended_value: outgoing_amt_msat,
+ timer_ticks: 0,
+ total_value_received: None,
+ },
onion_payload,
counterparty_skimmed_fee_msat: skimmed_fee_msat,
};
@@ -8334,21 +8355,22 @@ impl<
($htlc: expr, $payment_hash: expr) => {
debug_assert!(!committed_to_claimable);
let err_data = invalid_payment_err_data(
- $htlc.value,
+ $htlc.mpp_part.value,
self.best_block.read().unwrap().height,
);
- let counterparty_node_id = $htlc.prev_hop.counterparty_node_id;
+ let counterparty_node_id = $htlc.mpp_part.prev_hop.counterparty_node_id;
let incoming_packet_shared_secret =
- $htlc.prev_hop.incoming_packet_shared_secret;
- let prev_outbound_scid_alias = $htlc.prev_hop.prev_outbound_scid_alias;
+ $htlc.mpp_part.prev_hop.incoming_packet_shared_secret;
+ let prev_outbound_scid_alias =
+ $htlc.mpp_part.prev_hop.prev_outbound_scid_alias;
failed_forwards.push((
HTLCSource::PreviousHopData(HTLCPreviousHopData {
prev_outbound_scid_alias,
- user_channel_id: $htlc.prev_hop.user_channel_id,
+ user_channel_id: $htlc.mpp_part.prev_hop.user_channel_id,
counterparty_node_id,
channel_id: prev_channel_id,
outpoint: prev_funding_outpoint,
- htlc_id: $htlc.prev_hop.htlc_id,
+ htlc_id: $htlc.mpp_part.prev_hop.htlc_id,
incoming_packet_shared_secret,
phantom_shared_secret,
trampoline_shared_secret,
@@ -8365,7 +8387,8 @@ impl<
continue 'next_forwardable_htlc;
};
}
- let phantom_shared_secret = claimable_htlc.prev_hop.phantom_shared_secret;
+ let phantom_shared_secret =
+ claimable_htlc.mpp_part.prev_hop.phantom_shared_secret;
let mut receiver_node_id = self.our_network_pubkey;
if phantom_shared_secret.is_some() {
receiver_node_id = self
@@ -8404,11 +8427,11 @@ impl<
fail_htlc!(claimable_htlc, payment_hash);
}
let mut total_intended_recvd_value =
- claimable_htlc.sender_intended_value;
- let mut earliest_expiry = claimable_htlc.cltv_expiry;
+ claimable_htlc.mpp_part.sender_intended_value;
+ let mut earliest_expiry = claimable_htlc.mpp_part.cltv_expiry;
for htlc in claimable_payment.htlcs.iter() {
- total_intended_recvd_value += htlc.sender_intended_value;
- earliest_expiry = cmp::min(earliest_expiry, htlc.cltv_expiry);
+ total_intended_recvd_value += htlc.mpp_part.sender_intended_value;
+ earliest_expiry = cmp::min(earliest_expiry, htlc.mpp_part.cltv_expiry);
if total_intended_recvd_value >= msgs::MAX_VALUE_MSAT { break; }
}
let total_mpp_value =
@@ -8417,7 +8440,7 @@ impl<
// match exactly the condition used in `timer_tick_occurred`
if total_intended_recvd_value >= msgs::MAX_VALUE_MSAT {
fail_htlc!(claimable_htlc, payment_hash);
- } else if total_intended_recvd_value - claimable_htlc.sender_intended_value >= total_mpp_value {
+ } else if total_intended_recvd_value - claimable_htlc.mpp_part.sender_intended_value >= total_mpp_value {
log_trace!(self.logger, "Failing HTLC with payment_hash {} as payment is already claimable",
&payment_hash);
fail_htlc!(claimable_htlc, payment_hash);
@@ -8427,9 +8450,9 @@ impl<
}
claimable_payment.htlcs.push(claimable_htlc);
let amount_msat =
- claimable_payment.htlcs.iter().map(|htlc| htlc.value).sum();
+ claimable_payment.htlcs.iter().map(|htlc| htlc.mpp_part.value).sum();
claimable_payment.htlcs.iter_mut()
- .for_each(|htlc| htlc.total_value_received = Some(amount_msat));
+ .for_each(|htlc| htlc.mpp_part.total_value_received = Some(amount_msat));
let counterparty_skimmed_fee_msat = claimable_payment.htlcs.iter()
.map(|htlc| htlc.counterparty_skimmed_fee_msat.unwrap_or(0)).sum();
debug_assert!(total_intended_recvd_value.saturating_sub(amount_msat)
@@ -8894,18 +8917,18 @@ impl<
// This condition determining whether the MPP is complete here must match
// exactly the condition used in `process_pending_htlc_forwards`.
let total_intended_recvd_value =
- payment.htlcs.iter().map(|h| h.sender_intended_value).sum();
+ payment.htlcs.iter().map(|h| h.mpp_part.sender_intended_value).sum();
let total_mpp_value = payment.onion_fields.total_mpp_amount_msat;
if total_mpp_value <= total_intended_recvd_value {
return true;
} else if payment.htlcs.iter_mut().any(|htlc| {
- htlc.timer_ticks += 1;
- return htlc.timer_ticks >= MPP_TIMEOUT_TICKS;
+ htlc.mpp_part.timer_ticks += 1;
+ return htlc.mpp_part.timer_ticks >= MPP_TIMEOUT_TICKS;
}) {
let htlcs = payment
.htlcs
.drain(..)
- .map(|htlc: ClaimableHTLC| (htlc.prev_hop, *payment_hash));
+ .map(|htlc: ClaimableHTLC| (htlc.mpp_part.prev_hop, *payment_hash));
timed_out_mpp_htlcs.extend(htlcs);
return false;
}
@@ -8993,7 +9016,7 @@ impl<
if let Some(payment) = removed_source {
for htlc in payment.htlcs {
let reason = self.get_htlc_fail_reason_from_failure_code(failure_code, &htlc);
- let source = HTLCSource::PreviousHopData(htlc.prev_hop);
+ let source = HTLCSource::PreviousHopData(htlc.mpp_part.prev_hop);
let receiver = HTLCHandlingFailureType::Receive { payment_hash: *payment_hash };
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver, None);
}
@@ -9012,7 +9035,7 @@ impl<
HTLCFailReason::from_failure_code(failure_code.into())
},
FailureCode::IncorrectOrUnknownPaymentDetails => {
- let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
+ let mut htlc_msat_height_data = htlc.mpp_part.value.to_be_bytes().to_vec();
htlc_msat_height_data
.extend_from_slice(&self.best_block.read().unwrap().height.to_be_bytes());
HTLCFailReason::reason(failure_code.into(), htlc_msat_height_data)
@@ -9347,7 +9370,7 @@ impl<
FailureCode::InvalidOnionPayload(None),
&htlc,
);
- let source = HTLCSource::PreviousHopData(htlc.prev_hop);
+ let source = HTLCSource::PreviousHopData(htlc.mpp_part.prev_hop);
let receiver = HTLCHandlingFailureType::Receive { payment_hash };
self.fail_htlc_backwards_internal(
&source,
@@ -9373,14 +9396,16 @@ impl<
let mut errs = Vec::new();
let per_peer_state = self.per_peer_state.read().unwrap();
for htlc in sources.iter() {
- if expected_amt_msat.is_some() && expected_amt_msat != htlc.total_value_received {
+ if expected_amt_msat.is_some()
+ && expected_amt_msat != htlc.mpp_part.total_value_received
+ {
log_error!(self.logger, "Somehow ended up with an MPP payment with different received total amounts - this should not be reachable!");
debug_assert!(false);
valid_mpp = false;
break;
}
- expected_amt_msat = htlc.total_value_received;
- claimable_amt_msat += htlc.value;
+ expected_amt_msat = htlc.mpp_part.total_value_received;
+ claimable_amt_msat += htlc.mpp_part.value;
}
mem::drop(per_peer_state);
if sources.is_empty() || expected_amt_msat.is_none() {
@@ -9401,12 +9426,12 @@ impl<
let mpp_parts: Vec<_> = sources
.iter()
.filter_map(|htlc| {
- if let Some(cp_id) = htlc.prev_hop.counterparty_node_id {
+ if let Some(cp_id) = htlc.mpp_part.prev_hop.counterparty_node_id {
Some(MPPClaimHTLCSource {
counterparty_node_id: cp_id,
- funding_txo: htlc.prev_hop.outpoint,
- channel_id: htlc.prev_hop.channel_id,
- htlc_id: htlc.prev_hop.htlc_id,
+ funding_txo: htlc.mpp_part.prev_hop.outpoint,
+ channel_id: htlc.mpp_part.prev_hop.channel_id,
+ htlc_id: htlc.mpp_part.prev_hop.htlc_id,
})
} else {
None
@@ -9432,11 +9457,11 @@ impl<
for htlc in sources {
let this_mpp_claim =
pending_mpp_claim_ptr_opt.as_ref().map(|pending_mpp_claim| {
- let counterparty_id = htlc.prev_hop.counterparty_node_id;
+ let counterparty_id = htlc.mpp_part.prev_hop.counterparty_node_id;
let counterparty_id = counterparty_id
.expect("Prior to upgrading to LDK 0.1, all pending HTLCs forwarded by LDK 0.0.123 or before must be resolved. It appears at least one claimable payment was not resolved. Please downgrade to LDK 0.0.125 and resolve the HTLC by claiming the payment prior to upgrading.");
let claim_ptr = PendingMPPClaimPointer(Arc::clone(pending_mpp_claim));
- (counterparty_id, htlc.prev_hop.channel_id, claim_ptr)
+ (counterparty_id, htlc.mpp_part.prev_hop.channel_id, claim_ptr)
});
let raa_blocker = pending_mpp_claim_ptr_opt.as_ref().map(|pending_claim| {
RAAMonitorUpdateBlockingAction::ClaimedMPPPayment {
@@ -9448,7 +9473,7 @@ impl<
// non-zero value will not make a difference in the penalty that may be applied by the sender. If there
// is a phantom hop, we need to double-process.
let attribution_data =
- if let Some(phantom_secret) = htlc.prev_hop.phantom_shared_secret {
+ if let Some(phantom_secret) = htlc.mpp_part.prev_hop.phantom_shared_secret {
let attribution_data =
process_fulfill_attribution_data(None, &phantom_secret, 0);
Some(attribution_data)
@@ -9458,12 +9483,12 @@ impl<
let attribution_data = process_fulfill_attribution_data(
attribution_data,
- &htlc.prev_hop.incoming_packet_shared_secret,
+ &htlc.mpp_part.prev_hop.incoming_packet_shared_secret,
0,
);
self.claim_funds_from_hop(
- htlc.prev_hop,
+ &htlc.mpp_part.prev_hop,
payment_preimage,
payment_info.clone(),
Some(attribution_data),
@@ -9484,9 +9509,11 @@ impl<
}
} else {
for htlc in sources {
- let err_data =
- invalid_payment_err_data(htlc.value, self.best_block.read().unwrap().height);
- let source = HTLCSource::PreviousHopData(htlc.prev_hop);
+ let err_data = invalid_payment_err_data(
+ htlc.mpp_part.value,
+ self.best_block.read().unwrap().height,
+ );
+ let source = HTLCSource::PreviousHopData(htlc.mpp_part.prev_hop);
let reason = HTLCFailReason::reason(
LocalHTLCFailureReason::IncorrectPaymentDetails,
err_data,
@@ -9534,7 +9561,7 @@ impl<
#[cfg(test)]
let claiming_chan_funding_outpoint = hop_data.outpoint;
self.claim_funds_from_hop(
- hop_data,
+ &hop_data,
payment_preimage,
None,
Some(attribution_data),
@@ -9633,7 +9660,7 @@ impl<
bool,
) -> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
>(
- &self, prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage,
+ &self, prev_hop: &HTLCPreviousHopData, payment_preimage: PaymentPreimage,
payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
completion_action: ComplFunc,
) {
@@ -16172,14 +16199,14 @@ impl<
// our commitment transaction confirmed before the HTLC expires, plus the
// number of blocks we generally consider it to take to do a commitment update,
// just give up on it and fail the HTLC.
- if height >= htlc.cltv_expiry - HTLC_FAIL_BACK_BUFFER {
+ if height >= htlc.mpp_part.cltv_expiry - HTLC_FAIL_BACK_BUFFER {
let reason = LocalHTLCFailureReason::PaymentClaimBuffer;
timed_out_htlcs.push((
- HTLCSource::PreviousHopData(htlc.prev_hop.clone()),
+ HTLCSource::PreviousHopData(htlc.mpp_part.prev_hop.clone()),
payment_hash.clone(),
HTLCFailReason::reason(
reason,
- invalid_payment_err_data(htlc.value, height),
+ invalid_payment_err_data(htlc.mpp_part.value, height),
),
HTLCHandlingFailureType::Receive {
payment_hash: payment_hash.clone(),
@@ -17614,13 +17641,13 @@ fn write_claimable_htlc<W: Writer>(
OnionPayload::Spontaneous(preimage) => (None, Some(preimage)),
};
write_tlv_fields!(writer, {
- (0, htlc.prev_hop, required),
+ (0, htlc.mpp_part.prev_hop, required),
(1, total_mpp_value_msat, required),
- (2, htlc.value, required),
- (3, htlc.sender_intended_value, required),
+ (2, htlc.mpp_part.value, required),
+ (3, htlc.mpp_part.sender_intended_value, required),
(4, payment_data, option),
- (5, htlc.total_value_received, option),
- (6, htlc.cltv_expiry, required),
+ (5, htlc.mpp_part.total_value_received, option),
+ (6, htlc.mpp_part.cltv_expiry, required),
(8, keysend_preimage, option),
(10, htlc.counterparty_skimmed_fee_msat, option),
});
@@ -17653,13 +17680,15 @@ impl Readable for (ClaimableHTLC, u64) {
None => OnionPayload::Invoice { _legacy_hop_data: payment_data },
};
Ok((ClaimableHTLC {
- prev_hop: prev_hop.0.unwrap(),
- timer_ticks: 0,
- value,
- sender_intended_value: sender_intended_value.unwrap_or(value),
- total_value_received,
+ mpp_part: MppPart {
+ prev_hop: prev_hop.0.unwrap(),
+ timer_ticks: 0,
+ value,
+ sender_intended_value: sender_intended_value.unwrap_or(value),
+ total_value_received,
+ cltv_expiry: cltv_expiry.0.unwrap(),
+ },
onion_payload,
- cltv_expiry: cltv_expiry.0.unwrap(),
counterparty_skimmed_fee_msat,
}, total_msat.0.expect("required field")))
}
@@ -19783,10 +19812,13 @@ impl<
// panic if we attempted to claim them at this point.
for (payment_hash, payment) in claimable_payments.iter() {
for htlc in payment.htlcs.iter() {
- if htlc.prev_hop.counterparty_node_id.is_some() {
+ if htlc.mpp_part.prev_hop.counterparty_node_id.is_some() {
continue;
}
- if short_to_chan_info.get(&htlc.prev_hop.prev_outbound_scid_alias).is_some() {
+ if short_to_chan_info
+ .get(&htlc.mpp_part.prev_hop.prev_outbound_scid_alias)
+ .is_some()
+ {
log_error!(args.logger,
"We do not have the required information to claim a pending payment with payment hash {} reliably.\
As long as the channel for the inbound edge of the forward remains open, this may work okay, but we may panic at runtime!\
@@ -19974,10 +20006,10 @@ impl<
// See above comment on `failed_htlcs`.
for htlcs in claimable_payments.values().map(|pmt| &pmt.htlcs) {
- for prev_hop_data in htlcs.iter().map(|h| &h.prev_hop) {
+ for htlc in htlcs.iter() {
dedup_decode_update_add_htlcs(
&mut decode_update_add_htlcs,
- prev_hop_data,
+ &htlc.mpp_part.prev_hop,
"HTLC was already decoded and marked as a claimable payment",
&args.logger,
);
@@ -20280,7 +20312,8 @@ impl<
log_info!(channel_manager.logger, "Re-claiming HTLCs with payment hash {} as we've released the preimage to a ChannelMonitor!", &payment_hash);
let mut claimable_amt_msat = 0;
let mut receiver_node_id = Some(our_network_pubkey);
- let phantom_shared_secret = payment.htlcs[0].prev_hop.phantom_shared_secret;
+ let phantom_shared_secret =
+ payment.htlcs[0].mpp_part.prev_hop.phantom_shared_secret;
if phantom_shared_secret.is_some() {
let phantom_pubkey = channel_manager
.node_signer
@@ -20289,7 +20322,7 @@ impl<
receiver_node_id = Some(phantom_pubkey)
}
for claimable_htlc in &payment.htlcs {
- claimable_amt_msat += claimable_htlc.value;
+ claimable_amt_msat += claimable_htlc.mpp_part.value;
// Add a holding-cell claim of the payment to the Channel, which should be
// applied ~immediately on peer reconnection. Because it won't generate a
@@ -20306,7 +20339,7 @@ impl<
// this channel as well. On the flip side, there's no harm in restarting
// without the new monitor persisted - we'll end up right back here on
// restart.
- let previous_channel_id = claimable_htlc.prev_hop.channel_id;
+ let previous_channel_id = claimable_htlc.mpp_part.prev_hop.channel_id;
let peer_node_id = monitor.get_counterparty_node_id();
{
let peer_state_mutex = per_peer_state.get(&peer_node_id).unwrap();
@@ -20324,14 +20357,15 @@ impl<
);
channel
.claim_htlc_while_disconnected_dropping_mon_update_legacy(
- claimable_htlc.prev_hop.htlc_id,
+ claimable_htlc.mpp_part.prev_hop.htlc_id,
payment_preimage,
&&logger,
);
}
}
- if let Some(previous_hop_monitor) =
- args.channel_monitors.get(&claimable_htlc.prev_hop.channel_id)
+ if let Some(previous_hop_monitor) = args
+ .channel_monitors
+ .get(&claimable_htlc.mpp_part.prev_hop.channel_id)
{
// Note that this is unsafe as we no longer require the
// `ChannelMonitor`s to be re-persisted prior to this
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.