@@ -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}
@@ -1255,7 +1253,7 @@ impl ClaimablePayments {
12551253 })
12561254 .or_insert_with(|| {
12571255 let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
1258- let sender_intended_value = payment.htlcs.first().map(|htlc| htlc.total_msat) ;
1256+ let sender_intended_value = payment.onion_fields.total_mpp_amount_msat ;
12591257 // Pick an "arbitrary" channel to block RAAs on until the `PaymentSent`
12601258 // event is processed, specifically the last channel to get claimed.
12611259 let durable_preimage_channel = payment.htlcs.last().map_or(None, |htlc| {
@@ -1271,7 +1269,7 @@ impl ClaimablePayments {
12711269 payment_purpose: payment.purpose,
12721270 receiver_node_id,
12731271 htlcs,
1274- sender_intended_value,
1272+ sender_intended_value: Some(sender_intended_value) ,
12751273 onion_fields: payment.onion_fields,
12761274 payment_id: Some(payment_id),
12771275 durable_preimage_channel,
@@ -7884,11 +7882,6 @@ impl<
78847882 sender_intended_value: outgoing_amt_msat,
78857883 timer_ticks: 0,
78867884 total_value_received: None,
7887- total_msat: if let Some(data) = &payment_data {
7888- data.total_msat
7889- } else {
7890- outgoing_amt_msat
7891- },
78927885 cltv_expiry,
78937886 onion_payload,
78947887 counterparty_skimmed_fee_msat: skimmed_fee_msat,
@@ -7969,27 +7962,25 @@ impl<
79697962 if onions_compatible.is_err() {
79707963 fail_htlc!(claimable_htlc, payment_hash);
79717964 }
7972- let mut total_value = claimable_htlc.sender_intended_value;
7965+ let mut total_intended_recvd_value =
7966+ claimable_htlc.sender_intended_value;
79737967 let mut earliest_expiry = claimable_htlc.cltv_expiry;
79747968 for htlc in claimable_payment.htlcs.iter() {
7975- total_value += htlc.sender_intended_value;
7969+ total_intended_recvd_value += htlc.sender_intended_value;
79767970 earliest_expiry = cmp::min(earliest_expiry, htlc.cltv_expiry);
7977- if htlc.total_msat != claimable_htlc.total_msat {
7978- log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})",
7979- &payment_hash, claimable_htlc.total_msat, htlc.total_msat);
7980- total_value = msgs::MAX_VALUE_MSAT;
7981- }
7982- if total_value >= msgs::MAX_VALUE_MSAT { break; }
7971+ if total_intended_recvd_value >= msgs::MAX_VALUE_MSAT { break; }
79837972 }
7973+ let total_mpp_value =
7974+ claimable_payment.onion_fields.total_mpp_amount_msat;
79847975 // The condition determining whether an MPP is complete must
79857976 // match exactly the condition used in `timer_tick_occurred`
7986- if total_value >= msgs::MAX_VALUE_MSAT {
7977+ if total_intended_recvd_value >= msgs::MAX_VALUE_MSAT {
79877978 fail_htlc!(claimable_htlc, payment_hash);
7988- } else if total_value - claimable_htlc.sender_intended_value >= claimable_htlc.total_msat {
7979+ } else if total_intended_recvd_value - claimable_htlc.sender_intended_value >= total_mpp_value {
79897980 log_trace!(self.logger, "Failing HTLC with payment_hash {} as payment is already claimable",
79907981 &payment_hash);
79917982 fail_htlc!(claimable_htlc, payment_hash);
7992- } else if total_value >= claimable_htlc.total_msat {
7983+ } else if total_intended_recvd_value >= total_mpp_value {
79937984 #[allow(unused_assignments)] {
79947985 committed_to_claimable = true;
79957986 }
@@ -8000,8 +7991,8 @@ impl<
80007991 .for_each(|htlc| htlc.total_value_received = Some(amount_msat));
80017992 let counterparty_skimmed_fee_msat = claimable_payment.htlcs.iter()
80027993 .map(|htlc| htlc.counterparty_skimmed_fee_msat.unwrap_or(0)).sum();
8003- debug_assert!(total_value .saturating_sub(amount_msat) <=
8004- counterparty_skimmed_fee_msat);
7994+ debug_assert!(total_intended_recvd_value .saturating_sub(amount_msat)
7995+ <= counterparty_skimmed_fee_msat);
80057996 claimable_payment.htlcs.sort();
80067997 let payment_id =
80077998 claimable_payment.inbound_payment_id(&self.inbound_payment_id_secret);
@@ -8496,9 +8487,10 @@ impl<
84968487 // In this case we're not going to handle any timeouts of the parts here.
84978488 // This condition determining whether the MPP is complete here must match
84988489 // exactly the condition used in `process_pending_htlc_forwards`.
8499- let htlc_total_msat =
8490+ let total_intended_recvd_value =
85008491 payment.htlcs.iter().map(|h| h.sender_intended_value).sum();
8501- if payment.htlcs[0].total_msat <= htlc_total_msat {
8492+ let total_mpp_value = payment.onion_fields.total_mpp_amount_msat;
8493+ if total_mpp_value <= total_intended_recvd_value {
85028494 return true;
85038495 } else if payment.htlcs.iter_mut().any(|htlc| {
85048496 htlc.timer_ticks += 1;
@@ -8913,20 +8905,11 @@ impl<
89138905 // amount we told the user in the last `PaymentClaimable`. We also do a sanity-check that
89148906 // the MPP parts all have the same `total_msat`.
89158907 let mut claimable_amt_msat = 0;
8916- let mut prev_total_msat = None;
89178908 let mut expected_amt_msat = None;
89188909 let mut valid_mpp = true;
89198910 let mut errs = Vec::new();
89208911 let per_peer_state = self.per_peer_state.read().unwrap();
89218912 for htlc in sources.iter() {
8922- if prev_total_msat.is_some() && prev_total_msat != Some(htlc.total_msat) {
8923- log_error!(self.logger, "Somehow ended up with an MPP payment with different expected total amounts - this should not be reachable!");
8924- debug_assert!(false);
8925- valid_mpp = false;
8926- break;
8927- }
8928- prev_total_msat = Some(htlc.total_msat);
8929-
89308913 if expected_amt_msat.is_some() && expected_amt_msat != htlc.total_value_received {
89318914 log_error!(self.logger, "Somehow ended up with an MPP payment with different received total amounts - this should not be reachable!");
89328915 debug_assert!(false);
@@ -16937,28 +16920,28 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
1693716920 (13, trampoline_shared_secret, option),
1693816921});
1693916922
16940- impl Writeable for ClaimableHTLC {
16941- fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
16942- let (payment_data, keysend_preimage) = match &self.onion_payload {
16943- OnionPayload::Invoice { _legacy_hop_data } => (_legacy_hop_data.as_ref(), None),
16944- OnionPayload::Spontaneous(preimage) => (None, Some(preimage) ),
16945- };
16946- write_tlv_fields!(writer, {
16947- (0, self.prev_hop, required),
16948- (1, self.total_msat , required),
16949- (2, self.value , required),
16950- (3, self.sender_intended_value , required),
16951- (4, payment_data, option ),
16952- (5, self.total_value_received , option),
16953- (6, self.cltv_expiry, required ),
16954- (8, keysend_preimage, option ),
16955- (10, self.counterparty_skimmed_fee_msat , option),
16956- });
16957- Ok(())
16958- }
16923+ fn write_claimable_htlc<W: Writer>(
16924+ htlc: &ClaimableHTLC, total_mpp_value_msat: u64, writer: &mut W,
16925+ ) -> Result<(), io::Error> {
16926+ let (payment_data, keysend_preimage) = match &htlc.onion_payload {
16927+ OnionPayload::Invoice { _legacy_hop_data } => (_legacy_hop_data.as_ref(), None ),
16928+ OnionPayload::Spontaneous(preimage) => (None, Some(preimage)),
16929+ };
16930+ write_tlv_fields!(writer, {
16931+ (0, htlc.prev_hop , required),
16932+ (1, total_mpp_value_msat , required),
16933+ (2, htlc.value , required),
16934+ (3, htlc.sender_intended_value, required ),
16935+ (4, payment_data , option),
16936+ (5, htlc.total_value_received, option ),
16937+ (6, htlc.cltv_expiry, required ),
16938+ (8, keysend_preimage , option),
16939+ (10, htlc.counterparty_skimmed_fee_msat, option),
16940+ });
16941+ Ok(())
1695916942}
1696016943
16961- impl Readable for ClaimableHTLC {
16944+ impl Readable for ( ClaimableHTLC, u64) {
1696216945 #[rustfmt::skip]
1696316946 fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
1696416947 _init_and_read_len_prefixed_tlv_fields!(reader, {
@@ -16994,17 +16977,16 @@ impl Readable for ClaimableHTLC {
1699416977 OnionPayload::Invoice { _legacy_hop_data: payment_data }
1699516978 },
1699616979 };
16997- Ok(Self {
16980+ Ok((ClaimableHTLC {
1699816981 prev_hop: prev_hop.0.unwrap(),
1699916982 timer_ticks: 0,
1700016983 value,
1700116984 sender_intended_value: sender_intended_value.unwrap_or(value),
1700216985 total_value_received,
17003- total_msat: total_msat.unwrap(),
1700416986 onion_payload,
1700516987 cltv_expiry: cltv_expiry.0.unwrap(),
1700616988 counterparty_skimmed_fee_msat,
17007- })
16989+ }, total_msat.unwrap()) )
1700816990 }
1700916991}
1701016992
@@ -17270,7 +17252,7 @@ impl<
1727017252 payment_hash.write(writer)?;
1727117253 (payment.htlcs.len() as u64).write(writer)?;
1727217254 for htlc in payment.htlcs.iter() {
17273- htlc.write( writer)?;
17255+ write_claimable_htlc(& htlc, payment.onion_fields.total_mpp_amount_msat, writer)?;
1727417256 }
1727517257 htlc_purposes.push(&payment.purpose);
1727617258 htlc_onion_fields.push(Some(&payment.onion_fields));
@@ -17544,24 +17526,18 @@ pub(super) struct ChannelManagerData<SP: SignerProvider> {
1754417526}
1754517527
1754617528/// Arguments for deserializing [`ChannelManagerData`].
17547- struct ChannelManagerDataReadArgs<
17548- 'a,
17549- ES: EntropySource,
17550- NS: NodeSigner,
17551- SP: SignerProvider,
17552- L: Logger,
17553- > {
17529+ struct ChannelManagerDataReadArgs<'a, ES: EntropySource, SP: SignerProvider, L: Logger> {
1755417530 entropy_source: &'a ES,
1755517531 signer_provider: &'a SP,
1755617532 config: UserConfig,
1755717533 logger: &'a L,
1755817534}
1755917535
17560- impl<'a, ES: EntropySource, NS: NodeSigner, SP: SignerProvider, L: Logger>
17561- ReadableArgs<ChannelManagerDataReadArgs<'a, ES, NS, SP, L>> for ChannelManagerData<SP>
17536+ impl<'a, ES: EntropySource, SP: SignerProvider, L: Logger>
17537+ ReadableArgs<ChannelManagerDataReadArgs<'a, ES, SP, L>> for ChannelManagerData<SP>
1756217538{
1756317539 fn read<R: io::Read>(
17564- reader: &mut R, args: ChannelManagerDataReadArgs<'a, ES, NS, SP, L>,
17540+ reader: &mut R, args: ChannelManagerDataReadArgs<'a, ES, SP, L>,
1756517541 ) -> Result<Self, DecodeError> {
1756617542 let version = read_ver_prefix!(reader, SERIALIZATION_VERSION);
1756717543
@@ -17616,10 +17592,20 @@ impl<'a, ES: EntropySource, NS: NodeSigner, SP: SignerProvider, L: Logger>
1761617592 previous_hops_len as usize,
1761717593 MAX_ALLOC_SIZE / mem::size_of::<ClaimableHTLC>(),
1761817594 ));
17595+ let mut total_mpp_value_msat = None;
1761917596 for _ in 0..previous_hops_len {
17620- previous_hops.push(<ClaimableHTLC as Readable>::read(reader)?);
17597+ let (htlc, total_mpp_value_msat_read) =
17598+ <(ClaimableHTLC, u64) as Readable>::read(reader)?;
17599+ if total_mpp_value_msat.is_some()
17600+ && total_mpp_value_msat != Some(total_mpp_value_msat_read)
17601+ {
17602+ return Err(DecodeError::InvalidValue);
17603+ }
17604+ total_mpp_value_msat = Some(total_mpp_value_msat_read);
17605+ previous_hops.push(htlc);
1762117606 }
17622- claimable_htlcs_list.push((payment_hash, previous_hops));
17607+ let total_mpp_value_msat = total_mpp_value_msat.ok_or(DecodeError::InvalidValue)?;
17608+ claimable_htlcs_list.push((payment_hash, previous_hops, total_mpp_value_msat));
1762317609 }
1762417610
1762517611 let peer_count: u64 = Readable::read(reader)?;
@@ -17798,19 +17784,17 @@ impl<'a, ES: EntropySource, NS: NodeSigner, SP: SignerProvider, L: Logger>
1779817784 if onion_fields.len() != claimable_htlcs_list.len() {
1779917785 return Err(DecodeError::InvalidValue);
1780017786 }
17801- for (purpose, (onion, (payment_hash, htlcs))) in purposes
17787+ for (purpose, (onion, (payment_hash, htlcs, total_mpp_value_msat ))) in purposes
1780217788 .into_iter()
1780317789 .zip(onion_fields.into_iter().zip(claimable_htlcs_list.into_iter()))
1780417790 {
17805- let htlcs_total_msat =
17806- htlcs.first().ok_or(DecodeError::InvalidValue)?.total_msat;
1780717791 let onion_fields = if let Some(mut onion) = onion {
1780817792 if onion.0.total_mpp_amount_msat != 0
17809- && onion.0.total_mpp_amount_msat != htlcs_total_msat
17793+ && onion.0.total_mpp_amount_msat != total_mpp_value_msat
1781017794 {
1781117795 return Err(DecodeError::InvalidValue);
1781217796 }
17813- onion.0.total_mpp_amount_msat = htlcs_total_msat ;
17797+ onion.0.total_mpp_amount_msat = total_mpp_value_msat ;
1781417798 onion.0
1781517799 } else {
1781617800 return Err(DecodeError::InvalidValue);
@@ -19760,16 +19744,15 @@ impl<
1976019744 let payment_id =
1976119745 payment.inbound_payment_id(&inbound_payment_id_secret.unwrap());
1976219746 let htlcs = payment.htlcs.iter().map(events::ClaimedHTLC::from).collect();
19763- let sender_intended_total_msat =
19764- payment.htlcs.first().map(|htlc| htlc.total_msat);
19747+ let sender_intended_total_msat = payment.onion_fields.total_mpp_amount_msat;
1976519748 pending_events.push_back((
1976619749 events::Event::PaymentClaimed {
1976719750 receiver_node_id,
1976819751 payment_hash,
1976919752 purpose: payment.purpose,
1977019753 amount_msat: claimable_amt_msat,
1977119754 htlcs,
19772- sender_intended_total_msat,
19755+ sender_intended_total_msat: Some(sender_intended_total_msat) ,
1977319756 onion_fields: Some(payment.onion_fields),
1977419757 payment_id: Some(payment_id),
1977519758 },
0 commit comments