@@ -104,6 +104,9 @@ pub(crate) enum PendingOutboundPayment {
104
104
payment_metadata : Option < Vec < u8 > > ,
105
105
keysend_preimage : Option < PaymentPreimage > ,
106
106
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 > ,
107
110
custom_tlvs : Vec < ( u64 , Vec < u8 > ) > ,
108
111
pending_amt_msat : u64 ,
109
112
/// 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, {
153
156
} ) ;
154
157
155
158
impl PendingOutboundPayment {
159
+ fn bolt12_invoice ( & self ) -> Option < & Bolt12Invoice > {
160
+ match self {
161
+ PendingOutboundPayment :: Retryable { bolt12_invoice, .. } => bolt12_invoice. as_ref ( ) ,
162
+ _ => None ,
163
+ }
164
+ }
156
165
fn increment_attempts ( & mut self ) {
157
166
if let PendingOutboundPayment :: Retryable { attempts, .. } = self {
158
167
attempts. count += 1 ;
@@ -813,7 +822,7 @@ impl OutboundPayments {
813
822
IH : Fn ( ) -> InFlightHtlcs ,
814
823
SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
815
824
{
816
- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, None , retry_strategy,
825
+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, None , retry_strategy,
817
826
route_params, router, first_hops, & compute_inflight_htlcs, entropy_source, node_signer,
818
827
best_block_height, logger, pending_events, & send_payment_along_path)
819
828
}
@@ -836,7 +845,7 @@ impl OutboundPayments {
836
845
let preimage = payment_preimage
837
846
. unwrap_or_else ( || PaymentPreimage ( entropy_source. get_secure_random_bytes ( ) ) ) ;
838
847
let payment_hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 ) . to_byte_array ( ) ) ;
839
- self . send_payment_internal ( payment_id, payment_hash, recipient_onion, Some ( preimage) ,
848
+ self . send_payment_for_non_bolt12_invoice ( payment_id, payment_hash, recipient_onion, Some ( preimage) ,
840
849
retry_strategy, route_params, router, first_hops, inflight_htlcs, entropy_source,
841
850
node_signer, best_block_height, logger, pending_events, send_payment_along_path)
842
851
. map ( |( ) | payment_hash)
@@ -896,7 +905,7 @@ impl OutboundPayments {
896
905
route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
897
906
}
898
907
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,
900
909
inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
901
910
logger, pending_events, send_payment_along_path
902
911
)
@@ -907,6 +916,7 @@ impl OutboundPayments {
907
916
> (
908
917
& self , payment_id : PaymentId , payment_hash : PaymentHash ,
909
918
keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
919
+ bolt12_invoice : Option < & Bolt12Invoice > ,
910
920
mut route_params : RouteParameters , retry_strategy : Retry , router : & R ,
911
921
first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES , node_signer : & NS ,
912
922
node_id_lookup : & NL , secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 , logger : & L ,
@@ -969,8 +979,8 @@ impl OutboundPayments {
969
979
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
970
980
PendingOutboundPayment :: InvoiceReceived { .. } => {
971
981
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,
974
984
) ;
975
985
* entry. into_mut ( ) = retryable_payment;
976
986
onion_session_privs
@@ -980,7 +990,7 @@ impl OutboundPayments {
980
990
invoice_request
981
991
} else { unreachable ! ( ) } ;
982
992
let ( retryable_payment, onion_session_privs) = Self :: create_pending_payment (
983
- payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , & route,
993
+ payment_hash, recipient_onion. clone ( ) , keysend_preimage, Some ( invreq) , bolt12_invoice . cloned ( ) , & route,
984
994
Some ( retry_strategy) , payment_params, entropy_source, best_block_height
985
995
) ;
986
996
outbounds. insert ( payment_id, retryable_payment) ;
@@ -1130,7 +1140,7 @@ impl OutboundPayments {
1130
1140
} ;
1131
1141
1132
1142
self . send_payment_for_bolt12_invoice_internal (
1133
- payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , route_params,
1143
+ payment_id, payment_hash, Some ( keysend_preimage) , Some ( & invoice_request) , None , route_params,
1134
1144
retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
1135
1145
node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
1136
1146
)
@@ -1254,7 +1264,7 @@ impl OutboundPayments {
1254
1264
///
1255
1265
/// [`Event::PaymentPathFailed`]: crate::events::Event::PaymentPathFailed
1256
1266
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
1257
- fn send_payment_internal < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
1267
+ fn send_payment_for_non_bolt12_invoice < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
1258
1268
& self , payment_id : PaymentId , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
1259
1269
keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , mut route_params : RouteParameters ,
1260
1270
router : & R , first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES ,
@@ -1276,7 +1286,7 @@ impl OutboundPayments {
1276
1286
1277
1287
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1278
1288
recipient_onion. clone ( ) , payment_id, keysend_preimage, & route, Some ( retry_strategy) ,
1279
- Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height)
1289
+ Some ( route_params. payment_params . clone ( ) ) , entropy_source, best_block_height, None )
1280
1290
. map_err ( |_| {
1281
1291
log_error ! ( logger, "Payment with id {} is already pending. New payment had payment hash {}" ,
1282
1292
payment_id, payment_hash) ;
@@ -1590,7 +1600,7 @@ impl OutboundPayments {
1590
1600
let route = Route { paths : vec ! [ path] , route_params : None } ;
1591
1601
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1592
1602
RecipientOnionFields :: secret_only ( payment_secret) , payment_id, None , & route, None , None ,
1593
- entropy_source, best_block_height
1603
+ entropy_source, best_block_height, None
1594
1604
) . map_err ( |e| {
1595
1605
debug_assert ! ( matches!( e, PaymentSendFailure :: DuplicatePayment ) ) ;
1596
1606
ProbeSendFailure :: DuplicateProbe
@@ -1645,20 +1655,21 @@ impl OutboundPayments {
1645
1655
& self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
1646
1656
route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
1647
1657
) -> 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)
1658
+ self . add_new_pending_payment ( payment_hash, recipient_onion, payment_id, None , route, retry_strategy, None , entropy_source, best_block_height, None )
1649
1659
}
1650
1660
1651
1661
pub ( super ) fn add_new_pending_payment < ES : Deref > (
1652
1662
& self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
1653
1663
keysend_preimage : Option < PaymentPreimage > , route : & Route , retry_strategy : Option < Retry > ,
1654
- payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
1664
+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32 ,
1665
+ bolt12_invoice : Option < Bolt12Invoice >
1655
1666
) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
1656
1667
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1657
1668
match pending_outbounds. entry ( payment_id) {
1658
1669
hash_map:: Entry :: Occupied ( _) => Err ( PaymentSendFailure :: DuplicatePayment ) ,
1659
1670
hash_map:: Entry :: Vacant ( entry) => {
1660
1671
let ( payment, onion_session_privs) = Self :: create_pending_payment (
1661
- payment_hash, recipient_onion, keysend_preimage, None , route, retry_strategy,
1672
+ payment_hash, recipient_onion, keysend_preimage, None , bolt12_invoice , route, retry_strategy,
1662
1673
payment_params, entropy_source, best_block_height
1663
1674
) ;
1664
1675
entry. insert ( payment) ;
@@ -1670,8 +1681,8 @@ impl OutboundPayments {
1670
1681
fn create_pending_payment < ES : Deref > (
1671
1682
payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
1672
1683
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
1684
+ bolt12_invoice : Option < Bolt12Invoice > , route : & Route , retry_strategy : Option < Retry > ,
1685
+ payment_params : Option < PaymentParameters > , entropy_source : & ES , best_block_height : u32
1675
1686
) -> ( PendingOutboundPayment , Vec < [ u8 ; 32 ] > )
1676
1687
where
1677
1688
ES :: Target : EntropySource ,
@@ -1693,6 +1704,7 @@ impl OutboundPayments {
1693
1704
payment_metadata : recipient_onion. payment_metadata ,
1694
1705
keysend_preimage,
1695
1706
invoice_request,
1707
+ bolt12_invoice,
1696
1708
custom_tlvs : recipient_onion. custom_tlvs ,
1697
1709
starting_block_height : best_block_height,
1698
1710
total_msat : route. get_total_amount ( ) ,
@@ -2310,6 +2322,7 @@ impl OutboundPayments {
2310
2322
payment_metadata: None , // only used for retries, and we'll never retry on startup
2311
2323
keysend_preimage: None , // only used for retries, and we'll never retry on startup
2312
2324
invoice_request: None , // only used for retries, and we'll never retry on startup
2325
+ bolt12_invoice: None , // only used for retries, and we'll never retry on startup! TODO(vincenzopalazzo): double check this
2313
2326
custom_tlvs: Vec :: new( ) , // only used for retries, and we'll never retry on startup
2314
2327
pending_amt_msat: path_amt,
2315
2328
pending_fee_msat: Some ( path_fee) ,
@@ -2399,6 +2412,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
2399
2412
( 10 , starting_block_height, required) ,
2400
2413
( 11 , remaining_max_total_routing_fee_msat, option) ,
2401
2414
( 13 , invoice_request, option) ,
2415
+ ( 15 , bolt12_invoice, option) ,
2402
2416
( not_written, retry_strategy, ( static_value, None ) ) ,
2403
2417
( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
2404
2418
} ,
@@ -2516,7 +2530,7 @@ mod tests {
2516
2530
outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
2517
2531
PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
2518
2532
Some ( Retry :: Attempts ( 1 ) ) , Some ( expired_route_params. payment_params . clone ( ) ) ,
2519
- & & keys_manager, 0 ) . unwrap ( ) ;
2533
+ & & keys_manager, 0 , None ) . unwrap ( ) ;
2520
2534
outbound_payments. find_route_and_send_payment (
2521
2535
PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] ,
2522
2536
& || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
@@ -2559,7 +2573,7 @@ mod tests {
2559
2573
outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
2560
2574
PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
2561
2575
Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params. payment_params . clone ( ) ) ,
2562
- & & keys_manager, 0 ) . unwrap ( ) ;
2576
+ & & keys_manager, 0 , None ) . unwrap ( ) ;
2563
2577
outbound_payments. find_route_and_send_payment (
2564
2578
PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] ,
2565
2579
& || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
0 commit comments