Skip to content

Commit d94c3ce

Browse files
committed
Update AwaitingInvoice to include UserParameters
When `pay_for_offer` is called, it creates a new `PendingOutboundPayment` entry with relevant values that will be used when the corresponding invoice is received. This update modifies `AwaitingInvoice` to include the entire `UserParameters` struct instead of just `max_total_routing_fee_msat`. This change ensures all manual routing parameters are available when finding payment routes. Decisions & Reasoning: 1. **Retention of `max_total_routing_fee_msat` in `AwaitingInvoice`:** This field is retained to ensure downgrade support. However, it is removed from `InvoiceReceived` since it was never used, thereby helping to clean up the code while still supporting downgrading. 2. **Introduction of `user_params` in `InvoiceReceived`:** This was added for the same reason that `max_total_routing_fee_msat` was originally introduced in PR lightningdevkit#2417. The documentation has been updated to reflect this, based on [this comment](lightningdevkit@d7e2ff6#r1334619765).
1 parent 6a4a66e commit d94c3ce

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

lightning/src/ln/outbound_payment.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::ln::onion_utils::{DecodedOnionFailure, HTLCFailReason};
2424
use crate::offers::invoice::Bolt12Invoice;
2525
use crate::offers::invoice_request::InvoiceRequest;
2626
use crate::offers::nonce::Nonce;
27-
use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, PaymentParameters, Route, RouteParameters, Router};
27+
use crate::routing::router::{BlindedTail, InFlightHtlcs, Path, PaymentParameters, Route, RouteParameters, Router, UserParameters};
2828
use crate::sign::{EntropySource, NodeSigner, Recipient};
2929
use crate::util::errors::APIError;
3030
use crate::util::logger::Logger;
@@ -61,7 +61,11 @@ pub(crate) enum PendingOutboundPayment {
6161
AwaitingInvoice {
6262
expiration: StaleExpiration,
6363
retry_strategy: Retry,
64+
// Deprecated: Retained for backward compatibility.
65+
// If set during read, this field overrides `RouteParameters::max_total_routing_fee_msat`
66+
// instead of `RouteParametersOverride::max_total_routing_fee_msat`.
6467
max_total_routing_fee_msat: Option<u64>,
68+
user_params: UserParameters,
6569
retryable_invoice_request: Option<RetryableInvoiceRequest>
6670
},
6771
// This state will never be persisted to disk because we transition from `AwaitingInvoice` to
@@ -70,9 +74,10 @@ pub(crate) enum PendingOutboundPayment {
7074
InvoiceReceived {
7175
payment_hash: PaymentHash,
7276
retry_strategy: Retry,
73-
// Note this field is currently just replicated from AwaitingInvoice but not actually
74-
// used anywhere.
75-
max_total_routing_fee_msat: Option<u64>,
77+
// Currently unused, but replicated from `AwaitingInvoice` to avoid potential
78+
// race conditions where this field might be missing upon reload. It may be required
79+
// for future retries.
80+
user_params: UserParameters,
7681
},
7782
// This state applies when we are paying an often-offline recipient and another node on the
7883
// network served us a static invoice on the recipient's behalf in response to our invoice
@@ -849,14 +854,20 @@ impl OutboundPayments {
849854
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
850855
hash_map::Entry::Occupied(entry) => match entry.get() {
851856
PendingOutboundPayment::AwaitingInvoice {
852-
retry_strategy: retry, max_total_routing_fee_msat: max_total_fee, ..
857+
retry_strategy: retry, max_total_routing_fee_msat: max_total_fee, user_params, ..
853858
} => {
854859
retry_strategy = *retry;
855-
max_total_routing_fee_msat = *max_total_fee;
860+
// If max_total_fee is present, update route_params_override with the specified fee.
861+
// This supports the standard behavior during downgrades.
862+
let user_params = max_total_fee
863+
.map_or(*user_params, |fee| user_params.with_max_total_routing_fee_msat(fee));
864+
865+
max_total_routing_fee_msat = user_params.max_total_routing_fee_msat;
866+
856867
*entry.into_mut() = PendingOutboundPayment::InvoiceReceived {
857868
payment_hash,
858869
retry_strategy: *retry,
859-
max_total_routing_fee_msat,
870+
user_params,
860871
};
861872
},
862873
_ => return Err(Bolt12PaymentError::DuplicateInvoice),
@@ -1004,7 +1015,7 @@ impl OutboundPayments {
10041015
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
10051016
hash_map::Entry::Occupied(mut entry) => match entry.get() {
10061017
PendingOutboundPayment::AwaitingInvoice {
1007-
retry_strategy, retryable_invoice_request, max_total_routing_fee_msat, ..
1018+
retry_strategy, retryable_invoice_request, route_params_override, ..
10081019
} => {
10091020
let invreq = &retryable_invoice_request
10101021
.as_ref()
@@ -1031,7 +1042,7 @@ impl OutboundPayments {
10311042
let payment_hash = PaymentHash(Sha256::hash(&keysend_preimage.0).to_byte_array());
10321043
let pay_params = PaymentParameters::from_static_invoice(invoice);
10331044
let mut route_params = RouteParameters::from_payment_params_and_value(pay_params, amount_msat);
1034-
route_params.max_total_routing_fee_msat = *max_total_routing_fee_msat;
1045+
route_params.max_total_routing_fee_msat = route_params_override.map(|params| params.max_total_routing_fee_msat).flatten();
10351046

10361047
if let Err(()) = onion_utils::set_max_path_length(
10371048
&mut route_params, &RecipientOnionFields::spontaneous_empty(), Some(keysend_preimage),
@@ -1599,6 +1610,10 @@ impl OutboundPayments {
15991610
max_total_routing_fee_msat: Option<u64>, retryable_invoice_request: Option<RetryableInvoiceRequest>
16001611
) -> Result<(), ()> {
16011612
let mut pending_outbounds = self.pending_outbound_payments.lock().unwrap();
1613+
let user_params = max_total_routing_fee_msat.map_or(UserParameters::new(),
1614+
|fee_msats| UserParameters::new()
1615+
.with_max_total_routing_fee_msat(fee_msats)
1616+
);
16021617
match pending_outbounds.entry(payment_id) {
16031618
hash_map::Entry::Occupied(_) => Err(()),
16041619
hash_map::Entry::Vacant(entry) => {
@@ -1608,7 +1623,9 @@ impl OutboundPayments {
16081623
entry.insert(PendingOutboundPayment::AwaitingInvoice {
16091624
expiration,
16101625
retry_strategy,
1611-
max_total_routing_fee_msat,
1626+
user_params,
1627+
// Retained for downgrade support.
1628+
max_total_routing_fee_msat: None,
16121629
retryable_invoice_request,
16131630
});
16141631

@@ -2240,11 +2257,12 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22402257
(2, retry_strategy, required),
22412258
(4, max_total_routing_fee_msat, option),
22422259
(5, retryable_invoice_request, option),
2260+
(6, user_params, (default_value, UserParameters::new())),
22432261
},
22442262
(7, InvoiceReceived) => {
22452263
(0, payment_hash, required),
22462264
(2, retry_strategy, required),
2247-
(4, max_total_routing_fee_msat, option),
2265+
(4, user_params, (default_value, UserParameters::new())),
22482266
},
22492267
// Added in 0.0.125. Prior versions will drop these outbounds on downgrade, which is safe because
22502268
// no HTLCs are in-flight.

0 commit comments

Comments
 (0)