@@ -24,7 +24,7 @@ use crate::ln::onion_utils::{DecodedOnionFailure, HTLCFailReason};
24
24
use crate :: offers:: invoice:: Bolt12Invoice ;
25
25
use crate :: offers:: invoice_request:: InvoiceRequest ;
26
26
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 } ;
28
28
use crate :: sign:: { EntropySource , NodeSigner , Recipient } ;
29
29
use crate :: util:: errors:: APIError ;
30
30
use crate :: util:: logger:: Logger ;
@@ -62,15 +62,15 @@ pub(crate) enum PendingOutboundPayment {
62
62
AwaitingOffer {
63
63
expiration : StaleExpiration ,
64
64
retry_strategy : Retry ,
65
- max_total_routing_fee_msat : Option < u64 > ,
65
+ route_params_config : RouteParametersConfig ,
66
66
/// Human Readable Names-originated payments should always specify an explicit amount to
67
67
/// send up-front, which we track here and enforce once we receive the offer.
68
68
amount_msats : u64 ,
69
69
} ,
70
70
AwaitingInvoice {
71
71
expiration : StaleExpiration ,
72
72
retry_strategy : Retry ,
73
- max_total_routing_fee_msat : Option < u64 > ,
73
+ route_params_config : RouteParametersConfig ,
74
74
retryable_invoice_request : Option < RetryableInvoiceRequest >
75
75
} ,
76
76
// This state will never be persisted to disk because we transition from `AwaitingInvoice` to
@@ -79,9 +79,10 @@ pub(crate) enum PendingOutboundPayment {
79
79
InvoiceReceived {
80
80
payment_hash : PaymentHash ,
81
81
retry_strategy : Retry ,
82
- // Note this field is currently just replicated from AwaitingInvoice but not actually
83
- // used anywhere.
84
- max_total_routing_fee_msat : Option < u64 > ,
82
+ // Currently unused, but replicated from `AwaitingInvoice` to avoid potential
83
+ // race conditions where this field might be missing upon reload. It may be required
84
+ // for future retries.
85
+ route_params_config : RouteParametersConfig ,
85
86
} ,
86
87
// This state applies when we are paying an often-offline recipient and another node on the
87
88
// network served us a static invoice on the recipient's behalf in response to our invoice
@@ -867,14 +868,14 @@ impl OutboundPayments {
867
868
match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
868
869
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
869
870
PendingOutboundPayment :: AwaitingInvoice {
870
- retry_strategy : retry, max_total_routing_fee_msat : max_total_fee , ..
871
+ retry_strategy : retry, route_params_config , ..
871
872
} => {
872
873
retry_strategy = * retry;
873
- max_total_routing_fee_msat = * max_total_fee ;
874
+ max_total_routing_fee_msat = route_params_config . max_total_routing_fee_msat ;
874
875
* entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
875
876
payment_hash,
876
877
retry_strategy : * retry,
877
- max_total_routing_fee_msat ,
878
+ route_params_config : * route_params_config ,
878
879
} ;
879
880
} ,
880
881
_ => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
@@ -1035,7 +1036,7 @@ impl OutboundPayments {
1035
1036
match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
1036
1037
hash_map:: Entry :: Occupied ( mut entry) => match entry. get_mut ( ) {
1037
1038
PendingOutboundPayment :: AwaitingInvoice {
1038
- retry_strategy, retryable_invoice_request, max_total_routing_fee_msat , ..
1039
+ retry_strategy, retryable_invoice_request, route_params_config , ..
1039
1040
} => {
1040
1041
let invreq = & retryable_invoice_request
1041
1042
. as_ref ( )
@@ -1067,7 +1068,7 @@ impl OutboundPayments {
1067
1068
let payment_hash = PaymentHash ( Sha256 :: hash ( & keysend_preimage. 0 ) . to_byte_array ( ) ) ;
1068
1069
let pay_params = PaymentParameters :: from_static_invoice ( invoice) ;
1069
1070
let mut route_params = RouteParameters :: from_payment_params_and_value ( pay_params, amount_msat) ;
1070
- route_params. max_total_routing_fee_msat = * max_total_routing_fee_msat;
1071
+ route_params. max_total_routing_fee_msat = route_params_config . max_total_routing_fee_msat ;
1071
1072
1072
1073
if let Err ( ( ) ) = onion_utils:: set_max_path_length (
1073
1074
& mut route_params, & RecipientOnionFields :: spontaneous_empty ( ) , Some ( keysend_preimage) ,
@@ -1713,13 +1714,17 @@ impl OutboundPayments {
1713
1714
max_total_routing_fee_msat : Option < u64 > , amount_msats : u64 ,
1714
1715
) -> Result < ( ) , ( ) > {
1715
1716
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1717
+ let route_params_config = max_total_routing_fee_msat. map_or (
1718
+ RouteParametersConfig :: default ( ) ,
1719
+ |fee_msat| RouteParametersConfig :: default ( ) . with_max_total_routing_fee_msat ( fee_msat)
1720
+ ) ;
1716
1721
match pending_outbounds. entry ( payment_id) {
1717
1722
hash_map:: Entry :: Occupied ( _) => Err ( ( ) ) ,
1718
1723
hash_map:: Entry :: Vacant ( entry) => {
1719
1724
entry. insert ( PendingOutboundPayment :: AwaitingOffer {
1720
1725
expiration,
1721
1726
retry_strategy,
1722
- max_total_routing_fee_msat ,
1727
+ route_params_config ,
1723
1728
amount_msats,
1724
1729
} ) ;
1725
1730
@@ -1746,12 +1751,12 @@ impl OutboundPayments {
1746
1751
match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
1747
1752
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
1748
1753
PendingOutboundPayment :: AwaitingOffer {
1749
- expiration, retry_strategy, max_total_routing_fee_msat , ..
1754
+ expiration, retry_strategy, route_params_config , ..
1750
1755
} => {
1751
1756
let mut new_val = PendingOutboundPayment :: AwaitingInvoice {
1752
1757
expiration : * expiration,
1753
1758
retry_strategy : * retry_strategy,
1754
- max_total_routing_fee_msat : * max_total_routing_fee_msat ,
1759
+ route_params_config : * route_params_config ,
1755
1760
retryable_invoice_request,
1756
1761
} ;
1757
1762
core:: mem:: swap ( & mut new_val, entry. into_mut ( ) ) ;
@@ -1768,6 +1773,11 @@ impl OutboundPayments {
1768
1773
max_total_routing_fee_msat : Option < u64 > , retryable_invoice_request : Option < RetryableInvoiceRequest >
1769
1774
) -> Result < ( ) , ( ) > {
1770
1775
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1776
+ let route_params_config = max_total_routing_fee_msat. map_or (
1777
+ RouteParametersConfig :: default ( ) ,
1778
+ |fee_msats| RouteParametersConfig :: default ( )
1779
+ . with_max_total_routing_fee_msat ( fee_msats)
1780
+ ) ;
1771
1781
match pending_outbounds. entry ( payment_id) {
1772
1782
hash_map:: Entry :: Occupied ( _) => Err ( ( ) ) ,
1773
1783
hash_map:: Entry :: Vacant ( entry) => {
@@ -1777,7 +1787,7 @@ impl OutboundPayments {
1777
1787
entry. insert ( PendingOutboundPayment :: AwaitingInvoice {
1778
1788
expiration,
1779
1789
retry_strategy,
1780
- max_total_routing_fee_msat ,
1790
+ route_params_config ,
1781
1791
retryable_invoice_request,
1782
1792
} ) ;
1783
1793
@@ -2411,13 +2421,35 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
2411
2421
( 5 , AwaitingInvoice ) => {
2412
2422
( 0 , expiration, required) ,
2413
2423
( 2 , retry_strategy, required) ,
2414
- ( 4 , max_total_routing_fee_msat, option) ,
2424
+ ( 4 , _max_total_routing_fee_msat, ( legacy, u64 ,
2425
+ |us: & PendingOutboundPayment | match us {
2426
+ PendingOutboundPayment :: AwaitingInvoice { route_params_config, .. } => route_params_config. max_total_routing_fee_msat,
2427
+ _ => None ,
2428
+ }
2429
+ ) ) ,
2415
2430
( 5 , retryable_invoice_request, option) ,
2431
+ ( 7 , route_params_config, ( default_value, (
2432
+ _max_total_routing_fee_msat. map_or(
2433
+ RouteParametersConfig :: default ( ) ,
2434
+ |fee_msat| RouteParametersConfig :: default ( ) . with_max_total_routing_fee_msat( fee_msat)
2435
+ )
2436
+ ) ) ) ,
2416
2437
} ,
2417
2438
( 7 , InvoiceReceived ) => {
2418
2439
( 0 , payment_hash, required) ,
2419
2440
( 2 , retry_strategy, required) ,
2420
- ( 4 , max_total_routing_fee_msat, option) ,
2441
+ ( 4 , _max_total_routing_fee_msat, ( legacy, u64 ,
2442
+ |us: & PendingOutboundPayment | match us {
2443
+ PendingOutboundPayment :: InvoiceReceived { route_params_config, .. } => route_params_config. max_total_routing_fee_msat,
2444
+ _ => None ,
2445
+ }
2446
+ ) ) ,
2447
+ ( 5 , route_params_config, ( default_value, (
2448
+ _max_total_routing_fee_msat. map_or(
2449
+ RouteParametersConfig :: default ( ) ,
2450
+ |fee_msat| RouteParametersConfig :: default ( ) . with_max_total_routing_fee_msat( fee_msat)
2451
+ )
2452
+ ) ) ) ,
2421
2453
} ,
2422
2454
// Added in 0.1. Prior versions will drop these outbounds on downgrade, which is safe because no
2423
2455
// HTLCs are in-flight.
@@ -2433,7 +2465,18 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
2433
2465
( 11 , AwaitingOffer ) => {
2434
2466
( 0 , expiration, required) ,
2435
2467
( 2 , retry_strategy, required) ,
2436
- ( 4 , max_total_routing_fee_msat, option) ,
2468
+ ( 4 , _max_total_routing_fee_msat, ( legacy, u64 ,
2469
+ |us: & PendingOutboundPayment | match us {
2470
+ PendingOutboundPayment :: AwaitingOffer { route_params_config, .. } => route_params_config. max_total_routing_fee_msat,
2471
+ _ => None ,
2472
+ }
2473
+ ) ) ,
2474
+ ( 5 , route_params_config, ( default_value, (
2475
+ _max_total_routing_fee_msat. map_or(
2476
+ RouteParametersConfig :: default ( ) ,
2477
+ |fee_msat| RouteParametersConfig :: default ( ) . with_max_total_routing_fee_msat( fee_msat)
2478
+ )
2479
+ ) ) ) ,
2437
2480
( 6 , amount_msats, required) ,
2438
2481
} ,
2439
2482
) ;
0 commit comments