@@ -105,6 +105,9 @@ pub(crate) enum PendingOutboundPayment {
105105 payment_metadata : Option < Vec < u8 > > ,
106106 keysend_preimage : Option < PaymentPreimage > ,
107107 invoice_request : Option < InvoiceRequest > ,
108+ // Storing the bolt12 invoice here to allow Proof of Payment after
109+ // the payment is made.
110+ bolt12_invoice : Option < Bolt12Invoice > ,
108111 custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
109112 pending_amt_msat : u64 ,
110113 /// Used to track the fee paid. Present iff the payment was serialized on 0.0.103+.
@@ -154,6 +157,12 @@ impl_writeable_tlv_based!(RetryableInvoiceRequest, {
154157} ) ;
155158
156159impl PendingOutboundPayment {
160+ fn bolt12_invoice ( & self ) -> Option < & Bolt12Invoice > {
161+ match self {
162+ PendingOutboundPayment :: Retryable { bolt12_invoice, .. } => bolt12_invoice. as_ref ( ) ,
163+ _ => None ,
164+ }
165+ }
157166 fn increment_attempts ( & mut self ) {
158167 if let PendingOutboundPayment :: Retryable { attempts, .. } = self {
159168 attempts. count += 1 ;
@@ -814,7 +823,7 @@ impl OutboundPayments {
814823 IH : Fn ( ) -> InFlightHtlcs ,
815824 SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
816825 {
817- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, None , retry_strategy,
826+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, None , retry_strategy,
818827 route_params, router, first_hops, & compute_inflight_htlcs, entropy_source, node_signer,
819828 best_block_height, logger, pending_events, & send_payment_along_path)
820829 }
@@ -837,7 +846,7 @@ impl OutboundPayments {
837846 let preimage = payment_preimage
838847 . unwrap_or_else ( || PaymentPreimage ( entropy_source. get_secure_random_bytes ( ) ) ) ;
839848 let payment_hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 ) . to_byte_array ( ) ) ;
840- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, Some ( preimage) ,
849+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, Some ( preimage) ,
841850 retry_strategy, route_params, router, first_hops, inflight_htlcs, entropy_source,
842851 node_signer, best_block_height, logger, pending_events, send_payment_along_path)
843852 . map ( |( ) | payment_hash)
@@ -898,7 +907,7 @@ impl OutboundPayments {
898907 route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
899908 }
900909 self . send_payment_for_bolt12_invoice_internal (
901- payment_id, payment_hash, None , None , route_params, retry_strategy, router, first_hops,
910+ payment_id, payment_hash, None , None , Some ( invoice ) , route_params, retry_strategy, router, first_hops,
902911 inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
903912 logger, pending_events, send_payment_along_path
904913 )
@@ -909,6 +918,7 @@ impl OutboundPayments {
909918 > (
910919 & self , payment_id : PaymentId , payment_hash : PaymentHash ,
911920 keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
921+ bolt12_invoice : Option < & Bolt12Invoice > ,
912922 mut route_params : RouteParameters , retry_strategy : Retry , router : & R ,
913923 first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES , node_signer : & NS ,
914924 node_id_lookup : & NL , secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 , logger : & L ,
@@ -971,8 +981,8 @@ impl OutboundPayments {
971981 hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
972982 PendingOutboundPayment :: InvoiceReceived { .. } => {
973983 let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
974- payment_hash, recipient_onion. clone ( ) , keysend_preimage, None , & route,
975- Some ( retry_strategy) , payment_params, entropy_source, best_block_height
984+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, None , bolt12_invoice . cloned ( ) , & route,
985+ Some ( retry_strategy) , payment_params, entropy_source, best_block_height,
976986 ) ;
977987 * entry. into_mut ( ) = retryable_payment;
978988 onion_session_privs
@@ -982,7 +992,7 @@ impl OutboundPayments {
982992 invoice_request
983993 } else { unreachable ! ( ) } ;
984994 let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
985- payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , & route,
995+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , bolt12_invoice . cloned ( ) , & route,
986996 Some ( retry_strategy) , payment_params, entropy_source, best_block_height
987997 ) ;
988998 outbounds. insert ( payment_id, retryable_payment) ;
@@ -1133,7 +1143,7 @@ impl OutboundPayments {
11331143 } ;
11341144
11351145 self . send_payment_for_bolt12_invoice_internal (
1136- payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , route_params,
1146+ payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , None , route_params,
11371147 retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
11381148 node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
11391149 )
@@ -1257,7 +1267,7 @@ impl OutboundPayments {
12571267 ///
12581268 /// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
12591269 /// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
1260- fn send_payment_internal < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
1270+ fn send_payment_for_non_bolt12_invoice < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
12611271 & self , payment_id : PaymentId , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
12621272 keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , mut route_params : RouteParameters ,
12631273 router : & R , first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES ,
@@ -1279,7 +1289,7 @@ impl OutboundPayments {
12791289
12801290 let onion_session_privs = self . add_new_pending_payment ( payment_hash,
12811291 recipient_onion. clone ( ) , payment_id, keysend_preimage, & route, Some ( retry_strategy) ,
1282- Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height)
1292+ Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height, None )
12831293 . map_err ( |_| {
12841294 log_error ! ( logger, "Payment with id {} is already pending. New payment had payment hash {}" ,
12851295 payment_id, payment_hash) ;
@@ -1593,7 +1603,7 @@ impl OutboundPayments {
15931603 let route = Route { paths : vec ! [ path] , route_params : None } ;
15941604 let onion_session_privs = self . add_new_pending_payment ( payment_hash,
15951605 RecipientOnionFields :: secret_only ( payment_secret) , payment_id, None , & route, None , None ,
1596- entropy_source, best_block_height
1606+ entropy_source, best_block_height, None
15971607 ) . map_err ( |e| {
15981608 debug_assert ! ( matches!( e, PaymentSendFailure :: DuplicatePayment ) ) ;
15991609 ProbeSendFailure :: DuplicateProbe
@@ -1648,20 +1658,21 @@ impl OutboundPayments {
16481658 & self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
16491659 route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
16501660 ) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
1651- self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height)
1661+ self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height, None )
16521662 }
16531663
16541664 pub ( super ) fn add_new_pending_payment < ES : Deref > (
16551665 & self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
16561666 keysend_preimage : Option < PaymentPreimage > , route : & Route , retry_strategy : Option < Retry > ,
1657- payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
1667+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32 ,
1668+ bolt12_invoice : Option < Bolt12Invoice >
16581669 ) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
16591670 let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
16601671 match pending_outbounds. entry ( payment_id) {
16611672 hash_map:: Entry :: Occupied ( _) => Err ( PaymentSendFailure :: DuplicatePayment ) ,
16621673 hash_map:: Entry :: Vacant ( entry) => {
16631674 let ( payment, onion_session_privs) = Self :: create_pending_payment (
1664- payment_hash, recipient_onion, keysend_preimage, None , route, retry_strategy,
1675+ payment_hash, recipient_onion, keysend_preimage, None , bolt12_invoice , route, retry_strategy,
16651676 payment_params, entropy_source, best_block_height
16661677 ) ;
16671678 entry. insert ( payment) ;
@@ -1673,8 +1684,8 @@ impl OutboundPayments {
16731684 fn create_pending_payment < ES : Deref > (
16741685 payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
16751686 keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < InvoiceRequest > ,
1676- route : & Route , retry_strategy : Option < Retry > , payment_params : Option < PaymentParameters > ,
1677- entropy_source : & ES , best_block_height : u32
1687+ bolt12_invoice : Option < Bolt12Invoice > , route : & Route , retry_strategy : Option < Retry > ,
1688+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
16781689 ) -> ( PendingOutboundPayment , Vec < [ u8 ; 32 ] > )
16791690 where
16801691 ES :: Target : EntropySource ,
@@ -1696,6 +1707,7 @@ impl OutboundPayments {
16961707 payment_metadata : recipient_onion. payment_metadata ,
16971708 keysend_preimage,
16981709 invoice_request,
1710+ bolt12_invoice,
16991711 custom_tlvs : recipient_onion. custom_tlvs ,
17001712 starting_block_height : best_block_height,
17011713 total_msat : route. get_total_amount ( ) ,
@@ -2313,6 +2325,7 @@ impl OutboundPayments {
23132325 payment_metadata: None , // only used for retries, and we'll never retry on startup
23142326 keysend_preimage: None , // only used for retries, and we'll never retry on startup
23152327 invoice_request: None , // only used for retries, and we'll never retry on startup
2328+ bolt12_invoice: None , // only used for retries, and we'll never retry on startup! TODO(vincenzopalazzo): double check this
23162329 custom_tlvs: Vec :: new( ) , // only used for retries, and we'll never retry on startup
23172330 pending_amt_msat: path_amt,
23182331 pending_fee_msat: Some ( path_fee) ,
@@ -2402,6 +2415,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
24022415 ( 10 , starting_block_height, required) ,
24032416 ( 11 , remaining_max_total_routing_fee_msat, option) ,
24042417 ( 13 , invoice_request, option) ,
2418+ ( 15 , bolt12_invoice, option) ,
24052419 ( not_written, retry_strategy, ( static_value, None ) ) ,
24062420 ( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
24072421 } ,
@@ -2552,7 +2566,7 @@ mod tests {
25522566 outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
25532567 PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
25542568 Some ( Retry :: Attempts ( 1 ) ) , Some ( expired_route_params. payment_params . clone ( ) ) ,
2555- & & keys_manager, 0 ) . unwrap ( ) ;
2569+ & & keys_manager, 0 , None ) . unwrap ( ) ;
25562570 outbound_payments. find_route_and_send_payment (
25572571 PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] ,
25582572 & || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
@@ -2595,7 +2609,7 @@ mod tests {
25952609 outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
25962610 PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
25972611 Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params. payment_params . clone ( ) ) ,
2598- & & keys_manager, 0 ) . unwrap ( ) ;
2612+ & & keys_manager, 0 , None ) . unwrap ( ) ;
25992613 outbound_payments. find_route_and_send_payment (
26002614 PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] ,
26012615 & || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
0 commit comments