@@ -54,10 +54,14 @@ pub(crate) enum PendingOutboundPayment {
5454 AwaitingInvoice {
5555 timer_ticks_without_response : u8 ,
5656 retry_strategy : Retry ,
57+ max_total_routing_fee_msat : Option < u64 > ,
5758 } ,
5859 InvoiceReceived {
5960 payment_hash : PaymentHash ,
6061 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 > ,
6165 } ,
6266 Retryable {
6367 retry_strategy : Option < Retry > ,
@@ -76,6 +80,7 @@ pub(crate) enum PendingOutboundPayment {
7680 total_msat : u64 ,
7781 /// Our best known block height at the time this payment was initiated.
7882 starting_block_height : u32 ,
83+ remaining_max_total_routing_fee_msat : Option < u64 > ,
7984 } ,
8085 /// When a pending payment is fulfilled, we continue tracking it until all pending HTLCs have
8186 /// been resolved. This ensures we don't look up pending payments in ChannelMonitors on restart
@@ -731,12 +736,15 @@ impl OutboundPayments {
731736 SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
732737 {
733738 let payment_hash = invoice. payment_hash ( ) ;
739+ let mut max_total_routing_fee_msat = None ;
734740 match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
735741 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;
737744 * entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
738745 payment_hash,
739746 retry_strategy : * retry_strategy,
747+ max_total_routing_fee_msat,
740748 } ;
741749 } ,
742750 _ => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
@@ -747,6 +755,7 @@ impl OutboundPayments {
747755 let route_params = RouteParameters {
748756 payment_params : PaymentParameters :: from_bolt12_invoice ( & invoice) ,
749757 final_value_msat : invoice. amount_msats ( ) ,
758+ max_total_routing_fee_msat,
750759 } ;
751760
752761 self . find_route_and_send_payment (
@@ -779,11 +788,12 @@ impl OutboundPayments {
779788 let mut retry_id_route_params = None ;
780789 for ( pmt_id, pmt) in outbounds. iter_mut ( ) {
781790 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 {
783792 if pending_amt_msat < total_msat {
784793 retry_id_route_params = Some ( ( * payment_hash, * pmt_id, RouteParameters {
785794 final_value_msat : * total_msat - * pending_amt_msat,
786795 payment_params : params. clone ( ) ,
796+ max_total_routing_fee_msat : * remaining_max_total_routing_fee_msat,
787797 } ) ) ;
788798 break
789799 }
@@ -987,7 +997,7 @@ impl OutboundPayments {
987997 log_error ! ( logger, "Payment not yet sent" ) ;
988998 return
989999 } ,
990- PendingOutboundPayment :: InvoiceReceived { payment_hash, retry_strategy } => {
1000+ PendingOutboundPayment :: InvoiceReceived { payment_hash, retry_strategy, .. } => {
9911001 let total_amount = route_params. final_value_msat ;
9921002 let recipient_onion = RecipientOnionFields {
9931003 payment_secret : None ,
@@ -1207,6 +1217,8 @@ impl OutboundPayments {
12071217 custom_tlvs : recipient_onion. custom_tlvs ,
12081218 starting_block_height : best_block_height,
12091219 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 ) ,
12101222 } ;
12111223
12121224 for ( path, session_priv_bytes) in route. paths . iter ( ) . zip ( onion_session_privs. iter ( ) ) {
@@ -1218,7 +1230,7 @@ impl OutboundPayments {
12181230
12191231 #[ allow( unused) ]
12201232 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 >
12221234 ) -> Result < ( ) , ( ) > {
12231235 let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
12241236 match pending_outbounds. entry ( payment_id) {
@@ -1227,6 +1239,7 @@ impl OutboundPayments {
12271239 entry. insert ( PendingOutboundPayment :: AwaitingInvoice {
12281240 timer_ticks_without_response : 0 ,
12291241 retry_strategy,
1242+ max_total_routing_fee_msat,
12301243 } ) ;
12311244
12321245 Ok ( ( ) )
@@ -1328,8 +1341,9 @@ impl OutboundPayments {
13281341 failed_paths_retry : if pending_amt_unsent != 0 {
13291342 if let Some ( payment_params) = route. route_params . as_ref ( ) . map ( |p| p. payment_params . clone ( ) ) {
13301343 Some ( RouteParameters {
1331- payment_params : payment_params ,
1344+ payment_params,
13321345 final_value_msat : pending_amt_unsent,
1346+ max_total_routing_fee_msat : None ,
13331347 } )
13341348 } else { None }
13351349 } else { None } ,
@@ -1689,6 +1703,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
16891703 ( 8 , pending_amt_msat, required) ,
16901704 ( 9 , custom_tlvs, optional_vec) ,
16911705 ( 10 , starting_block_height, required) ,
1706+ ( 11 , remaining_max_total_routing_fee_msat, option) ,
16921707 ( not_written, retry_strategy, ( static_value, None ) ) ,
16931708 ( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
16941709 } ,
@@ -1700,10 +1715,12 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
17001715 ( 5 , AwaitingInvoice ) => {
17011716 ( 0 , timer_ticks_without_response, required) ,
17021717 ( 2 , retry_strategy, required) ,
1718+ ( 4 , max_total_routing_fee_msat, option) ,
17031719 } ,
17041720 ( 7 , InvoiceReceived ) => {
17051721 ( 0 , payment_hash, required) ,
17061722 ( 2 , retry_strategy, required) ,
1723+ ( 4 , max_total_routing_fee_msat, option) ,
17071724 } ,
17081725) ;
17091726
@@ -1926,7 +1943,9 @@ mod tests {
19261943 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19271944
19281945 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+ ) ;
19301949 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19311950
19321951 for _ in 0 ..INVOICE_REQUEST_TIMEOUT_TICKS {
@@ -1944,10 +1963,15 @@ mod tests {
19441963 ) ;
19451964 assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
19461965
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+ ) ;
19481969 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19491970
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+ ) ;
19511975 }
19521976
19531977 #[ test]
@@ -1957,7 +1981,9 @@ mod tests {
19571981 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19581982
19591983 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+ ) ;
19611987 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19621988
19631989 outbound_payments. abandon_payment (
@@ -1985,7 +2011,9 @@ mod tests {
19852011 let outbound_payments = OutboundPayments :: new ( ) ;
19862012 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19872013
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+ ) ;
19892017 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19902018
19912019 let created_at = now ( ) - DEFAULT_RELATIVE_EXPIRY ;
@@ -2031,7 +2059,9 @@ mod tests {
20312059 let outbound_payments = OutboundPayments :: new ( ) ;
20322060 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
20332061
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+ ) ;
20352065 assert ! ( outbound_payments. has_pending_payments( ) ) ;
20362066
20372067 let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2045,10 +2075,10 @@ mod tests {
20452075 . sign ( recipient_sign) . unwrap ( ) ;
20462076
20472077 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+ ) ,
20522082 Err ( LightningError { err : String :: new ( ) , action : ErrorAction :: IgnoreError } ) ,
20532083 ) ;
20542084
@@ -2084,7 +2114,9 @@ mod tests {
20842114 let outbound_payments = OutboundPayments :: new ( ) ;
20852115 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
20862116
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+ ) ;
20882120 assert ! ( outbound_payments. has_pending_payments( ) ) ;
20892121
20902122 let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2097,10 +2129,10 @@ mod tests {
20972129 . build ( ) . unwrap ( )
20982130 . sign ( recipient_sign) . unwrap ( ) ;
20992131
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+ ) ;
21042136 router. expect_find_route (
21052137 route_params. clone ( ) , Ok ( Route { paths : vec ! [ ] , route_params : Some ( route_params) } )
21062138 ) ;
@@ -2150,6 +2182,7 @@ mod tests {
21502182 let route_params = RouteParameters {
21512183 payment_params : PaymentParameters :: from_bolt12_invoice ( & invoice) ,
21522184 final_value_msat : invoice. amount_msats ( ) ,
2185+ max_total_routing_fee_msat : Some ( 1234 ) ,
21532186 } ;
21542187 router. expect_find_route (
21552188 route_params. clone ( ) ,
@@ -2185,7 +2218,9 @@ mod tests {
21852218 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
21862219 assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
21872220
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+ ) ;
21892224 assert ! ( outbound_payments. has_pending_payments( ) ) ;
21902225
21912226 assert_eq ! (
0 commit comments