@@ -82,6 +82,7 @@ pub(crate) enum PendingOutboundPayment {
8282 retry_strategy : Retry ,
8383 route_params_config : RouteParametersConfig ,
8484 retryable_invoice_request : Option < RetryableInvoiceRequest > ,
85+ custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
8586 } ,
8687 // Represents the state after the invoice has been received, transitioning from the corresponding
8788 // `AwaitingInvoice` state.
@@ -93,6 +94,7 @@ pub(crate) enum PendingOutboundPayment {
9394 // race conditions where this field might be missing upon reload. It may be required
9495 // for future retries.
9596 route_params_config : RouteParametersConfig ,
97+ custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
9698 } ,
9799 // This state applies when we are paying an often-offline recipient and another node on the
98100 // network served us a static invoice on the recipient's behalf in response to our invoice
@@ -986,7 +988,7 @@ where
986988 SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
987989 {
988990
989- let ( payment_hash, retry_strategy, params_config, _) = self
991+ let ( payment_hash, retry_strategy, params_config, custom_tlvs , _) = self
990992 . mark_invoice_received_and_get_details ( invoice, payment_id) ?;
991993
992994 if invoice. invoice_features ( ) . requires_unknown_bits_from ( & features) {
@@ -1004,10 +1006,16 @@ where
10041006 route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
10051007 }
10061008 let invoice = PaidBolt12Invoice :: Bolt12Invoice ( invoice. clone ( ) ) ;
1009+
1010+ let recipient_onion = RecipientOnionFields :: spontaneous_empty ( )
1011+ . with_custom_tlvs ( custom_tlvs)
1012+ . map_err ( |_| Bolt12PaymentError :: SendingFailed ( RetryableSendFailure :: InvalidCustomTlvs ) ) ?;
1013+
10071014 self . send_payment_for_bolt12_invoice_internal (
1008- payment_id, payment_hash, None , None , invoice, route_params, retry_strategy, false , router,
1009- first_hops, inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx,
1010- best_block_height, pending_events, send_payment_along_path
1015+ payment_id, payment_hash, None , None , invoice, recipient_onion,
1016+ route_params, retry_strategy, false , router, first_hops, inflight_htlcs,
1017+ entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height, pending_events,
1018+ send_payment_along_path
10111019 )
10121020 }
10131021
@@ -1017,7 +1025,7 @@ where
10171025 > (
10181026 & self , payment_id : PaymentId , payment_hash : PaymentHash ,
10191027 keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
1020- bolt12_invoice : PaidBolt12Invoice ,
1028+ bolt12_invoice : PaidBolt12Invoice , recipient_onion : RecipientOnionFields ,
10211029 mut route_params : RouteParameters , retry_strategy : Retry , hold_htlcs_at_next_hop : bool , router : & R ,
10221030 first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES , node_signer : & NS ,
10231031 node_id_lookup : & NL , secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 ,
@@ -1050,11 +1058,6 @@ where
10501058 }
10511059 }
10521060
1053- let recipient_onion = RecipientOnionFields {
1054- payment_secret : None ,
1055- payment_metadata : None ,
1056- custom_tlvs : vec ! [ ] ,
1057- } ;
10581061 let route = match self . find_initial_route (
10591062 payment_id, payment_hash, & recipient_onion, keysend_preimage, invoice_request,
10601063 & mut route_params, router, & first_hops, & inflight_htlcs, node_signer, best_block_height,
@@ -1289,13 +1292,16 @@ where
12891292 retry_strategy = Retry :: Attempts ( 0 ) ;
12901293 }
12911294
1295+ let recipient_onion = RecipientOnionFields :: spontaneous_empty ( ) ;
1296+
12921297 let invoice = PaidBolt12Invoice :: StaticInvoice ( invoice) ;
12931298 self . send_payment_for_bolt12_invoice_internal (
12941299 payment_id,
12951300 payment_hash,
12961301 Some ( keysend_preimage) ,
12971302 Some ( & invoice_request) ,
12981303 invoice,
1304+ recipient_onion,
12991305 route_params,
13001306 retry_strategy,
13011307 hold_htlcs_at_next_hop,
@@ -1980,7 +1986,8 @@ where
19801986 #[ cfg( feature = "dnssec" ) ]
19811987 #[ rustfmt:: skip]
19821988 pub ( super ) fn received_offer (
1983- & self , payment_id : PaymentId , retryable_invoice_request : Option < RetryableInvoiceRequest > ,
1989+ & self , payment_id : PaymentId , custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
1990+ retryable_invoice_request : Option < RetryableInvoiceRequest > ,
19841991 ) -> Result < ( ) , ( ) > {
19851992 match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
19861993 hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
@@ -1992,6 +1999,7 @@ where
19921999 retry_strategy : * retry_strategy,
19932000 route_params_config : * route_params_config,
19942001 retryable_invoice_request,
2002+ custom_tlvs,
19952003 } ;
19962004 core:: mem:: swap ( & mut new_val, entry. into_mut ( ) ) ;
19972005 Ok ( ( ) )
@@ -2003,7 +2011,8 @@ where
20032011 }
20042012
20052013 pub ( super ) fn add_new_awaiting_invoice (
2006- & self , payment_id : PaymentId , expiration : StaleExpiration , retry_strategy : Retry ,
2014+ & self , payment_id : PaymentId , custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
2015+ expiration : StaleExpiration , retry_strategy : Retry ,
20072016 route_params_config : RouteParametersConfig ,
20082017 retryable_invoice_request : Option < RetryableInvoiceRequest > ,
20092018 ) -> Result < ( ) , ( ) > {
@@ -2019,6 +2028,7 @@ where
20192028 retry_strategy,
20202029 route_params_config,
20212030 retryable_invoice_request,
2031+ custom_tlvs,
20222032 } ) ;
20232033
20242034 Ok ( ( ) )
@@ -2031,7 +2041,7 @@ where
20312041 & self , invoice : & Bolt12Invoice , payment_id : PaymentId
20322042 ) -> Result < ( ) , Bolt12PaymentError > {
20332043 self . mark_invoice_received_and_get_details ( invoice, payment_id)
2034- . and_then ( |( _, _, _, is_newly_marked) | {
2044+ . and_then ( |( _, _, _, _ , is_newly_marked) | {
20352045 is_newly_marked
20362046 . then_some ( ( ) )
20372047 . ok_or ( Bolt12PaymentError :: DuplicateInvoice )
@@ -2040,32 +2050,34 @@ where
20402050
20412051 #[ rustfmt:: skip]
20422052 fn mark_invoice_received_and_get_details (
2043- & self , invoice : & Bolt12Invoice , payment_id : PaymentId
2044- ) -> Result < ( PaymentHash , Retry , RouteParametersConfig , bool ) , Bolt12PaymentError > {
2053+ & self , invoice : & Bolt12Invoice , payment_id : PaymentId ,
2054+ ) -> Result < ( PaymentHash , Retry , RouteParametersConfig , Vec < ( u64 , Vec < u8 > ) > , bool ) , Bolt12PaymentError > {
20452055 match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
2046- hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
2056+ hash_map:: Entry :: Occupied ( mut entry) => match entry. get_mut ( ) {
20472057 PendingOutboundPayment :: AwaitingInvoice {
2048- retry_strategy : retry, route_params_config, ..
2058+ retry_strategy : retry, route_params_config, custom_tlvs , ..
20492059 } => {
20502060 let payment_hash = invoice. payment_hash ( ) ;
20512061 let retry = * retry;
20522062 let config = * route_params_config;
2053- * entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
2063+ let custom = core:: mem:: take ( custom_tlvs) ;
2064+ * entry. get_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
20542065 payment_hash,
20552066 retry_strategy : retry,
20562067 route_params_config : config,
2068+ custom_tlvs : custom. clone ( ) ,
20572069 } ;
20582070
2059- Ok ( ( payment_hash, retry, config, true ) )
2071+ Ok ( ( payment_hash, retry, config, custom , true ) )
20602072 } ,
20612073 // When manual invoice handling is enabled, the corresponding `PendingOutboundPayment` entry
20622074 // is already updated at the time the invoice is received. This ensures that `InvoiceReceived`
20632075 // event generation remains idempotent, even if the same invoice is received again before the
20642076 // event is handled by the user.
20652077 PendingOutboundPayment :: InvoiceReceived {
2066- retry_strategy, route_params_config, ..
2078+ retry_strategy, route_params_config, custom_tlvs , ..
20672079 } => {
2068- Ok ( ( invoice. payment_hash ( ) , * retry_strategy, * route_params_config, false ) )
2080+ Ok ( ( invoice. payment_hash ( ) , * retry_strategy, * route_params_config, custom_tlvs . clone ( ) , false ) )
20692081 } ,
20702082 _ => Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
20712083 } ,
@@ -2757,6 +2769,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
27572769 |fee_msat| RouteParametersConfig :: default ( ) . with_max_total_routing_fee_msat( fee_msat)
27582770 )
27592771 ) ) ) ,
2772+ ( 9 , custom_tlvs, optional_vec) ,
27602773 } ,
27612774 ( 7 , InvoiceReceived ) => {
27622775 ( 0 , payment_hash, required) ,
@@ -2773,6 +2786,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
27732786 |fee_msat| RouteParametersConfig :: default ( ) . with_max_total_routing_fee_msat( fee_msat)
27742787 )
27752788 ) ) ) ,
2789+ ( 7 , custom_tlvs, optional_vec) ,
27762790 } ,
27772791 // Added in 0.1. Prior versions will drop these outbounds on downgrade, which is safe because no
27782792 // HTLCs are in-flight.
@@ -3053,7 +3067,7 @@ mod tests {
30533067 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
30543068 assert ! (
30553069 outbound_payments. add_new_awaiting_invoice(
3056- payment_id, expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
3070+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
30573071 ) . is_ok( )
30583072 ) ;
30593073 assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -3083,14 +3097,14 @@ mod tests {
30833097
30843098 assert ! (
30853099 outbound_payments. add_new_awaiting_invoice(
3086- payment_id, expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
3100+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
30873101 ) . is_ok( )
30883102 ) ;
30893103 assert ! ( outbound_payments. has_pending_payments( ) ) ;
30903104
30913105 assert ! (
30923106 outbound_payments. add_new_awaiting_invoice(
3093- payment_id, expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
3107+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
30943108 ) . is_err( )
30953109 ) ;
30963110 }
@@ -3108,7 +3122,7 @@ mod tests {
31083122 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
31093123 assert ! (
31103124 outbound_payments. add_new_awaiting_invoice(
3111- payment_id, expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
3125+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
31123126 ) . is_ok( )
31133127 ) ;
31143128 assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -3138,14 +3152,14 @@ mod tests {
31383152
31393153 assert ! (
31403154 outbound_payments. add_new_awaiting_invoice(
3141- payment_id, expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
3155+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
31423156 ) . is_ok( )
31433157 ) ;
31443158 assert ! ( outbound_payments. has_pending_payments( ) ) ;
31453159
31463160 assert ! (
31473161 outbound_payments. add_new_awaiting_invoice(
3148- payment_id, expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
3162+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
31493163 ) . is_err( )
31503164 ) ;
31513165 }
@@ -3162,7 +3176,7 @@ mod tests {
31623176 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
31633177 assert ! (
31643178 outbound_payments. add_new_awaiting_invoice(
3165- payment_id, expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
3179+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
31663180 ) . is_ok( )
31673181 ) ;
31683182 assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -3201,7 +3215,7 @@ mod tests {
32013215
32023216 assert ! (
32033217 outbound_payments. add_new_awaiting_invoice(
3204- payment_id, expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
3218+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , RouteParametersConfig :: default ( ) , None ,
32053219 ) . is_ok( )
32063220 ) ;
32073221 assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -3267,7 +3281,7 @@ mod tests {
32673281
32683282 assert ! (
32693283 outbound_payments. add_new_awaiting_invoice(
3270- payment_id, expiration, Retry :: Attempts ( 0 ) ,
3284+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) ,
32713285 route_params_config, None ,
32723286 ) . is_ok( )
32733287 ) ;
@@ -3370,7 +3384,7 @@ mod tests {
33703384
33713385 assert ! (
33723386 outbound_payments. add_new_awaiting_invoice(
3373- payment_id, expiration, Retry :: Attempts ( 0 ) , route_params_config, None ,
3387+ payment_id, vec! [ ] , expiration, Retry :: Attempts ( 0 ) , route_params_config, None ,
33743388 ) . is_ok( )
33753389 ) ;
33763390 assert ! ( outbound_payments. has_pending_payments( ) ) ;
0 commit comments