Skip to content

Commit 74c67c1

Browse files
committed
Add total-MPP-value storage in pending payments
In some uses of LDK we need the ability to send HTLCs for only a portion of some larger MPP payment. This allows payers to make single payments which spend funds from multiple wallets, which may be important for ecash wallets holding funds in multiple mints or graduated wallets which hold funds across a trusted wallet and a self-custodial wallet. In the previous commits we moved the total-MPP-value we set in onions from being manually passed through onion-building to passing it via `RecipientOnionFields`. This introduced a subtle bug, though - payments which are retried will get a fresh `RecipientOnionFields` built from the data in `PendingOutboundPayment::Retryable`, losing any custom total-MPP-value settings and causing retries to fail. Here we fix this by storing the total-MPP-value directly in `PendingOutboundPayment::Retryable`.
1 parent 7bcbc9d commit 74c67c1

1 file changed

Lines changed: 24 additions & 2 deletions

File tree

lightning/src/ln/outbound_payment.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ pub(crate) enum PendingOutboundPayment {
133133
pending_fee_msat: Option<u64>,
134134
/// The total payment amount across all paths, used to verify that a retry is not overpaying.
135135
total_msat: u64,
136+
/// The total payment amount which is set in the onion.
137+
///
138+
/// This is generally equal to [`Self::Retryable::total_msat`] but may differ when making
139+
/// payments which are sent MPP from different sources.
140+
onion_total_msat: u64,
136141
/// Our best known block height at the time this payment was initiated.
137142
starting_block_height: u32,
138143
remaining_max_total_routing_fee_msat: Option<u64>,
@@ -1656,7 +1661,7 @@ impl OutboundPayments {
16561661
match payment.get() {
16571662
PendingOutboundPayment::Retryable {
16581663
total_msat, keysend_preimage, payment_secret, payment_metadata,
1659-
custom_tlvs, pending_amt_msat, invoice_request, ..
1664+
custom_tlvs, pending_amt_msat, invoice_request, onion_total_msat, ..
16601665
} => {
16611666
const RETRY_OVERFLOW_PERCENTAGE: u64 = 10;
16621667
let retry_amt_msat = route.get_total_amount();
@@ -1676,7 +1681,7 @@ impl OutboundPayments {
16761681
payment_secret: *payment_secret,
16771682
payment_metadata: payment_metadata.clone(),
16781683
custom_tlvs: custom_tlvs.clone(),
1679-
total_mpp_amount_msat: *total_msat,
1684+
total_mpp_amount_msat: *onion_total_msat,
16801685
};
16811686
let keysend_preimage = *keysend_preimage;
16821687
let invoice_request = invoice_request.clone();
@@ -1992,6 +1997,7 @@ impl OutboundPayments {
19921997
custom_tlvs: recipient_onion.custom_tlvs,
19931998
starting_block_height: best_block_height,
19941999
total_msat: route.get_total_amount(),
2000+
onion_total_msat: recipient_onion.total_mpp_amount_msat,
19952001
remaining_max_total_routing_fee_msat:
19962002
route.route_params.as_ref().and_then(|p| p.max_total_routing_fee_msat),
19972003
};
@@ -2699,6 +2705,7 @@ impl OutboundPayments {
26992705
pending_amt_msat: path_amt,
27002706
pending_fee_msat: Some(path_fee),
27012707
total_msat: path_amt,
2708+
onion_total_msat: path_amt,
27022709
starting_block_height: best_block_height,
27032710
remaining_max_total_routing_fee_msat: None, // only used for retries, and we'll never retry on startup
27042711
}
@@ -2781,6 +2788,21 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
27812788
(9, custom_tlvs, optional_vec),
27822789
(10, starting_block_height, required),
27832790
(11, remaining_max_total_routing_fee_msat, option),
2791+
(12, onion_total_msat, (custom, u64,
2792+
// Once we get here, `total_msat` will have been read (or we'll fail to read)
2793+
|read_val: Option<u64>| Ok(read_val.unwrap_or(total_msat.0.unwrap())),
2794+
|us: &PendingOutboundPayment| {
2795+
match us {
2796+
PendingOutboundPayment::Retryable { total_msat, onion_total_msat, .. } => {
2797+
if total_msat != onion_total_msat {
2798+
Some(*onion_total_msat)
2799+
} else {
2800+
None
2801+
}
2802+
},
2803+
_ => unreachable!(),
2804+
}
2805+
})),
27842806
(13, invoice_request, option),
27852807
(15, bolt12_invoice, option),
27862808
(not_written, retry_strategy, (static_value, None)),

0 commit comments

Comments
 (0)