@@ -13,6 +13,7 @@ use bitcoin::hashes::Hash;
13
13
use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
14
14
use bitcoin:: secp256k1:: { self , Secp256k1 , SecretKey } ;
15
15
16
+ use crate :: offers:: invoice_request:: InvoiceRequest ;
16
17
use crate :: sign:: { EntropySource , NodeSigner , Recipient } ;
17
18
use crate :: events:: { self , PaymentFailureReason } ;
18
19
use crate :: ln:: types:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
@@ -31,6 +32,7 @@ use crate::util::ser::ReadableArgs;
31
32
32
33
use core:: fmt:: { self , Display , Formatter } ;
33
34
use core:: ops:: Deref ;
35
+ use core:: sync:: atomic:: { AtomicBool , Ordering } ;
34
36
use core:: time:: Duration ;
35
37
36
38
use crate :: prelude:: * ;
@@ -52,6 +54,7 @@ pub(crate) enum PendingOutboundPayment {
52
54
expiration : StaleExpiration ,
53
55
retry_strategy : Retry ,
54
56
max_total_routing_fee_msat : Option < u64 > ,
57
+ invoice_request : Option < InvoiceRequest > ,
55
58
} ,
56
59
InvoiceReceived {
57
60
payment_hash : PaymentHash ,
@@ -677,13 +680,15 @@ pub(super) struct SendAlongPathArgs<'a> {
677
680
678
681
pub ( super ) struct OutboundPayments {
679
682
pub ( super ) pending_outbound_payments : Mutex < HashMap < PaymentId , PendingOutboundPayment > > ,
683
+ pub ( super ) awaiting_invoice_flag : AtomicBool ,
680
684
pub ( super ) retry_lock : Mutex < ( ) > ,
681
685
}
682
686
683
687
impl OutboundPayments {
684
688
pub ( super ) fn new ( ) -> Self {
685
689
Self {
686
690
pending_outbound_payments : Mutex :: new ( new_hash_map ( ) ) ,
691
+ awaiting_invoice_flag : AtomicBool :: new ( false ) ,
687
692
retry_lock : Mutex :: new ( ( ) ) ,
688
693
}
689
694
}
@@ -1310,7 +1315,7 @@ impl OutboundPayments {
1310
1315
1311
1316
pub ( super ) fn add_new_awaiting_invoice (
1312
1317
& self , payment_id : PaymentId , expiration : StaleExpiration , retry_strategy : Retry ,
1313
- max_total_routing_fee_msat : Option < u64 >
1318
+ max_total_routing_fee_msat : Option < u64 > , invoice_request : Option < InvoiceRequest >
1314
1319
) -> Result < ( ) , ( ) > {
1315
1320
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1316
1321
match pending_outbounds. entry ( payment_id) {
@@ -1320,6 +1325,7 @@ impl OutboundPayments {
1320
1325
expiration,
1321
1326
retry_strategy,
1322
1327
max_total_routing_fee_msat,
1328
+ invoice_request,
1323
1329
} ) ;
1324
1330
1325
1331
Ok ( ( ) )
@@ -1786,6 +1792,30 @@ impl OutboundPayments {
1786
1792
pub fn clear_pending_payments ( & self ) {
1787
1793
self . pending_outbound_payments . lock ( ) . unwrap ( ) . clear ( )
1788
1794
}
1795
+
1796
+ pub fn set_awaiting_invoice_flag ( & self ) {
1797
+ let pending_outbound_payments = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1798
+ let has_invoice_requests = pending_outbound_payments. values ( ) . any ( |payment| {
1799
+ matches ! ( payment, PendingOutboundPayment :: AwaitingInvoice { invoice_request: Some ( _) , .. } )
1800
+ } ) ;
1801
+ self . awaiting_invoice_flag . store ( has_invoice_requests, Ordering :: SeqCst ) ;
1802
+ }
1803
+
1804
+ pub fn get_invoice_request_awaiting_invoice ( & self ) -> Vec < InvoiceRequest > {
1805
+ if !self . awaiting_invoice_flag . load ( Ordering :: SeqCst ) {
1806
+ return vec ! [ ] ;
1807
+ }
1808
+ let mut pending_outbound_payments = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1809
+ let invoice_requests = pending_outbound_payments. values_mut ( )
1810
+ . filter_map ( |payment| match payment {
1811
+ PendingOutboundPayment :: AwaitingInvoice { invoice_request, .. } => invoice_request. take ( ) ,
1812
+ _ => None ,
1813
+ } )
1814
+ . collect ( ) ;
1815
+
1816
+ self . awaiting_invoice_flag . store ( false , Ordering :: SeqCst ) ;
1817
+ invoice_requests
1818
+ }
1789
1819
}
1790
1820
1791
1821
/// Returns whether a payment with the given [`PaymentHash`] and [`PaymentId`] is, in fact, a
@@ -1841,6 +1871,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
1841
1871
( 0 , expiration, required) ,
1842
1872
( 2 , retry_strategy, required) ,
1843
1873
( 4 , max_total_routing_fee_msat, option) ,
1874
+ ( 6 , invoice_request, option) ,
1844
1875
} ,
1845
1876
( 7 , InvoiceReceived ) => {
1846
1877
( 0 , payment_hash, required) ,
@@ -2078,7 +2109,7 @@ mod tests {
2078
2109
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
2079
2110
assert ! (
2080
2111
outbound_payments. add_new_awaiting_invoice(
2081
- payment_id, expiration, Retry :: Attempts ( 0 ) , None
2112
+ payment_id, expiration, Retry :: Attempts ( 0 ) , None , None
2082
2113
) . is_ok( )
2083
2114
) ;
2084
2115
assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -2104,14 +2135,14 @@ mod tests {
2104
2135
2105
2136
assert ! (
2106
2137
outbound_payments. add_new_awaiting_invoice(
2107
- payment_id, expiration, Retry :: Attempts ( 0 ) , None
2138
+ payment_id, expiration, Retry :: Attempts ( 0 ) , None , None
2108
2139
) . is_ok( )
2109
2140
) ;
2110
2141
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2111
2142
2112
2143
assert ! (
2113
2144
outbound_payments. add_new_awaiting_invoice(
2114
- payment_id, expiration, Retry :: Attempts ( 0 ) , None
2145
+ payment_id, expiration, Retry :: Attempts ( 0 ) , None , None
2115
2146
) . is_err( )
2116
2147
) ;
2117
2148
}
@@ -2127,7 +2158,7 @@ mod tests {
2127
2158
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
2128
2159
assert ! (
2129
2160
outbound_payments. add_new_awaiting_invoice(
2130
- payment_id, expiration, Retry :: Attempts ( 0 ) , None
2161
+ payment_id, expiration, Retry :: Attempts ( 0 ) , None , None
2131
2162
) . is_ok( )
2132
2163
) ;
2133
2164
assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -2153,14 +2184,14 @@ mod tests {
2153
2184
2154
2185
assert ! (
2155
2186
outbound_payments. add_new_awaiting_invoice(
2156
- payment_id, expiration, Retry :: Attempts ( 0 ) , None
2187
+ payment_id, expiration, Retry :: Attempts ( 0 ) , None , None
2157
2188
) . is_ok( )
2158
2189
) ;
2159
2190
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2160
2191
2161
2192
assert ! (
2162
2193
outbound_payments. add_new_awaiting_invoice(
2163
- payment_id, expiration, Retry :: Attempts ( 0 ) , None
2194
+ payment_id, expiration, Retry :: Attempts ( 0 ) , None , None
2164
2195
) . is_err( )
2165
2196
) ;
2166
2197
}
@@ -2175,7 +2206,7 @@ mod tests {
2175
2206
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
2176
2207
assert ! (
2177
2208
outbound_payments. add_new_awaiting_invoice(
2178
- payment_id, expiration, Retry :: Attempts ( 0 ) , None
2209
+ payment_id, expiration, Retry :: Attempts ( 0 ) , None , None
2179
2210
) . is_ok( )
2180
2211
) ;
2181
2212
assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -2208,7 +2239,7 @@ mod tests {
2208
2239
2209
2240
assert ! (
2210
2241
outbound_payments. add_new_awaiting_invoice(
2211
- payment_id, expiration, Retry :: Attempts ( 0 ) , None
2242
+ payment_id, expiration, Retry :: Attempts ( 0 ) , None , None
2212
2243
) . is_ok( )
2213
2244
) ;
2214
2245
assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -2270,7 +2301,7 @@ mod tests {
2270
2301
assert ! (
2271
2302
outbound_payments. add_new_awaiting_invoice(
2272
2303
payment_id, expiration, Retry :: Attempts ( 0 ) ,
2273
- Some ( invoice. amount_msats( ) / 100 + 50_000 )
2304
+ Some ( invoice. amount_msats( ) / 100 + 50_000 ) , None
2274
2305
) . is_ok( )
2275
2306
) ;
2276
2307
assert ! ( outbound_payments. has_pending_payments( ) ) ;
@@ -2367,7 +2398,7 @@ mod tests {
2367
2398
2368
2399
assert ! (
2369
2400
outbound_payments. add_new_awaiting_invoice(
2370
- payment_id, expiration, Retry :: Attempts ( 0 ) , Some ( 1234 )
2401
+ payment_id, expiration, Retry :: Attempts ( 0 ) , Some ( 1234 ) , None
2371
2402
) . is_ok( )
2372
2403
) ;
2373
2404
assert ! ( outbound_payments. has_pending_payments( ) ) ;
0 commit comments