@@ -106,6 +106,9 @@ pub(crate) enum PendingOutboundPayment {
106
106
payment_metadata : Option < Vec < u8 > > ,
107
107
keysend_preimage : Option < PaymentPreimage > ,
108
108
invoice_request : Option < InvoiceRequest > ,
109
+ // Storing the bolt12 invoice here to allow Proof of Payment after
110
+ // the payment is made.
111
+ bolt12_invoice : Option < Bolt12Invoice > ,
109
112
custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
110
113
pending_amt_msat : u64 ,
111
114
/// Used to track the fee paid. Present iff the payment was serialized on 0.0.103+.
@@ -155,6 +158,12 @@ impl_writeable_tlv_based!(RetryableInvoiceRequest, {
155
158
} ) ;
156
159
157
160
impl PendingOutboundPayment {
161
+ fn bolt12_invoice ( & self ) -> Option < & Bolt12Invoice > {
162
+ match self {
163
+ PendingOutboundPayment :: Retryable { bolt12_invoice, .. } => bolt12_invoice. as_ref ( ) ,
164
+ _ => None ,
165
+ }
166
+ }
158
167
fn increment_attempts ( & mut self ) {
159
168
if let PendingOutboundPayment :: Retryable { attempts, .. } = self {
160
169
attempts. count += 1 ;
@@ -831,7 +840,7 @@ impl OutboundPayments {
831
840
IH : Fn ( ) -> InFlightHtlcs ,
832
841
SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
833
842
{
834
- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, None , retry_strategy,
843
+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, None , retry_strategy,
835
844
route_params, router, first_hops, & compute_inflight_htlcs, entropy_source, node_signer,
836
845
best_block_height, logger, pending_events, & send_payment_along_path)
837
846
}
@@ -854,7 +863,7 @@ impl OutboundPayments {
854
863
let preimage = payment_preimage
855
864
. unwrap_or_else ( || PaymentPreimage ( entropy_source. get_secure_random_bytes ( ) ) ) ;
856
865
let payment_hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 ) . to_byte_array ( ) ) ;
857
- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, Some ( preimage) ,
866
+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, Some ( preimage) ,
858
867
retry_strategy, route_params, router, first_hops, inflight_htlcs, entropy_source,
859
868
node_signer, best_block_height, logger, pending_events, send_payment_along_path)
860
869
. map ( |( ) | payment_hash)
@@ -897,7 +906,7 @@ impl OutboundPayments {
897
906
route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
898
907
}
899
908
900
- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, None , retry_strategy, route_params,
909
+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, None , retry_strategy, route_params,
901
910
router, first_hops, compute_inflight_htlcs,
902
911
entropy_source, node_signer, best_block_height, logger,
903
912
pending_events, send_payment_along_path
@@ -959,7 +968,7 @@ impl OutboundPayments {
959
968
route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
960
969
}
961
970
self . send_payment_for_bolt12_invoice_internal (
962
- payment_id, payment_hash, None , None , route_params, retry_strategy, router, first_hops,
971
+ payment_id, payment_hash, None , None , Some ( invoice ) , route_params, retry_strategy, router, first_hops,
963
972
inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
964
973
logger, pending_events, send_payment_along_path
965
974
)
@@ -970,6 +979,7 @@ impl OutboundPayments {
970
979
> (
971
980
& self , payment_id : PaymentId , payment_hash : PaymentHash ,
972
981
keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
982
+ bolt12_invoice : Option < & Bolt12Invoice > ,
973
983
mut route_params : RouteParameters , retry_strategy : Retry , router : & R ,
974
984
first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES , node_signer : & NS ,
975
985
node_id_lookup : & NL , secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 , logger : & L ,
@@ -1032,8 +1042,8 @@ impl OutboundPayments {
1032
1042
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
1033
1043
PendingOutboundPayment :: InvoiceReceived { .. } => {
1034
1044
let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
1035
- payment_hash, recipient_onion. clone ( ) , keysend_preimage, None , & route,
1036
- Some ( retry_strategy) , payment_params, entropy_source, best_block_height
1045
+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, None , bolt12_invoice . cloned ( ) , & route,
1046
+ Some ( retry_strategy) , payment_params, entropy_source, best_block_height,
1037
1047
) ;
1038
1048
* entry. into_mut ( ) = retryable_payment;
1039
1049
onion_session_privs
@@ -1043,7 +1053,7 @@ impl OutboundPayments {
1043
1053
invoice_request
1044
1054
} else { unreachable ! ( ) } ;
1045
1055
let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
1046
- payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , & route,
1056
+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , bolt12_invoice . cloned ( ) , & route,
1047
1057
Some ( retry_strategy) , payment_params, entropy_source, best_block_height
1048
1058
) ;
1049
1059
outbounds. insert ( payment_id, retryable_payment) ;
@@ -1194,7 +1204,7 @@ impl OutboundPayments {
1194
1204
} ;
1195
1205
1196
1206
self . send_payment_for_bolt12_invoice_internal (
1197
- payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , route_params,
1207
+ payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , None , route_params,
1198
1208
retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
1199
1209
node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
1200
1210
)
@@ -1318,7 +1328,7 @@ impl OutboundPayments {
1318
1328
///
1319
1329
/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
1320
1330
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
1321
- fn send_payment_internal < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
1331
+ fn send_payment_for_non_bolt12_invoice < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
1322
1332
& self , payment_id : PaymentId , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
1323
1333
keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , mut route_params : RouteParameters ,
1324
1334
router : & R , first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES ,
@@ -1340,7 +1350,7 @@ impl OutboundPayments {
1340
1350
1341
1351
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1342
1352
recipient_onion. clone ( ) , payment_id, keysend_preimage, & route, Some ( retry_strategy) ,
1343
- Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height)
1353
+ Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height, None )
1344
1354
. map_err ( |_| {
1345
1355
log_error ! ( logger, "Payment with id {} is already pending. New payment had payment hash {}" ,
1346
1356
payment_id, payment_hash) ;
@@ -1654,7 +1664,7 @@ impl OutboundPayments {
1654
1664
let route = Route { paths : vec ! [ path] , route_params : None } ;
1655
1665
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1656
1666
RecipientOnionFields :: secret_only ( payment_secret) , payment_id, None , & route, None , None ,
1657
- entropy_source, best_block_height
1667
+ entropy_source, best_block_height, None
1658
1668
) . map_err ( |e| {
1659
1669
debug_assert ! ( matches!( e, PaymentSendFailure :: DuplicatePayment ) ) ;
1660
1670
ProbeSendFailure :: DuplicateProbe
@@ -1709,20 +1719,21 @@ impl OutboundPayments {
1709
1719
& self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
1710
1720
route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
1711
1721
) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
1712
- self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height)
1722
+ self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height, None )
1713
1723
}
1714
1724
1715
1725
pub ( super ) fn add_new_pending_payment < ES : Deref > (
1716
1726
& self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
1717
1727
keysend_preimage : Option < PaymentPreimage > , route : & Route , retry_strategy : Option < Retry > ,
1718
- payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
1728
+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32 ,
1729
+ bolt12_invoice : Option < Bolt12Invoice >
1719
1730
) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
1720
1731
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1721
1732
match pending_outbounds. entry ( payment_id) {
1722
1733
hash_map:: Entry :: Occupied ( _) => Err ( PaymentSendFailure :: DuplicatePayment ) ,
1723
1734
hash_map:: Entry :: Vacant ( entry) => {
1724
1735
let ( payment, onion_session_privs) = Self :: create_pending_payment (
1725
- payment_hash, recipient_onion, keysend_preimage, None , route, retry_strategy,
1736
+ payment_hash, recipient_onion, keysend_preimage, None , bolt12_invoice , route, retry_strategy,
1726
1737
payment_params, entropy_source, best_block_height
1727
1738
) ;
1728
1739
entry. insert ( payment) ;
@@ -1734,8 +1745,8 @@ impl OutboundPayments {
1734
1745
fn create_pending_payment < ES : Deref > (
1735
1746
payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
1736
1747
keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < InvoiceRequest > ,
1737
- route : & Route , retry_strategy : Option < Retry > , payment_params : Option < PaymentParameters > ,
1738
- entropy_source : & ES , best_block_height : u32
1748
+ bolt12_invoice : Option < Bolt12Invoice > , route : & Route , retry_strategy : Option < Retry > ,
1749
+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
1739
1750
) -> ( PendingOutboundPayment , Vec < [ u8 ; 32 ] > )
1740
1751
where
1741
1752
ES :: Target : EntropySource ,
@@ -1757,6 +1768,7 @@ impl OutboundPayments {
1757
1768
payment_metadata : recipient_onion. payment_metadata ,
1758
1769
keysend_preimage,
1759
1770
invoice_request,
1771
+ bolt12_invoice,
1760
1772
custom_tlvs : recipient_onion. custom_tlvs ,
1761
1773
starting_block_height : best_block_height,
1762
1774
total_msat : route. get_total_amount ( ) ,
@@ -2374,6 +2386,7 @@ impl OutboundPayments {
2374
2386
payment_metadata: None , // only used for retries, and we'll never retry on startup
2375
2387
keysend_preimage: None , // only used for retries, and we'll never retry on startup
2376
2388
invoice_request: None , // only used for retries, and we'll never retry on startup
2389
+ bolt12_invoice: None , // only used for retries, and we'll never retry on startup! TODO(vincenzopalazzo): double check this
2377
2390
custom_tlvs: Vec :: new( ) , // only used for retries, and we'll never retry on startup
2378
2391
pending_amt_msat: path_amt,
2379
2392
pending_fee_msat: Some ( path_fee) ,
@@ -2463,6 +2476,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
2463
2476
( 10 , starting_block_height, required) ,
2464
2477
( 11 , remaining_max_total_routing_fee_msat, option) ,
2465
2478
( 13 , invoice_request, option) ,
2479
+ ( 15 , bolt12_invoice, option) ,
2466
2480
( not_written, retry_strategy, ( static_value, None ) ) ,
2467
2481
( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
2468
2482
} ,
@@ -2613,7 +2627,7 @@ mod tests {
2613
2627
outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
2614
2628
PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
2615
2629
Some ( Retry :: Attempts ( 1 ) ) , Some ( expired_route_params. payment_params . clone ( ) ) ,
2616
- & & keys_manager, 0 ) . unwrap ( ) ;
2630
+ & & keys_manager, 0 , None ) . unwrap ( ) ;
2617
2631
outbound_payments. find_route_and_send_payment (
2618
2632
PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] ,
2619
2633
& || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
@@ -2656,7 +2670,7 @@ mod tests {
2656
2670
outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
2657
2671
PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
2658
2672
Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params. payment_params . clone ( ) ) ,
2659
- & & keys_manager, 0 ) . unwrap ( ) ;
2673
+ & & keys_manager, 0 , None ) . unwrap ( ) ;
2660
2674
outbound_payments. find_route_and_send_payment (
2661
2675
PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] ,
2662
2676
& || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
0 commit comments