@@ -105,6 +105,9 @@ pub(crate) enum PendingOutboundPayment {
105
105
payment_metadata : Option < Vec < u8 > > ,
106
106
keysend_preimage : Option < PaymentPreimage > ,
107
107
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 > ,
108
111
custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
109
112
pending_amt_msat : u64 ,
110
113
/// 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, {
154
157
} ) ;
155
158
156
159
impl PendingOutboundPayment {
160
+ fn bolt12_invoice ( & self ) -> Option < & Bolt12Invoice > {
161
+ match self {
162
+ PendingOutboundPayment :: Retryable { bolt12_invoice, .. } => bolt12_invoice. as_ref ( ) ,
163
+ _ => None ,
164
+ }
165
+ }
157
166
fn increment_attempts ( & mut self ) {
158
167
if let PendingOutboundPayment :: Retryable { attempts, .. } = self {
159
168
attempts. count += 1 ;
@@ -814,7 +823,7 @@ impl OutboundPayments {
814
823
IH : Fn ( ) -> InFlightHtlcs ,
815
824
SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
816
825
{
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,
818
827
route_params, router, first_hops, & compute_inflight_htlcs, entropy_source, node_signer,
819
828
best_block_height, logger, pending_events, & send_payment_along_path)
820
829
}
@@ -837,7 +846,7 @@ impl OutboundPayments {
837
846
let preimage = payment_preimage
838
847
. unwrap_or_else ( || PaymentPreimage ( entropy_source. get_secure_random_bytes ( ) ) ) ;
839
848
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) ,
841
850
retry_strategy, route_params, router, first_hops, inflight_htlcs, entropy_source,
842
851
node_signer, best_block_height, logger, pending_events, send_payment_along_path)
843
852
. map ( |( ) | payment_hash)
@@ -898,7 +907,7 @@ impl OutboundPayments {
898
907
route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
899
908
}
900
909
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,
902
911
inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
903
912
logger, pending_events, send_payment_along_path
904
913
)
@@ -909,6 +918,7 @@ impl OutboundPayments {
909
918
> (
910
919
& self , payment_id : PaymentId , payment_hash : PaymentHash ,
911
920
keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
921
+ bolt12_invoice : Option < & Bolt12Invoice > ,
912
922
mut route_params : RouteParameters , retry_strategy : Retry , router : & R ,
913
923
first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES , node_signer : & NS ,
914
924
node_id_lookup : & NL , secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 , logger : & L ,
@@ -971,8 +981,8 @@ impl OutboundPayments {
971
981
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
972
982
PendingOutboundPayment :: InvoiceReceived { .. } => {
973
983
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,
976
986
) ;
977
987
* entry. into_mut ( ) = retryable_payment;
978
988
onion_session_privs
@@ -982,7 +992,7 @@ impl OutboundPayments {
982
992
invoice_request
983
993
} else { unreachable ! ( ) } ;
984
994
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,
986
996
Some ( retry_strategy) , payment_params, entropy_source, best_block_height
987
997
) ;
988
998
outbounds. insert ( payment_id, retryable_payment) ;
@@ -1133,7 +1143,7 @@ impl OutboundPayments {
1133
1143
} ;
1134
1144
1135
1145
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,
1137
1147
retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
1138
1148
node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
1139
1149
)
@@ -1257,7 +1267,7 @@ impl OutboundPayments {
1257
1267
///
1258
1268
/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
1259
1269
/// [`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 > (
1261
1271
& self , payment_id : PaymentId , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
1262
1272
keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , mut route_params : RouteParameters ,
1263
1273
router : & R , first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES ,
@@ -1279,7 +1289,7 @@ impl OutboundPayments {
1279
1289
1280
1290
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1281
1291
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 )
1283
1293
. map_err ( |_| {
1284
1294
log_error ! ( logger, "Payment with id {} is already pending. New payment had payment hash {}" ,
1285
1295
payment_id, payment_hash) ;
@@ -1593,7 +1603,7 @@ impl OutboundPayments {
1593
1603
let route = Route { paths : vec ! [ path] , route_params : None } ;
1594
1604
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1595
1605
RecipientOnionFields :: secret_only ( payment_secret) , payment_id, None , & route, None , None ,
1596
- entropy_source, best_block_height
1606
+ entropy_source, best_block_height, None
1597
1607
) . map_err ( |e| {
1598
1608
debug_assert ! ( matches!( e, PaymentSendFailure :: DuplicatePayment ) ) ;
1599
1609
ProbeSendFailure :: DuplicateProbe
@@ -1648,20 +1658,21 @@ impl OutboundPayments {
1648
1658
& self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
1649
1659
route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
1650
1660
) -> 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 )
1652
1662
}
1653
1663
1654
1664
pub ( super ) fn add_new_pending_payment < ES : Deref > (
1655
1665
& self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
1656
1666
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 >
1658
1669
) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
1659
1670
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1660
1671
match pending_outbounds. entry ( payment_id) {
1661
1672
hash_map:: Entry :: Occupied ( _) => Err ( PaymentSendFailure :: DuplicatePayment ) ,
1662
1673
hash_map:: Entry :: Vacant ( entry) => {
1663
1674
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,
1665
1676
payment_params, entropy_source, best_block_height
1666
1677
) ;
1667
1678
entry. insert ( payment) ;
@@ -1673,8 +1684,8 @@ impl OutboundPayments {
1673
1684
fn create_pending_payment < ES : Deref > (
1674
1685
payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
1675
1686
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
1678
1689
) -> ( PendingOutboundPayment , Vec < [ u8 ; 32 ] > )
1679
1690
where
1680
1691
ES :: Target : EntropySource ,
@@ -1696,6 +1707,7 @@ impl OutboundPayments {
1696
1707
payment_metadata : recipient_onion. payment_metadata ,
1697
1708
keysend_preimage,
1698
1709
invoice_request,
1710
+ bolt12_invoice,
1699
1711
custom_tlvs : recipient_onion. custom_tlvs ,
1700
1712
starting_block_height : best_block_height,
1701
1713
total_msat : route. get_total_amount ( ) ,
@@ -2313,6 +2325,7 @@ impl OutboundPayments {
2313
2325
payment_metadata: None , // only used for retries, and we'll never retry on startup
2314
2326
keysend_preimage: None , // only used for retries, and we'll never retry on startup
2315
2327
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
2316
2329
custom_tlvs: Vec :: new( ) , // only used for retries, and we'll never retry on startup
2317
2330
pending_amt_msat: path_amt,
2318
2331
pending_fee_msat: Some ( path_fee) ,
@@ -2402,6 +2415,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
2402
2415
( 10 , starting_block_height, required) ,
2403
2416
( 11 , remaining_max_total_routing_fee_msat, option) ,
2404
2417
( 13 , invoice_request, option) ,
2418
+ ( 15 , bolt12_invoice, option) ,
2405
2419
( not_written, retry_strategy, ( static_value, None ) ) ,
2406
2420
( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
2407
2421
} ,
@@ -2552,7 +2566,7 @@ mod tests {
2552
2566
outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
2553
2567
PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
2554
2568
Some ( Retry :: Attempts ( 1 ) ) , Some ( expired_route_params. payment_params . clone ( ) ) ,
2555
- & & keys_manager, 0 ) . unwrap ( ) ;
2569
+ & & keys_manager, 0 , None ) . unwrap ( ) ;
2556
2570
outbound_payments. find_route_and_send_payment (
2557
2571
PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] ,
2558
2572
& || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
@@ -2595,7 +2609,7 @@ mod tests {
2595
2609
outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
2596
2610
PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
2597
2611
Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params. payment_params . clone ( ) ) ,
2598
- & & keys_manager, 0 ) . unwrap ( ) ;
2612
+ & & keys_manager, 0 , None ) . unwrap ( ) ;
2599
2613
outbound_payments. find_route_and_send_payment (
2600
2614
PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] ,
2601
2615
& || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
0 commit comments