@@ -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 ;
@@ -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,18 +979,20 @@ 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
977987 } ,
988+ // TODO(vincenzopalazzo): What about static invoices? There is no proof of payment with async payment because we need PTLC
989+ // so we can ingore it for now
978990 PendingOutboundPayment :: StaticInvoiceReceived { .. } => {
979991 let invreq = if let PendingOutboundPayment :: StaticInvoiceReceived { invoice_request, .. } = entry. remove ( ) {
980992 invoice_request
981993 } else { unreachable ! ( ) } ;
982994 let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
983- payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , & route,
995+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , None , & route,
984996 Some ( retry_strategy) , payment_params, entropy_source, best_block_height
985997 ) ;
986998 outbounds. insert ( payment_id, retryable_payment) ;
@@ -1130,7 +1142,7 @@ impl OutboundPayments {
11301142 } ;
11311143
11321144 self . send_payment_for_bolt12_invoice_internal (
1133- payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , route_params,
1145+ payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , None , route_params,
11341146 retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
11351147 node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
11361148 )
@@ -1276,7 +1288,7 @@ impl OutboundPayments {
12761288
12771289 let onion_session_privs = self . add_new_pending_payment ( payment_hash,
12781290 recipient_onion. clone ( ) , payment_id, keysend_preimage, & route, Some ( retry_strategy) ,
1279- Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height)
1291+ Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height, None )
12801292 . map_err ( |_| {
12811293 log_error ! ( logger, "Payment with id {} is already pending. New payment had payment hash {}" ,
12821294 payment_id, payment_hash) ;
@@ -1590,7 +1602,7 @@ impl OutboundPayments {
15901602 let route = Route { paths : vec ! [ path] , route_params : None } ;
15911603 let onion_session_privs = self . add_new_pending_payment ( payment_hash,
15921604 RecipientOnionFields :: secret_only ( payment_secret) , payment_id, None , & route, None , None ,
1593- entropy_source, best_block_height
1605+ entropy_source, best_block_height, None
15941606 ) . map_err ( |e| {
15951607 debug_assert ! ( matches!( e, PaymentSendFailure :: DuplicatePayment ) ) ;
15961608 ProbeSendFailure :: DuplicateProbe
@@ -1645,20 +1657,21 @@ impl OutboundPayments {
16451657 & self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
16461658 route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
16471659 ) -> 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)
1660+ self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height, None )
16491661 }
16501662
16511663 pub ( super ) fn add_new_pending_payment < ES : Deref > (
16521664 & self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
16531665 keysend_preimage : Option < PaymentPreimage > , route : & Route , retry_strategy : Option < Retry > ,
1654- payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
1666+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32 ,
1667+ bolt12_invoice : Option < Bolt12Invoice >
16551668 ) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
16561669 let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
16571670 match pending_outbounds. entry ( payment_id) {
16581671 hash_map:: Entry :: Occupied ( _) => Err ( PaymentSendFailure :: DuplicatePayment ) ,
16591672 hash_map:: Entry :: Vacant ( entry) => {
16601673 let ( payment, onion_session_privs) = Self :: create_pending_payment (
1661- payment_hash, recipient_onion, keysend_preimage, None , route, retry_strategy,
1674+ payment_hash, recipient_onion, keysend_preimage, None , bolt12_invoice , route, retry_strategy,
16621675 payment_params, entropy_source, best_block_height
16631676 ) ;
16641677 entry. insert ( payment) ;
@@ -1670,8 +1683,8 @@ impl OutboundPayments {
16701683 fn create_pending_payment < ES : Deref > (
16711684 payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
16721685 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
1686+ bolt12_invoice : Option < Bolt12Invoice > , route : & Route , retry_strategy : Option < Retry > ,
1687+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
16751688 ) -> ( PendingOutboundPayment , Vec < [ u8 ; 32 ] > )
16761689 where
16771690 ES :: Target : EntropySource ,
@@ -1693,6 +1706,7 @@ impl OutboundPayments {
16931706 payment_metadata : recipient_onion. payment_metadata ,
16941707 keysend_preimage,
16951708 invoice_request,
1709+ bolt12_invoice,
16961710 custom_tlvs : recipient_onion. custom_tlvs ,
16971711 starting_block_height : best_block_height,
16981712 total_msat : route. get_total_amount ( ) ,
@@ -2310,6 +2324,7 @@ impl OutboundPayments {
23102324 payment_metadata: None , // only used for retries, and we'll never retry on startup
23112325 keysend_preimage: None , // only used for retries, and we'll never retry on startup
23122326 invoice_request: None , // only used for retries, and we'll never retry on startup
2327+ bolt12_invoice: None , // only used for retries, and we'll never retry on startup! TODO(vincenzopalazzo): double check this
23132328 custom_tlvs: Vec :: new( ) , // only used for retries, and we'll never retry on startup
23142329 pending_amt_msat: path_amt,
23152330 pending_fee_msat: Some ( path_fee) ,
@@ -2399,6 +2414,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
23992414 ( 10 , starting_block_height, required) ,
24002415 ( 11 , remaining_max_total_routing_fee_msat, option) ,
24012416 ( 13 , invoice_request, option) ,
2417+ ( 15 , bolt12_invoice, option) ,
24022418 ( not_written, retry_strategy, ( static_value, None ) ) ,
24032419 ( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
24042420 } ,
@@ -2516,7 +2532,7 @@ mod tests {
25162532 outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
25172533 PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
25182534 Some ( Retry :: Attempts ( 1 ) ) , Some ( expired_route_params. payment_params . clone ( ) ) ,
2519- & & keys_manager, 0 ) . unwrap ( ) ;
2535+ & & keys_manager, 0 , None ) . unwrap ( ) ;
25202536 outbound_payments. find_route_and_send_payment (
25212537 PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] ,
25222538 & || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
@@ -2559,7 +2575,7 @@ mod tests {
25592575 outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
25602576 PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
25612577 Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params. payment_params . clone ( ) ) ,
2562- & & keys_manager, 0 ) . unwrap ( ) ;
2578+ & & keys_manager, 0 , None ) . unwrap ( ) ;
25632579 outbound_payments. find_route_and_send_payment (
25642580 PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] ,
25652581 & || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
0 commit comments