Skip to content

Commit b42b3c7

Browse files
committed
Update AwaitingInvoice to include RouteParametersOverride
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 `ManualRoutingParameters` 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 `route_params_override` 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 adba982 commit b42b3c7

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

lightning/src/ln/outbound_payment.rs

+32-11
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, RouteParametersOverride, Path, PaymentParameters, Route, RouteParameters, Router};
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+
route_params_override: Option<RouteParametersOverride>,
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+
route_params_override: Option<RouteParametersOverride>,
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,23 @@ 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, route_params_override, ..
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 route_params_override = max_total_fee.map_or(*route_params_override, |fee_msat| {
863+
route_params_override.map(|params_override|
864+
params_override.with_max_total_routing_fee_msat(fee_msat)
865+
).or_else(|| Some(RouteParametersOverride::new().with_max_total_routing_fee_msat(fee_msat)))
866+
});
867+
max_total_routing_fee_msat = route_params_override.and_then(
868+
|params| params.max_total_routing_fee_msat
869+
);
856870
*entry.into_mut() = PendingOutboundPayment::InvoiceReceived {
857871
payment_hash,
858872
retry_strategy: *retry,
859-
max_total_routing_fee_msat,
873+
route_params_override: route_params_override,
860874
};
861875
},
862876
_ => return Err(Bolt12PaymentError::DuplicateInvoice),
@@ -1004,7 +1018,7 @@ impl OutboundPayments {
10041018
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
10051019
hash_map::Entry::Occupied(mut entry) => match entry.get() {
10061020
PendingOutboundPayment::AwaitingInvoice {
1007-
retry_strategy, retryable_invoice_request, max_total_routing_fee_msat, ..
1021+
retry_strategy, retryable_invoice_request, route_params_override, ..
10081022
} => {
10091023
let invreq = &retryable_invoice_request
10101024
.as_ref()
@@ -1031,7 +1045,7 @@ impl OutboundPayments {
10311045
let payment_hash = PaymentHash(Sha256::hash(&keysend_preimage.0).to_byte_array());
10321046
let pay_params = PaymentParameters::from_static_invoice(invoice);
10331047
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;
1048+
route_params.max_total_routing_fee_msat = route_params_override.map(|params| params.max_total_routing_fee_msat).flatten();
10351049

10361050
if let Err(()) = onion_utils::set_max_path_length(
10371051
&mut route_params, &RecipientOnionFields::spontaneous_empty(), Some(keysend_preimage),
@@ -1599,6 +1613,10 @@ impl OutboundPayments {
15991613
max_total_routing_fee_msat: Option<u64>, retryable_invoice_request: Option<RetryableInvoiceRequest>
16001614
) -> Result<(), ()> {
16011615
let mut pending_outbounds = self.pending_outbound_payments.lock().unwrap();
1616+
let route_params_override = max_total_routing_fee_msat.map(
1617+
|fee_msats| RouteParametersOverride::new()
1618+
.with_max_total_routing_fee_msat(fee_msats)
1619+
);
16021620
match pending_outbounds.entry(payment_id) {
16031621
hash_map::Entry::Occupied(_) => Err(()),
16041622
hash_map::Entry::Vacant(entry) => {
@@ -1608,7 +1626,9 @@ impl OutboundPayments {
16081626
entry.insert(PendingOutboundPayment::AwaitingInvoice {
16091627
expiration,
16101628
retry_strategy,
1611-
max_total_routing_fee_msat,
1629+
route_params_override,
1630+
// Retained for downgrade support.
1631+
max_total_routing_fee_msat: None,
16121632
retryable_invoice_request,
16131633
});
16141634

@@ -2240,11 +2260,12 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22402260
(2, retry_strategy, required),
22412261
(4, max_total_routing_fee_msat, option),
22422262
(5, retryable_invoice_request, option),
2263+
(7, route_params_override, option),
22432264
},
22442265
(7, InvoiceReceived) => {
22452266
(0, payment_hash, required),
22462267
(2, retry_strategy, required),
2247-
(4, max_total_routing_fee_msat, option),
2268+
(3, route_params_override, option),
22482269
},
22492270
// Added in 0.0.125. Prior versions will drop these outbounds on downgrade, which is safe because
22502271
// no HTLCs are in-flight.

0 commit comments

Comments
 (0)