@@ -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+.
@@ -148,6 +151,12 @@ impl_writeable_tlv_based!(RetryableInvoiceRequest, {
148151} ) ;
149152
150153impl PendingOutboundPayment {
154+ fn bolt12_invoice ( & self ) -> Option < & Bolt12Invoice > {
155+ match self {
156+ PendingOutboundPayment :: Retryable { bolt12_invoice, .. } => bolt12_invoice. as_ref ( ) ,
157+ _ => None ,
158+ }
159+ }
151160 fn increment_attempts ( & mut self ) {
152161 if let PendingOutboundPayment :: Retryable { attempts, .. } = self {
153162 attempts. count += 1 ;
@@ -879,7 +888,7 @@ impl OutboundPayments {
879888 route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
880889 }
881890 self . send_payment_for_bolt12_invoice_internal (
882- payment_id, payment_hash, None , None , route_params, retry_strategy, router, first_hops,
891+ payment_id, payment_hash, None , None , Some ( invoice ) , route_params, retry_strategy, router, first_hops,
883892 inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
884893 logger, pending_events, send_payment_along_path
885894 )
@@ -890,6 +899,7 @@ impl OutboundPayments {
890899 > (
891900 & self , payment_id : PaymentId , payment_hash : PaymentHash ,
892901 keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
902+ bolt12_invoice : Option < & Bolt12Invoice > ,
893903 mut route_params : RouteParameters , retry_strategy : Retry , router : & R ,
894904 first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES , node_signer : & NS ,
895905 node_id_lookup : & NL , secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 , logger : & L ,
@@ -952,18 +962,20 @@ impl OutboundPayments {
952962 hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
953963 PendingOutboundPayment :: InvoiceReceived { .. } => {
954964 let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
955- payment_hash, recipient_onion. clone ( ) , keysend_preimage, None , & route,
956- Some ( retry_strategy) , payment_params, entropy_source, best_block_height
965+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, None , bolt12_invoice . cloned ( ) , & route,
966+ Some ( retry_strategy) , payment_params, entropy_source, best_block_height,
957967 ) ;
958968 * entry. into_mut ( ) = retryable_payment;
959969 onion_session_privs
960970 } ,
971+ // TODO(vincenzopalazzo): What about static invoices? There is no proof of payment with async payment because we need PTLC
972+ // so we can ingore it for now
961973 PendingOutboundPayment :: StaticInvoiceReceived { .. } => {
962974 let invreq = if let PendingOutboundPayment :: StaticInvoiceReceived { invoice_request, .. } = entry. remove ( ) {
963975 invoice_request
964976 } else { unreachable ! ( ) } ;
965977 let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
966- payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , & route,
978+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , None , & route,
967979 Some ( retry_strategy) , payment_params, entropy_source, best_block_height
968980 ) ;
969981 outbounds. insert ( payment_id, retryable_payment) ;
@@ -1113,7 +1125,7 @@ impl OutboundPayments {
11131125 } ;
11141126
11151127 self . send_payment_for_bolt12_invoice_internal (
1116- payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , route_params,
1128+ payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , None , route_params,
11171129 retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
11181130 node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
11191131 )
@@ -1259,7 +1271,7 @@ impl OutboundPayments {
12591271
12601272 let onion_session_privs = self . add_new_pending_payment ( payment_hash,
12611273 recipient_onion. clone ( ) , payment_id, keysend_preimage, & route, Some ( retry_strategy) ,
1262- Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height)
1274+ Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height, None )
12631275 . map_err ( |_| {
12641276 log_error ! ( logger, "Payment with id {} is already pending. New payment had payment hash {}" ,
12651277 payment_id, payment_hash) ;
@@ -1573,7 +1585,7 @@ impl OutboundPayments {
15731585 let route = Route { paths : vec ! [ path] , route_params : None } ;
15741586 let onion_session_privs = self . add_new_pending_payment ( payment_hash,
15751587 RecipientOnionFields :: secret_only ( payment_secret) , payment_id, None , & route, None , None ,
1576- entropy_source, best_block_height
1588+ entropy_source, best_block_height, None
15771589 ) . map_err ( |e| {
15781590 debug_assert ! ( matches!( e, PaymentSendFailure :: DuplicatePayment ) ) ;
15791591 ProbeSendFailure :: DuplicateProbe
@@ -1628,20 +1640,21 @@ impl OutboundPayments {
16281640 & self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
16291641 route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
16301642 ) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
1631- self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height)
1643+ self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height, None )
16321644 }
16331645
16341646 pub ( super ) fn add_new_pending_payment < ES : Deref > (
16351647 & self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
16361648 keysend_preimage : Option < PaymentPreimage > , route : & Route , retry_strategy : Option < Retry > ,
1637- payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
1649+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32 ,
1650+ bolt12_invoice : Option < Bolt12Invoice >
16381651 ) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
16391652 let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
16401653 match pending_outbounds. entry ( payment_id) {
16411654 hash_map:: Entry :: Occupied ( _) => Err ( PaymentSendFailure :: DuplicatePayment ) ,
16421655 hash_map:: Entry :: Vacant ( entry) => {
16431656 let ( payment, onion_session_privs) = Self :: create_pending_payment (
1644- payment_hash, recipient_onion, keysend_preimage, None , route, retry_strategy,
1657+ payment_hash, recipient_onion, keysend_preimage, None , bolt12_invoice , route, retry_strategy,
16451658 payment_params, entropy_source, best_block_height
16461659 ) ;
16471660 entry. insert ( payment) ;
@@ -1653,8 +1666,8 @@ impl OutboundPayments {
16531666 fn create_pending_payment < ES : Deref > (
16541667 payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
16551668 keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < InvoiceRequest > ,
1656- route : & Route , retry_strategy : Option < Retry > , payment_params : Option < PaymentParameters > ,
1657- entropy_source : & ES , best_block_height : u32
1669+ bolt12_invoice : Option < Bolt12Invoice > , route : & Route , retry_strategy : Option < Retry > ,
1670+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
16581671 ) -> ( PendingOutboundPayment , Vec < [ u8 ; 32 ] > )
16591672 where
16601673 ES :: Target : EntropySource ,
@@ -1676,6 +1689,7 @@ impl OutboundPayments {
16761689 payment_metadata : recipient_onion. payment_metadata ,
16771690 keysend_preimage,
16781691 invoice_request,
1692+ bolt12_invoice,
16791693 custom_tlvs : recipient_onion. custom_tlvs ,
16801694 starting_block_height : best_block_height,
16811695 total_msat : route. get_total_amount ( ) ,
@@ -2291,6 +2305,7 @@ impl OutboundPayments {
22912305 payment_metadata: None , // only used for retries, and we'll never retry on startup
22922306 keysend_preimage: None , // only used for retries, and we'll never retry on startup
22932307 invoice_request: None , // only used for retries, and we'll never retry on startup
2308+ bolt12_invoice: None , // only used for retries, and we'll never retry on startup! TODO(vincenzopalazzo): double check this
22942309 custom_tlvs: Vec :: new( ) , // only used for retries, and we'll never retry on startup
22952310 pending_amt_msat: path_amt,
22962311 pending_fee_msat: Some ( path_fee) ,
@@ -2379,6 +2394,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
23792394 ( 10 , starting_block_height, required) ,
23802395 ( 11 , remaining_max_total_routing_fee_msat, option) ,
23812396 ( 13 , invoice_request, option) ,
2397+ ( 15 , bolt12_invoice, option) ,
23822398 ( not_written, retry_strategy, ( static_value, None ) ) ,
23832399 ( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
23842400 } ,
@@ -2496,7 +2512,7 @@ mod tests {
24962512 outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
24972513 PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
24982514 Some ( Retry :: Attempts ( 1 ) ) , Some ( expired_route_params. payment_params . clone ( ) ) ,
2499- & & keys_manager, 0 ) . unwrap ( ) ;
2515+ & & keys_manager, 0 , None ) . unwrap ( ) ;
25002516 outbound_payments. find_route_and_send_payment (
25012517 PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] ,
25022518 & || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
@@ -2540,7 +2556,7 @@ mod tests {
25402556 outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
25412557 PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
25422558 Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params. payment_params . clone ( ) ) ,
2543- & & keys_manager, 0 ) . unwrap ( ) ;
2559+ & & keys_manager, 0 , None ) . unwrap ( ) ;
25442560 outbound_payments. find_route_and_send_payment (
25452561 PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] ,
25462562 & || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
0 commit comments