@@ -104,6 +104,9 @@ pub(crate) enum PendingOutboundPayment {
104104 payment_metadata : Option < Vec < u8 > > ,
105105 keysend_preimage : Option < PaymentPreimage > ,
106106 invoice_request : Option < InvoiceRequest > ,
107+ // Storing the bolt12 invoice here to allow Proof of Payment after
108+ // the payment is made.
109+ bolt12_invoice : Option < Bolt12Invoice > ,
107110 custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
108111 pending_amt_msat : u64 ,
109112 /// Used to track the fee paid. Present iff the payment was serialized on 0.0.103+.
@@ -153,6 +156,12 @@ impl_writeable_tlv_based!(RetryableInvoiceRequest, {
153156} ) ;
154157
155158impl PendingOutboundPayment {
159+ fn bolt12_invoice ( & self ) -> Option < & Bolt12Invoice > {
160+ match self {
161+ PendingOutboundPayment :: Retryable { bolt12_invoice, .. } => bolt12_invoice. as_ref ( ) ,
162+ _ => None ,
163+ }
164+ }
156165 fn increment_attempts ( & mut self ) {
157166 if let PendingOutboundPayment :: Retryable { attempts, .. } = self {
158167 attempts. count += 1 ;
@@ -813,7 +822,7 @@ impl OutboundPayments {
813822 IH : Fn ( ) -> InFlightHtlcs ,
814823 SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
815824 {
816- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, None , retry_strategy,
825+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, None , retry_strategy,
817826 route_params, router, first_hops, & compute_inflight_htlcs, entropy_source, node_signer,
818827 best_block_height, logger, pending_events, & send_payment_along_path)
819828 }
@@ -836,7 +845,7 @@ impl OutboundPayments {
836845 let preimage = payment_preimage
837846 . unwrap_or_else ( || PaymentPreimage ( entropy_source. get_secure_random_bytes ( ) ) ) ;
838847 let payment_hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 ) . to_byte_array ( ) ) ;
839- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, Some ( preimage) ,
848+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, Some ( preimage) ,
840849 retry_strategy, route_params, router, first_hops, inflight_htlcs, entropy_source,
841850 node_signer, best_block_height, logger, pending_events, send_payment_along_path)
842851 . map ( |( ) | payment_hash)
@@ -896,7 +905,7 @@ impl OutboundPayments {
896905 route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
897906 }
898907 self . send_payment_for_bolt12_invoice_internal (
899- payment_id, payment_hash, None , None , route_params, retry_strategy, router, first_hops,
908+ payment_id, payment_hash, None , None , Some ( invoice ) , route_params, retry_strategy, router, first_hops,
900909 inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
901910 logger, pending_events, send_payment_along_path
902911 )
@@ -907,6 +916,7 @@ impl OutboundPayments {
907916 > (
908917 & self , payment_id : PaymentId , payment_hash : PaymentHash ,
909918 keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
919+ bolt12_invoice : Option < & Bolt12Invoice > ,
910920 mut route_params : RouteParameters , retry_strategy : Retry , router : & R ,
911921 first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES , node_signer : & NS ,
912922 node_id_lookup : & NL , secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 , logger : & L ,
@@ -969,8 +979,8 @@ impl OutboundPayments {
969979 hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
970980 PendingOutboundPayment :: InvoiceReceived { .. } => {
971981 let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
972- payment_hash, recipient_onion. clone ( ) , keysend_preimage, None , & route,
973- Some ( retry_strategy) , payment_params, entropy_source, best_block_height
982+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, None , bolt12_invoice . cloned ( ) , & route,
983+ Some ( retry_strategy) , payment_params, entropy_source, best_block_height,
974984 ) ;
975985 * entry. into_mut ( ) = retryable_payment;
976986 onion_session_privs
@@ -980,7 +990,7 @@ impl OutboundPayments {
980990 invoice_request
981991 } else { unreachable ! ( ) } ;
982992 let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
983- payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , & route,
993+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , bolt12_invoice . cloned ( ) , & route,
984994 Some ( retry_strategy) , payment_params, entropy_source, best_block_height
985995 ) ;
986996 outbounds. insert ( payment_id, retryable_payment) ;
@@ -1130,7 +1140,7 @@ impl OutboundPayments {
11301140 } ;
11311141
11321142 self . send_payment_for_bolt12_invoice_internal (
1133- payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , route_params,
1143+ payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , None , route_params,
11341144 retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
11351145 node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
11361146 )
@@ -1254,7 +1264,7 @@ impl OutboundPayments {
12541264 ///
12551265 /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
12561266 /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
1257- fn send_payment_internal < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
1267+ fn send_payment_for_non_bolt12_invoice < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
12581268 & self , payment_id : PaymentId , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
12591269 keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , mut route_params : RouteParameters ,
12601270 router : & R , first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES ,
@@ -1276,7 +1286,7 @@ impl OutboundPayments {
12761286
12771287 let onion_session_privs = self . add_new_pending_payment ( payment_hash,
12781288 recipient_onion. clone ( ) , payment_id, keysend_preimage, & route, Some ( retry_strategy) ,
1279- Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height)
1289+ Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height, None )
12801290 . map_err ( |_| {
12811291 log_error ! ( logger, "Payment with id {} is already pending. New payment had payment hash {}" ,
12821292 payment_id, payment_hash) ;
@@ -1590,7 +1600,7 @@ impl OutboundPayments {
15901600 let route = Route { paths : vec ! [ path] , route_params : None } ;
15911601 let onion_session_privs = self . add_new_pending_payment ( payment_hash,
15921602 RecipientOnionFields :: secret_only ( payment_secret) , payment_id, None , & route, None , None ,
1593- entropy_source, best_block_height
1603+ entropy_source, best_block_height, None
15941604 ) . map_err ( |e| {
15951605 debug_assert ! ( matches!( e, PaymentSendFailure :: DuplicatePayment ) ) ;
15961606 ProbeSendFailure :: DuplicateProbe
@@ -1645,20 +1655,21 @@ impl OutboundPayments {
16451655 & self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
16461656 route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
16471657 ) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
1648- self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height)
1658+ self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height, None )
16491659 }
16501660
16511661 pub ( super ) fn add_new_pending_payment < ES : Deref > (
16521662 & self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
16531663 keysend_preimage : Option < PaymentPreimage > , route : & Route , retry_strategy : Option < Retry > ,
1654- payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
1664+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32 ,
1665+ bolt12_invoice : Option < Bolt12Invoice >
16551666 ) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
16561667 let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
16571668 match pending_outbounds. entry ( payment_id) {
16581669 hash_map:: Entry :: Occupied ( _) => Err ( PaymentSendFailure :: DuplicatePayment ) ,
16591670 hash_map:: Entry :: Vacant ( entry) => {
16601671 let ( payment, onion_session_privs) = Self :: create_pending_payment (
1661- payment_hash, recipient_onion, keysend_preimage, None , route, retry_strategy,
1672+ payment_hash, recipient_onion, keysend_preimage, None , bolt12_invoice , route, retry_strategy,
16621673 payment_params, entropy_source, best_block_height
16631674 ) ;
16641675 entry. insert ( payment) ;
@@ -1670,8 +1681,8 @@ impl OutboundPayments {
16701681 fn create_pending_payment < ES : Deref > (
16711682 payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
16721683 keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < InvoiceRequest > ,
1673- route : & Route , retry_strategy : Option < Retry > , payment_params : Option < PaymentParameters > ,
1674- entropy_source : & ES , best_block_height : u32
1684+ bolt12_invoice : Option < Bolt12Invoice > , route : & Route , retry_strategy : Option < Retry > ,
1685+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
16751686 ) -> ( PendingOutboundPayment , Vec < [ u8 ; 32 ] > )
16761687 where
16771688 ES :: Target : EntropySource ,
@@ -1693,6 +1704,7 @@ impl OutboundPayments {
16931704 payment_metadata : recipient_onion. payment_metadata ,
16941705 keysend_preimage,
16951706 invoice_request,
1707+ bolt12_invoice,
16961708 custom_tlvs : recipient_onion. custom_tlvs ,
16971709 starting_block_height : best_block_height,
16981710 total_msat : route. get_total_amount ( ) ,
@@ -2310,6 +2322,7 @@ impl OutboundPayments {
23102322 payment_metadata: None , // only used for retries, and we'll never retry on startup
23112323 keysend_preimage: None , // only used for retries, and we'll never retry on startup
23122324 invoice_request: None , // only used for retries, and we'll never retry on startup
2325+ bolt12_invoice: None , // only used for retries, and we'll never retry on startup! TODO(vincenzopalazzo): double check this
23132326 custom_tlvs: Vec :: new( ) , // only used for retries, and we'll never retry on startup
23142327 pending_amt_msat: path_amt,
23152328 pending_fee_msat: Some ( path_fee) ,
@@ -2399,6 +2412,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
23992412 ( 10 , starting_block_height, required) ,
24002413 ( 11 , remaining_max_total_routing_fee_msat, option) ,
24012414 ( 13 , invoice_request, option) ,
2415+ ( 15 , bolt12_invoice, option) ,
24022416 ( not_written, retry_strategy, ( static_value, None ) ) ,
24032417 ( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
24042418 } ,
@@ -2516,7 +2530,7 @@ mod tests {
25162530 outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
25172531 PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
25182532 Some ( Retry :: Attempts ( 1 ) ) , Some ( expired_route_params. payment_params . clone ( ) ) ,
2519- & & keys_manager, 0 ) . unwrap ( ) ;
2533+ & & keys_manager, 0 , None ) . unwrap ( ) ;
25202534 outbound_payments. find_route_and_send_payment (
25212535 PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] ,
25222536 & || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
@@ -2559,7 +2573,7 @@ mod tests {
25592573 outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
25602574 PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
25612575 Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params. payment_params . clone ( ) ) ,
2562- & & keys_manager, 0 ) . unwrap ( ) ;
2576+ & & keys_manager, 0 , None ) . unwrap ( ) ;
25632577 outbound_payments. find_route_and_send_payment (
25642578 PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] ,
25652579 & || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
0 commit comments