@@ -54,10 +54,14 @@ pub(crate) enum PendingOutboundPayment {
54
54
AwaitingInvoice {
55
55
timer_ticks_without_response : u8 ,
56
56
retry_strategy : Retry ,
57
+ max_total_routing_fee_msat : Option < u64 > ,
57
58
} ,
58
59
InvoiceReceived {
59
60
payment_hash : PaymentHash ,
60
61
retry_strategy : Retry ,
62
+ // Note this field is currently just replicated from AwaitingInvoice but not actually
63
+ // used anywhere.
64
+ max_total_routing_fee_msat : Option < u64 > ,
61
65
} ,
62
66
Retryable {
63
67
retry_strategy : Option < Retry > ,
@@ -76,6 +80,7 @@ pub(crate) enum PendingOutboundPayment {
76
80
total_msat : u64 ,
77
81
/// Our best known block height at the time this payment was initiated.
78
82
starting_block_height : u32 ,
83
+ remaining_max_total_routing_fee_msat : Option < u64 > ,
79
84
} ,
80
85
/// When a pending payment is fulfilled, we continue tracking it until all pending HTLCs have
81
86
/// been resolved. This ensures we don't look up pending payments in ChannelMonitors on restart
@@ -731,12 +736,15 @@ impl OutboundPayments {
731
736
SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
732
737
{
733
738
let payment_hash = invoice. payment_hash ( ) ;
739
+ let mut max_total_routing_fee_msat = None ;
734
740
match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
735
741
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
736
- PendingOutboundPayment :: AwaitingInvoice { retry_strategy, .. } => {
742
+ PendingOutboundPayment :: AwaitingInvoice { retry_strategy, max_total_routing_fee_msat : max_total_fee, .. } => {
743
+ max_total_routing_fee_msat = * max_total_fee;
737
744
* entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
738
745
payment_hash,
739
746
retry_strategy : * retry_strategy,
747
+ max_total_routing_fee_msat,
740
748
} ;
741
749
} ,
742
750
_ => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
@@ -747,6 +755,7 @@ impl OutboundPayments {
747
755
let route_params = RouteParameters {
748
756
payment_params : PaymentParameters :: from_bolt12_invoice ( & invoice) ,
749
757
final_value_msat : invoice. amount_msats ( ) ,
758
+ max_total_routing_fee_msat,
750
759
} ;
751
760
752
761
self . find_route_and_send_payment (
@@ -779,11 +788,12 @@ impl OutboundPayments {
779
788
let mut retry_id_route_params = None ;
780
789
for ( pmt_id, pmt) in outbounds. iter_mut ( ) {
781
790
if pmt. is_auto_retryable_now ( ) {
782
- if let PendingOutboundPayment :: Retryable { pending_amt_msat, total_msat, payment_params : Some ( params) , payment_hash, .. } = pmt {
791
+ if let PendingOutboundPayment :: Retryable { pending_amt_msat, total_msat, payment_params : Some ( params) , payment_hash, remaining_max_total_routing_fee_msat , .. } = pmt {
783
792
if pending_amt_msat < total_msat {
784
793
retry_id_route_params = Some ( ( * payment_hash, * pmt_id, RouteParameters {
785
794
final_value_msat : * total_msat - * pending_amt_msat,
786
795
payment_params : params. clone ( ) ,
796
+ max_total_routing_fee_msat : * remaining_max_total_routing_fee_msat,
787
797
} ) ) ;
788
798
break
789
799
}
@@ -987,7 +997,7 @@ impl OutboundPayments {
987
997
log_error ! ( logger, "Payment not yet sent" ) ;
988
998
return
989
999
} ,
990
- PendingOutboundPayment :: InvoiceReceived { payment_hash, retry_strategy } => {
1000
+ PendingOutboundPayment :: InvoiceReceived { payment_hash, retry_strategy, .. } => {
991
1001
let total_amount = route_params. final_value_msat ;
992
1002
let recipient_onion = RecipientOnionFields {
993
1003
payment_secret : None ,
@@ -1207,6 +1217,8 @@ impl OutboundPayments {
1207
1217
custom_tlvs : recipient_onion. custom_tlvs ,
1208
1218
starting_block_height : best_block_height,
1209
1219
total_msat : route. get_total_amount ( ) ,
1220
+ remaining_max_total_routing_fee_msat :
1221
+ route. route_params . as_ref ( ) . and_then ( |p| p. max_total_routing_fee_msat ) ,
1210
1222
} ;
1211
1223
1212
1224
for ( path, session_priv_bytes) in route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) {
@@ -1218,7 +1230,7 @@ impl OutboundPayments {
1218
1230
1219
1231
#[ allow( unused) ]
1220
1232
pub ( super ) fn add_new_awaiting_invoice (
1221
- & self , payment_id : PaymentId , retry_strategy : Retry
1233
+ & self , payment_id : PaymentId , retry_strategy : Retry , max_total_routing_fee_msat : Option < u64 >
1222
1234
) -> Result < ( ) , ( ) > {
1223
1235
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1224
1236
match pending_outbounds. entry ( payment_id) {
@@ -1227,6 +1239,7 @@ impl OutboundPayments {
1227
1239
entry. insert ( PendingOutboundPayment :: AwaitingInvoice {
1228
1240
timer_ticks_without_response : 0 ,
1229
1241
retry_strategy,
1242
+ max_total_routing_fee_msat,
1230
1243
} ) ;
1231
1244
1232
1245
Ok ( ( ) )
@@ -1328,8 +1341,9 @@ impl OutboundPayments {
1328
1341
failed_paths_retry : if pending_amt_unsent != 0 {
1329
1342
if let Some ( payment_params) = route. route_params . as_ref ( ) . map ( |p| p. payment_params . clone ( ) ) {
1330
1343
Some ( RouteParameters {
1331
- payment_params : payment_params ,
1344
+ payment_params,
1332
1345
final_value_msat : pending_amt_unsent,
1346
+ max_total_routing_fee_msat : None ,
1333
1347
} )
1334
1348
} else { None }
1335
1349
} else { None } ,
@@ -1689,6 +1703,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
1689
1703
( 8 , pending_amt_msat, required) ,
1690
1704
( 9 , custom_tlvs, optional_vec) ,
1691
1705
( 10 , starting_block_height, required) ,
1706
+ ( 11 , remaining_max_total_routing_fee_msat, option) ,
1692
1707
( not_written, retry_strategy, ( static_value, None ) ) ,
1693
1708
( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
1694
1709
} ,
@@ -1700,10 +1715,12 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
1700
1715
( 5 , AwaitingInvoice ) => {
1701
1716
( 0 , timer_ticks_without_response, required) ,
1702
1717
( 2 , retry_strategy, required) ,
1718
+ ( 4 , max_total_routing_fee_msat, option) ,
1703
1719
} ,
1704
1720
( 7 , InvoiceReceived ) => {
1705
1721
( 0 , payment_hash, required) ,
1706
1722
( 2 , retry_strategy, required) ,
1723
+ ( 4 , max_total_routing_fee_msat, option) ,
1707
1724
} ,
1708
1725
) ;
1709
1726
@@ -1926,7 +1943,9 @@ mod tests {
1926
1943
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1927
1944
1928
1945
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
1929
- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
1946
+ assert ! (
1947
+ outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) , None ) . is_ok( )
1948
+ ) ;
1930
1949
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1931
1950
1932
1951
for _ in 0 ..INVOICE_REQUEST_TIMEOUT_TICKS {
@@ -1944,10 +1963,15 @@ mod tests {
1944
1963
) ;
1945
1964
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
1946
1965
1947
- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
1966
+ assert ! (
1967
+ outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) , None ) . is_ok( )
1968
+ ) ;
1948
1969
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1949
1970
1950
- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_err( ) ) ;
1971
+ assert ! (
1972
+ outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) , None )
1973
+ . is_err( )
1974
+ ) ;
1951
1975
}
1952
1976
1953
1977
#[ test]
@@ -1957,7 +1981,9 @@ mod tests {
1957
1981
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1958
1982
1959
1983
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
1960
- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
1984
+ assert ! (
1985
+ outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) , None ) . is_ok( )
1986
+ ) ;
1961
1987
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1962
1988
1963
1989
outbound_payments. abandon_payment (
@@ -1985,7 +2011,9 @@ mod tests {
1985
2011
let outbound_payments = OutboundPayments :: new ( ) ;
1986
2012
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1987
2013
1988
- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
2014
+ assert ! (
2015
+ outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) , None ) . is_ok( )
2016
+ ) ;
1989
2017
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1990
2018
1991
2019
let created_at = now ( ) - DEFAULT_RELATIVE_EXPIRY ;
@@ -2031,7 +2059,9 @@ mod tests {
2031
2059
let outbound_payments = OutboundPayments :: new ( ) ;
2032
2060
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
2033
2061
2034
- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
2062
+ assert ! (
2063
+ outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) , None ) . is_ok( )
2064
+ ) ;
2035
2065
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2036
2066
2037
2067
let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2045,10 +2075,10 @@ mod tests {
2045
2075
. sign ( recipient_sign) . unwrap ( ) ;
2046
2076
2047
2077
router. expect_find_route (
2048
- RouteParameters {
2049
- payment_params : PaymentParameters :: from_bolt12_invoice ( & invoice) ,
2050
- final_value_msat : invoice. amount_msats ( ) ,
2051
- } ,
2078
+ RouteParameters :: from_payment_params_and_value (
2079
+ PaymentParameters :: from_bolt12_invoice ( & invoice) ,
2080
+ invoice. amount_msats ( ) ,
2081
+ ) ,
2052
2082
Err ( LightningError { err : String :: new ( ) , action : ErrorAction :: IgnoreError } ) ,
2053
2083
) ;
2054
2084
@@ -2084,7 +2114,9 @@ mod tests {
2084
2114
let outbound_payments = OutboundPayments :: new ( ) ;
2085
2115
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
2086
2116
2087
- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
2117
+ assert ! (
2118
+ outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) , None ) . is_ok( )
2119
+ ) ;
2088
2120
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2089
2121
2090
2122
let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2097,10 +2129,10 @@ mod tests {
2097
2129
. build ( ) . unwrap ( )
2098
2130
. sign ( recipient_sign) . unwrap ( ) ;
2099
2131
2100
- let route_params = RouteParameters {
2101
- payment_params : PaymentParameters :: from_bolt12_invoice ( & invoice) ,
2102
- final_value_msat : invoice. amount_msats ( ) ,
2103
- } ;
2132
+ let route_params = RouteParameters :: from_payment_params_and_value (
2133
+ PaymentParameters :: from_bolt12_invoice ( & invoice) ,
2134
+ invoice. amount_msats ( ) ,
2135
+ ) ;
2104
2136
router. expect_find_route (
2105
2137
route_params. clone ( ) , Ok ( Route { paths : vec ! [ ] , route_params : Some ( route_params) } )
2106
2138
) ;
@@ -2150,6 +2182,7 @@ mod tests {
2150
2182
let route_params = RouteParameters {
2151
2183
payment_params : PaymentParameters :: from_bolt12_invoice ( & invoice) ,
2152
2184
final_value_msat : invoice. amount_msats ( ) ,
2185
+ max_total_routing_fee_msat : Some ( 1234 ) ,
2153
2186
} ;
2154
2187
router. expect_find_route (
2155
2188
route_params. clone ( ) ,
@@ -2185,7 +2218,9 @@ mod tests {
2185
2218
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
2186
2219
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
2187
2220
2188
- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
2221
+ assert ! (
2222
+ outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) , Some ( 1234 ) ) . is_ok( )
2223
+ ) ;
2189
2224
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2190
2225
2191
2226
assert_eq ! (
0 commit comments