Skip to content

Commit 8dc49f2

Browse files
committed
Update AwaitingInvoice to include RouteParametersConfig
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 `RouteParametersConfig` 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` & `InvoiceReceived`** This field is retained to ensure downgrade support. 2. **Introduction of `route_params_config` 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 4d587ae commit 8dc49f2

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

lightning/src/ln/outbound_payment.rs

+29-9
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, RouteParametersConfig, 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 `RouteParametersConfig::max_total_routing_fee_msat`.
6467
max_total_routing_fee_msat: Option<u64>,
68+
route_params_config: RouteParametersConfig,
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,12 @@ 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.
77+
// Deprecated: Retained for backward compatibility.
7578
max_total_routing_fee_msat: Option<u64>,
79+
// Currently unused, but replicated from `AwaitingInvoice` to avoid potential
80+
// race conditions where this field might be missing upon reload. It may be required
81+
// for future retries.
82+
route_params_config: RouteParametersConfig,
7683
},
7784
// This state applies when we are paying an often-offline recipient and another node on the
7885
// network served us a static invoice on the recipient's behalf in response to our invoice
@@ -849,14 +856,18 @@ impl OutboundPayments {
849856
match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
850857
hash_map::Entry::Occupied(entry) => match entry.get() {
851858
PendingOutboundPayment::AwaitingInvoice {
852-
retry_strategy: retry, max_total_routing_fee_msat: max_total_fee, ..
859+
retry_strategy: retry, max_total_routing_fee_msat: max_total_fee, route_params_config, ..
853860
} => {
854861
retry_strategy = *retry;
855-
max_total_routing_fee_msat = *max_total_fee;
862+
// If max_total_fee is present, update route_params_config with the specified fee.
863+
// This supports the standard behavior during downgrades.
864+
let route_params_config = max_total_fee.map_or(*route_params_config, |fee_msat| route_params_config.with_max_total_routing_fee_msat(fee_msat));
865+
max_total_routing_fee_msat = route_params_config.max_total_routing_fee_msat;
856866
*entry.into_mut() = PendingOutboundPayment::InvoiceReceived {
857867
payment_hash,
858868
retry_strategy: *retry,
859-
max_total_routing_fee_msat,
869+
max_total_routing_fee_msat: *max_total_fee,
870+
route_params_config: route_params_config,
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_config, ..
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_config.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,11 @@ 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 route_params_config = max_total_routing_fee_msat.map_or(
1614+
RouteParametersConfig::new(),
1615+
|fee_msats| RouteParametersConfig::new()
1616+
.with_max_total_routing_fee_msat(fee_msats)
1617+
);
16021618
match pending_outbounds.entry(payment_id) {
16031619
hash_map::Entry::Occupied(_) => Err(()),
16041620
hash_map::Entry::Vacant(entry) => {
@@ -1608,7 +1624,9 @@ impl OutboundPayments {
16081624
entry.insert(PendingOutboundPayment::AwaitingInvoice {
16091625
expiration,
16101626
retry_strategy,
1611-
max_total_routing_fee_msat,
1627+
route_params_config,
1628+
// Retained for downgrade support.
1629+
max_total_routing_fee_msat: None,
16121630
retryable_invoice_request,
16131631
});
16141632

@@ -2240,10 +2258,12 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22402258
(2, retry_strategy, required),
22412259
(4, max_total_routing_fee_msat, option),
22422260
(5, retryable_invoice_request, option),
2261+
(7, route_params_config, (default_value, RouteParametersConfig::new())),
22432262
},
22442263
(7, InvoiceReceived) => {
22452264
(0, payment_hash, required),
22462265
(2, retry_strategy, required),
2266+
(3, route_params_config, (default_value, RouteParametersConfig::new())),
22472267
(4, max_total_routing_fee_msat, option),
22482268
},
22492269
// Added in 0.0.125. Prior versions will drop these outbounds on downgrade, which is safe because

0 commit comments

Comments
 (0)