@@ -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+.
@@ -148,6 +151,12 @@ impl_writeable_tlv_based!(RetryableInvoiceRequest, {
148
151
} ) ;
149
152
150
153
impl PendingOutboundPayment {
154
+ fn bolt12_invoice ( & self ) -> Option < & Bolt12Invoice > {
155
+ match self {
156
+ PendingOutboundPayment :: Retryable { bolt12_invoice, .. } => bolt12_invoice. as_ref ( ) ,
157
+ _ => None ,
158
+ }
159
+ }
151
160
fn increment_attempts ( & mut self ) {
152
161
if let PendingOutboundPayment :: Retryable { attempts, .. } = self {
153
162
attempts. count += 1 ;
@@ -879,7 +888,7 @@ impl OutboundPayments {
879
888
route_params. max_total_routing_fee_msat = Some ( max_fee_msat) ;
880
889
}
881
890
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,
883
892
inflight_htlcs, entropy_source, node_signer, node_id_lookup, secp_ctx, best_block_height,
884
893
logger, pending_events, send_payment_along_path
885
894
)
@@ -890,6 +899,7 @@ impl OutboundPayments {
890
899
> (
891
900
& self , payment_id : PaymentId , payment_hash : PaymentHash ,
892
901
keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
902
+ bolt12_invoice : Option < & Bolt12Invoice > ,
893
903
mut route_params : RouteParameters , retry_strategy : Retry , router : & R ,
894
904
first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES , node_signer : & NS ,
895
905
node_id_lookup : & NL , secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 , logger : & L ,
@@ -952,18 +962,20 @@ impl OutboundPayments {
952
962
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
953
963
PendingOutboundPayment :: InvoiceReceived { .. } => {
954
964
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,
957
967
) ;
958
968
* entry. into_mut ( ) = retryable_payment;
959
969
onion_session_privs
960
970
} ,
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
961
973
PendingOutboundPayment :: StaticInvoiceReceived { .. } => {
962
974
let invreq = if let PendingOutboundPayment :: StaticInvoiceReceived { invoice_request, .. } = entry. remove ( ) {
963
975
invoice_request
964
976
} else { unreachable ! ( ) } ;
965
977
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,
967
979
Some ( retry_strategy) , payment_params, entropy_source, best_block_height
968
980
) ;
969
981
outbounds. insert ( payment_id, retryable_payment) ;
@@ -1113,7 +1125,7 @@ impl OutboundPayments {
1113
1125
} ;
1114
1126
1115
1127
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,
1117
1129
retry_strategy, router, first_hops, inflight_htlcs, entropy_source, node_signer,
1118
1130
node_id_lookup, secp_ctx, best_block_height, logger, pending_events, send_payment_along_path
1119
1131
)
@@ -1259,7 +1271,7 @@ impl OutboundPayments {
1259
1271
1260
1272
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1261
1273
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 )
1263
1275
. map_err ( |_| {
1264
1276
log_error ! ( logger, "Payment with id {} is already pending. New payment had payment hash {}" ,
1265
1277
payment_id, payment_hash) ;
@@ -1573,7 +1585,7 @@ impl OutboundPayments {
1573
1585
let route = Route { paths : vec ! [ path] , route_params : None } ;
1574
1586
let onion_session_privs = self . add_new_pending_payment ( payment_hash,
1575
1587
RecipientOnionFields :: secret_only ( payment_secret) , payment_id, None , & route, None , None ,
1576
- entropy_source, best_block_height
1588
+ entropy_source, best_block_height, None
1577
1589
) . map_err ( |e| {
1578
1590
debug_assert ! ( matches!( e, PaymentSendFailure :: DuplicatePayment ) ) ;
1579
1591
ProbeSendFailure :: DuplicateProbe
@@ -1628,20 +1640,21 @@ impl OutboundPayments {
1628
1640
& self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
1629
1641
route : & Route , retry_strategy : Option < Retry > , entropy_source : & ES , best_block_height : u32
1630
1642
) -> 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 )
1632
1644
}
1633
1645
1634
1646
pub ( super ) fn add_new_pending_payment < ES : Deref > (
1635
1647
& self , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields , payment_id : PaymentId ,
1636
1648
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 >
1638
1651
) -> Result < Vec < [ u8 ; 32 ] > , PaymentSendFailure > where ES :: Target : EntropySource {
1639
1652
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1640
1653
match pending_outbounds. entry ( payment_id) {
1641
1654
hash_map:: Entry :: Occupied ( _) => Err ( PaymentSendFailure :: DuplicatePayment ) ,
1642
1655
hash_map:: Entry :: Vacant ( entry) => {
1643
1656
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,
1645
1658
payment_params, entropy_source, best_block_height
1646
1659
) ;
1647
1660
entry. insert ( payment) ;
@@ -1653,8 +1666,8 @@ impl OutboundPayments {
1653
1666
fn create_pending_payment < ES : Deref > (
1654
1667
payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
1655
1668
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
1658
1671
) -> ( PendingOutboundPayment , Vec < [ u8 ; 32 ] > )
1659
1672
where
1660
1673
ES :: Target : EntropySource ,
@@ -1676,6 +1689,7 @@ impl OutboundPayments {
1676
1689
payment_metadata : recipient_onion. payment_metadata ,
1677
1690
keysend_preimage,
1678
1691
invoice_request,
1692
+ bolt12_invoice,
1679
1693
custom_tlvs : recipient_onion. custom_tlvs ,
1680
1694
starting_block_height : best_block_height,
1681
1695
total_msat : route. get_total_amount ( ) ,
@@ -2291,6 +2305,7 @@ impl OutboundPayments {
2291
2305
payment_metadata: None , // only used for retries, and we'll never retry on startup
2292
2306
keysend_preimage: None , // only used for retries, and we'll never retry on startup
2293
2307
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
2294
2309
custom_tlvs: Vec :: new( ) , // only used for retries, and we'll never retry on startup
2295
2310
pending_amt_msat: path_amt,
2296
2311
pending_fee_msat: Some ( path_fee) ,
@@ -2379,6 +2394,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
2379
2394
( 10 , starting_block_height, required) ,
2380
2395
( 11 , remaining_max_total_routing_fee_msat, option) ,
2381
2396
( 13 , invoice_request, option) ,
2397
+ ( 15 , bolt12_invoice, option) ,
2382
2398
( not_written, retry_strategy, ( static_value, None ) ) ,
2383
2399
( not_written, attempts, ( static_value, PaymentAttempts :: new( ) ) ) ,
2384
2400
} ,
@@ -2496,7 +2512,7 @@ mod tests {
2496
2512
outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
2497
2513
PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
2498
2514
Some ( Retry :: Attempts ( 1 ) ) , Some ( expired_route_params. payment_params . clone ( ) ) ,
2499
- & & keys_manager, 0 ) . unwrap ( ) ;
2515
+ & & keys_manager, 0 , None ) . unwrap ( ) ;
2500
2516
outbound_payments. find_route_and_send_payment (
2501
2517
PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , expired_route_params, & & router, vec ! [ ] ,
2502
2518
& || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
@@ -2540,7 +2556,7 @@ mod tests {
2540
2556
outbound_payments. add_new_pending_payment ( PaymentHash ( [ 0 ; 32 ] ) , RecipientOnionFields :: spontaneous_empty ( ) ,
2541
2557
PaymentId ( [ 0 ; 32 ] ) , None , & Route { paths : vec ! [ ] , route_params : None } ,
2542
2558
Some ( Retry :: Attempts ( 1 ) ) , Some ( route_params. payment_params . clone ( ) ) ,
2543
- & & keys_manager, 0 ) . unwrap ( ) ;
2559
+ & & keys_manager, 0 , None ) . unwrap ( ) ;
2544
2560
outbound_payments. find_route_and_send_payment (
2545
2561
PaymentHash ( [ 0 ; 32 ] ) , PaymentId ( [ 0 ; 32 ] ) , route_params, & & router, vec ! [ ] ,
2546
2562
& || InFlightHtlcs :: new ( ) , & & keys_manager, & & keys_manager, 0 , & & logger, & pending_events,
0 commit comments