@@ -539,8 +539,6 @@ struct ClaimableHTLC {
539539 /// The total value received for a payment (sum of all MPP parts if the payment is a MPP).
540540 /// Gets set to the amount reported when pushing [`Event::PaymentClaimable`].
541541 total_value_received: Option<u64>,
542- /// The sender intended sum total of all MPP parts specified in the onion
543- total_msat: u64,
544542 /// The extra fee our counterparty skimmed off the top of this HTLC.
545543 counterparty_skimmed_fee_msat: Option<u64>,
546544}
@@ -1240,7 +1238,7 @@ impl ClaimablePayments {
12401238 })
12411239 .or_insert_with(|| {
12421240 let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
1243- let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat) ;
1241+ let sender_intended_value = payment.onion_fields.total_mpp_amount_msat ;
12441242 // Pick an "arbitrary" channel to block RAAs on until the `PaymentSent`
12451243 // event is processed, specifically the last channel to get claimed.
12461244 let durable_preimage_channel = payment.htlcs.last().map_or(None, |htlc| {
@@ -1256,7 +1254,7 @@ impl ClaimablePayments {
12561254 payment_purpose: payment.purpose,
12571255 receiver_node_id,
12581256 htlcs,
1259- sender_intended_value,
1257+ sender_intended_value: Some(sender_intended_value) ,
12601258 onion_fields: payment.onion_fields,
12611259 payment_id: Some(payment_id),
12621260 durable_preimage_channel,
@@ -7896,11 +7894,6 @@ impl<
78967894 sender_intended_value: outgoing_amt_msat,
78977895 timer_ticks: 0,
78987896 total_value_received: None,
7899- total_msat: if let Some(data) = &payment_data {
7900- data.total_msat
7901- } else {
7902- outgoing_amt_msat
7903- },
79047897 cltv_expiry,
79057898 onion_payload,
79067899 counterparty_skimmed_fee_msat: skimmed_fee_msat,
@@ -7981,27 +7974,25 @@ impl<
79817974 if onions_compatible.is_err() {
79827975 fail_htlc!(claimable_htlc, payment_hash);
79837976 }
7984- let mut total_value = claimable_htlc.sender_intended_value;
7977+ let mut total_intended_recvd_value =
7978+ claimable_htlc.sender_intended_value;
79857979 let mut earliest_expiry = claimable_htlc.cltv_expiry;
79867980 for htlc in claimable_payment.htlcs.iter() {
7987- total_value += htlc.sender_intended_value;
7981+ total_intended_recvd_value += htlc.sender_intended_value;
79887982 earliest_expiry = cmp::min(earliest_expiry, htlc.cltv_expiry);
7989- if htlc.total_msat != claimable_htlc.total_msat {
7990- log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})",
7991- &payment_hash, claimable_htlc.total_msat, htlc.total_msat);
7992- total_value = msgs::MAX_VALUE_MSAT;
7993- }
7994- if total_value >= msgs::MAX_VALUE_MSAT { break; }
7983+ if total_intended_recvd_value >= msgs::MAX_VALUE_MSAT { break; }
79957984 }
7985+ let total_mpp_value =
7986+ claimable_payment.onion_fields.total_mpp_amount_msat;
79967987 // The condition determining whether an MPP is complete must
79977988 // match exactly the condition used in `timer_tick_occurred`
7998- if total_value >= msgs::MAX_VALUE_MSAT {
7989+ if total_intended_recvd_value >= msgs::MAX_VALUE_MSAT {
79997990 fail_htlc!(claimable_htlc, payment_hash);
8000- } else if total_value - claimable_htlc.sender_intended_value >= claimable_htlc.total_msat {
7991+ } else if total_intended_recvd_value - claimable_htlc.sender_intended_value >= total_mpp_value {
80017992 log_trace!(self.logger, "Failing HTLC with payment_hash {} as payment is already claimable",
80027993 &payment_hash);
80037994 fail_htlc!(claimable_htlc, payment_hash);
8004- } else if total_value >= claimable_htlc.total_msat {
7995+ } else if total_intended_recvd_value >= total_mpp_value {
80057996 #[allow(unused_assignments)] {
80067997 committed_to_claimable = true;
80077998 }
@@ -8012,8 +8003,8 @@ impl<
80128003 .for_each(|htlc| htlc.total_value_received = Some(amount_msat));
80138004 let counterparty_skimmed_fee_msat = claimable_payment.htlcs.iter()
80148005 .map(|htlc| htlc.counterparty_skimmed_fee_msat.unwrap_or(0)).sum();
8015- debug_assert!(total_value .saturating_sub(amount_msat) <=
8016- counterparty_skimmed_fee_msat);
8006+ debug_assert!(total_intended_recvd_value .saturating_sub(amount_msat)
8007+ <= counterparty_skimmed_fee_msat);
80178008 claimable_payment.htlcs.sort();
80188009 let payment_id =
80198010 claimable_payment.inbound_payment_id(&self.inbound_payment_id_secret);
@@ -8508,9 +8499,10 @@ impl<
85088499 // In this case we're not going to handle any timeouts of the parts here.
85098500 // This condition determining whether the MPP is complete here must match
85108501 // exactly the condition used in `process_pending_htlc_forwards`.
8511- let htlc_total_msat =
8502+ let total_intended_recvd_value =
85128503 payment.htlcs.iter().map(|h| h.sender_intended_value).sum();
8513- if payment.htlcs[0].total_msat <= htlc_total_msat {
8504+ let total_mpp_value = payment.onion_fields.total_mpp_amount_msat;
8505+ if total_mpp_value <= total_intended_recvd_value {
85148506 return true;
85158507 } else if payment.htlcs.iter_mut().any(|htlc| {
85168508 htlc.timer_ticks += 1;
@@ -8925,20 +8917,11 @@ impl<
89258917 // amount we told the user in the last `PaymentClaimable`. We also do a sanity-check that
89268918 // the MPP parts all have the same `total_msat`.
89278919 let mut claimable_amt_msat = 0;
8928- let mut prev_total_msat = None;
89298920 let mut expected_amt_msat = None;
89308921 let mut valid_mpp = true;
89318922 let mut errs = Vec::new();
89328923 let per_peer_state = self.per_peer_state.read().unwrap();
89338924 for htlc in sources.iter() {
8934- if prev_total_msat.is_some() && prev_total_msat != Some(htlc.total_msat) {
8935- log_error!(self.logger, "Somehow ended up with an MPP payment with different expected total amounts - this should not be reachable!");
8936- debug_assert!(false);
8937- valid_mpp = false;
8938- break;
8939- }
8940- prev_total_msat = Some(htlc.total_msat);
8941-
89428925 if expected_amt_msat.is_some() && expected_amt_msat != htlc.total_value_received {
89438926 log_error!(self.logger, "Somehow ended up with an MPP payment with different received total amounts - this should not be reachable!");
89448927 debug_assert!(false);
@@ -16780,28 +16763,28 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
1678016763 (13, trampoline_shared_secret, option),
1678116764});
1678216765
16783- impl Writeable for ClaimableHTLC {
16784- fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
16785- let (payment_data, keysend_preimage) = match &self.onion_payload {
16786- OnionPayload::Invoice { _legacy_hop_data } => (_legacy_hop_data.as_ref(), None),
16787- OnionPayload::Spontaneous(preimage) => (None, Some(preimage) ),
16788- };
16789- write_tlv_fields!(writer, {
16790- (0, self.prev_hop, required),
16791- (1, self.total_msat , required),
16792- (2, self.value , required),
16793- (3, self.sender_intended_value , required),
16794- (4, payment_data, option ),
16795- (5, self.total_value_received , option),
16796- (6, self.cltv_expiry, required ),
16797- (8, keysend_preimage, option ),
16798- (10, self.counterparty_skimmed_fee_msat , option),
16799- });
16800- Ok(())
16801- }
16766+ fn write_claimable_htlc<W: Writer>(
16767+ htlc: &ClaimableHTLC, total_mpp_value_msat: u64, writer: &mut W,
16768+ ) -> Result<(), io::Error> {
16769+ let (payment_data, keysend_preimage) = match &htlc.onion_payload {
16770+ OnionPayload::Invoice { _legacy_hop_data } => (_legacy_hop_data.as_ref(), None ),
16771+ OnionPayload::Spontaneous(preimage) => (None, Some(preimage)),
16772+ };
16773+ write_tlv_fields!(writer, {
16774+ (0, htlc.prev_hop , required),
16775+ (1, total_mpp_value_msat , required),
16776+ (2, htlc.value , required),
16777+ (3, htlc.sender_intended_value, required ),
16778+ (4, payment_data , option),
16779+ (5, htlc.total_value_received, option ),
16780+ (6, htlc.cltv_expiry, required ),
16781+ (8, keysend_preimage , option),
16782+ (10, htlc.counterparty_skimmed_fee_msat, option),
16783+ });
16784+ Ok(())
1680216785}
1680316786
16804- impl Readable for ClaimableHTLC {
16787+ impl Readable for ( ClaimableHTLC, u64) {
1680516788 #[rustfmt::skip]
1680616789 fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
1680716790 _init_and_read_len_prefixed_tlv_fields!(reader, {
@@ -16837,17 +16820,16 @@ impl Readable for ClaimableHTLC {
1683716820 OnionPayload::Invoice { _legacy_hop_data: payment_data }
1683816821 },
1683916822 };
16840- Ok(Self {
16823+ Ok((ClaimableHTLC {
1684116824 prev_hop: prev_hop.0.unwrap(),
1684216825 timer_ticks: 0,
1684316826 value,
1684416827 sender_intended_value: sender_intended_value.unwrap_or(value),
1684516828 total_value_received,
16846- total_msat: total_msat.unwrap(),
1684716829 onion_payload,
1684816830 cltv_expiry: cltv_expiry.0.unwrap(),
1684916831 counterparty_skimmed_fee_msat,
16850- })
16832+ }, total_msat.unwrap()) )
1685116833 }
1685216834}
1685316835
@@ -17113,7 +17095,7 @@ impl<
1711317095 payment_hash.write(writer)?;
1711417096 (payment.htlcs.len() as u64).write(writer)?;
1711517097 for htlc in payment.htlcs.iter() {
17116- htlc.write( writer)?;
17098+ write_claimable_htlc(& htlc, payment.onion_fields.total_mpp_amount_msat, writer)?;
1711717099 }
1711817100 htlc_purposes.push(&payment.purpose);
1711917101 htlc_onion_fields.push(Some(&payment.onion_fields));
@@ -17387,24 +17369,18 @@ pub(super) struct ChannelManagerData<SP: SignerProvider> {
1738717369}
1738817370
1738917371/// Arguments for deserializing [`ChannelManagerData`].
17390- struct ChannelManagerDataReadArgs<
17391- 'a,
17392- ES: EntropySource,
17393- NS: NodeSigner,
17394- SP: SignerProvider,
17395- L: Logger,
17396- > {
17372+ struct ChannelManagerDataReadArgs<'a, ES: EntropySource, SP: SignerProvider, L: Logger> {
1739717373 entropy_source: &'a ES,
1739817374 signer_provider: &'a SP,
1739917375 config: UserConfig,
1740017376 logger: &'a L,
1740117377}
1740217378
17403- impl<'a, ES: EntropySource, NS: NodeSigner, SP: SignerProvider, L: Logger>
17404- ReadableArgs<ChannelManagerDataReadArgs<'a, ES, NS, SP, L>> for ChannelManagerData<SP>
17379+ impl<'a, ES: EntropySource, SP: SignerProvider, L: Logger>
17380+ ReadableArgs<ChannelManagerDataReadArgs<'a, ES, SP, L>> for ChannelManagerData<SP>
1740517381{
1740617382 fn read<R: io::Read>(
17407- reader: &mut R, args: ChannelManagerDataReadArgs<'a, ES, NS, SP, L>,
17383+ reader: &mut R, args: ChannelManagerDataReadArgs<'a, ES, SP, L>,
1740817384 ) -> Result<Self, DecodeError> {
1740917385 let version = read_ver_prefix!(reader, SERIALIZATION_VERSION);
1741017386
@@ -17459,10 +17435,20 @@ impl<'a, ES: EntropySource, NS: NodeSigner, SP: SignerProvider, L: Logger>
1745917435 previous_hops_len as usize,
1746017436 MAX_ALLOC_SIZE / mem::size_of::<ClaimableHTLC>(),
1746117437 ));
17438+ let mut total_mpp_value_msat = None;
1746217439 for _ in 0..previous_hops_len {
17463- previous_hops.push(<ClaimableHTLC as Readable>::read(reader)?);
17440+ let (htlc, total_mpp_value_msat_read) =
17441+ <(ClaimableHTLC, u64) as Readable>::read(reader)?;
17442+ if total_mpp_value_msat.is_some()
17443+ && total_mpp_value_msat != Some(total_mpp_value_msat_read)
17444+ {
17445+ return Err(DecodeError::InvalidValue);
17446+ }
17447+ total_mpp_value_msat = Some(total_mpp_value_msat_read);
17448+ previous_hops.push(htlc);
1746417449 }
17465- claimable_htlcs_list.push((payment_hash, previous_hops));
17450+ let total_mpp_value_msat = total_mpp_value_msat.ok_or(DecodeError::InvalidValue)?;
17451+ claimable_htlcs_list.push((payment_hash, previous_hops, total_mpp_value_msat));
1746617452 }
1746717453
1746817454 let peer_count: u64 = Readable::read(reader)?;
@@ -17641,19 +17627,17 @@ impl<'a, ES: EntropySource, NS: NodeSigner, SP: SignerProvider, L: Logger>
1764117627 if onion_fields.len() != claimable_htlcs_list.len() {
1764217628 return Err(DecodeError::InvalidValue);
1764317629 }
17644- for (purpose, (onion, (payment_hash, htlcs))) in purposes
17630+ for (purpose, (onion, (payment_hash, htlcs, total_mpp_value_msat ))) in purposes
1764517631 .into_iter()
1764617632 .zip(onion_fields.into_iter().zip(claimable_htlcs_list.into_iter()))
1764717633 {
17648- let htlcs_total_msat =
17649- htlcs.first().ok_or(DecodeError::InvalidValue)?.total_msat;
1765017634 let onion_fields = if let Some(mut onion) = onion {
1765117635 if onion.0.total_mpp_amount_msat != 0
17652- && onion.0.total_mpp_amount_msat != htlcs_total_msat
17636+ && onion.0.total_mpp_amount_msat != total_mpp_value_msat
1765317637 {
1765417638 return Err(DecodeError::InvalidValue);
1765517639 }
17656- onion.0.total_mpp_amount_msat = htlcs_total_msat ;
17640+ onion.0.total_mpp_amount_msat = total_mpp_value_msat ;
1765717641 onion.0
1765817642 } else {
1765917643 return Err(DecodeError::InvalidValue);
@@ -19607,16 +19591,15 @@ impl<
1960719591 let payment_id =
1960819592 payment.inbound_payment_id(&inbound_payment_id_secret.unwrap());
1960919593 let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
19610- let sender_intended_total_msat =
19611- payment.htlcs.first().map(|htlc| htlc.total_msat);
19594+ let sender_intended_total_msat = payment.onion_fields.total_mpp_amount_msat;
1961219595 pending_events.push_back((
1961319596 events::Event::PaymentClaimed {
1961419597 receiver_node_id,
1961519598 payment_hash,
1961619599 purpose: payment.purpose,
1961719600 amount_msat: claimable_amt_msat,
1961819601 htlcs,
19619- sender_intended_total_msat,
19602+ sender_intended_total_msat: Some(sender_intended_total_msat) ,
1962019603 onion_fields: Some(payment.onion_fields),
1962119604 payment_id: Some(payment_id),
1962219605 },
0 commit comments