@@ -16,7 +16,7 @@ use bitcoin::{secp256k1, Network};
16
16
use types:: payment:: PaymentHash ;
17
17
use crate :: blinded_path:: message:: { BlindedMessagePath , MessageContext , MessageForwardNode , OffersContext } ;
18
18
use crate :: blinded_path:: payment:: BlindedPaymentPath ;
19
- use crate :: ln:: channelmanager:: PaymentId ;
19
+ use crate :: ln:: channelmanager:: { PaymentId , MAX_SHORT_LIVED_RELATIVE_EXPIRY , OFFERS_MESSAGE_REQUEST_LIMIT } ;
20
20
use crate :: ln:: inbound_payment;
21
21
use crate :: onion_message:: dns_resolution:: { DNSSECQuery , HumanReadableName } ;
22
22
use crate :: sign:: EntropySource ;
@@ -142,4 +142,234 @@ where
142
142
pub fn get_our_node_id ( & self ) -> PublicKey {
143
143
self . our_network_pubkey
144
144
}
145
- }
145
+
146
+ fn duration_since_epoch ( & self ) -> Duration {
147
+ #[ cfg( not( feature = "std" ) ) ]
148
+ let now = Duration :: from_secs (
149
+ self . highest_seen_timestamp . load ( Ordering :: Acquire ) as u64
150
+ ) ;
151
+ #[ cfg( feature = "std" ) ]
152
+ let now = std:: time:: SystemTime :: now ( )
153
+ . duration_since ( std:: time:: SystemTime :: UNIX_EPOCH )
154
+ . expect ( "SystemTime::now() should come after SystemTime::UNIX_EPOCH" ) ;
155
+
156
+ now
157
+ }
158
+ }
159
+
160
+ impl < ES : Deref , MR : Deref > Flow for OffersMessageFlow < ES , MR >
161
+ where
162
+ ES :: Target : EntropySource ,
163
+ MR :: Target : MessageRouter ,
164
+ {
165
+ fn create_offer_builder ( & self , nonce : Nonce ) -> Result < OfferBuilder < DerivedMetadata , secp256k1:: All > , Bolt12SemanticError > {
166
+ let node_id = self . get_our_node_id ( ) ;
167
+ let expanded_key = & self . inbound_payment_key ;
168
+ let secp_ctx = & self . secp_ctx ;
169
+
170
+ let builder = OfferBuilder :: deriving_signing_pubkey ( node_id, expanded_key, nonce, secp_ctx)
171
+ . chain_hash ( self . chain_hash ) ;
172
+
173
+ Ok ( builder)
174
+ }
175
+
176
+ fn create_refund_builder ( & self , amount_msats : u64 , absolute_expiry : Duration , payment_id : PaymentId , nonce : Nonce ) -> Result < RefundBuilder < secp256k1:: All > , Bolt12SemanticError > {
177
+ let node_id = self . get_our_node_id ( ) ;
178
+ let expanded_key = & self . inbound_payment_key ;
179
+ let secp_ctx = & self . secp_ctx ;
180
+
181
+ let builder = RefundBuilder :: deriving_signing_pubkey (
182
+ node_id, expanded_key, nonce, secp_ctx, amount_msats, payment_id
183
+ ) ?
184
+ . chain_hash ( self . chain_hash )
185
+ . absolute_expiry ( absolute_expiry) ;
186
+
187
+ Ok ( builder)
188
+ }
189
+
190
+ fn create_invoice_request_builder < ' a > (
191
+ & ' a self , offer : & ' a Offer , nonce : Nonce , quantity : Option < u64 > , amount_msats : Option < u64 > ,
192
+ payer_note : Option < String > , human_readable_name : Option < HumanReadableName > , payment_id : PaymentId
193
+ ) -> Result < InvoiceRequestBuilder < ' a , ' a , secp256k1:: All > , Bolt12SemanticError > {
194
+ let expanded_key = & self . inbound_payment_key ;
195
+ let secp_ctx = & self . secp_ctx ;
196
+
197
+ let builder = offer
198
+ . request_invoice ( expanded_key, nonce, secp_ctx, payment_id) ?
199
+ . chain_hash ( self . chain_hash ) ?;
200
+
201
+ let builder = match quantity {
202
+ None => builder,
203
+ Some ( quantity) => builder. quantity ( quantity) ?,
204
+ } ;
205
+ let builder = match amount_msats {
206
+ None => builder,
207
+ Some ( amount_msats) => builder. amount_msats ( amount_msats) ?,
208
+ } ;
209
+ let builder = match payer_note {
210
+ None => builder,
211
+ Some ( payer_note) => builder. payer_note ( payer_note) ,
212
+ } ;
213
+ let builder = match human_readable_name {
214
+ None => builder,
215
+ Some ( hrn) => builder. sourced_from_human_readable_name ( hrn) ,
216
+ } ;
217
+
218
+ Ok ( builder. into ( ) )
219
+ }
220
+
221
+ fn create_invoice_builder < ' a > (
222
+ & ' a self , refund : & ' a Refund , payment_paths : Vec < BlindedPaymentPath > , payment_hash : PaymentHash
223
+ ) -> Result < InvoiceBuilder < ' a , DerivedSigningPubkey > , Bolt12SemanticError > {
224
+ let expanded_key = & self . inbound_payment_key ;
225
+ let entropy = & * self . entropy_source ;
226
+
227
+ #[ cfg( feature = "std" ) ]
228
+ let builder = refund. respond_using_derived_keys (
229
+ payment_paths, payment_hash, expanded_key, entropy
230
+ ) ?;
231
+ #[ cfg( not( feature = "std" ) ) ]
232
+ let created_at = Duration :: from_secs (
233
+ self . highest_seen_timestamp . load ( Ordering :: Acquire ) as u64
234
+ ) ;
235
+ #[ cfg( not( feature = "std" ) ) ]
236
+ let builder = refund. respond_using_derived_keys_no_std (
237
+ payment_paths, payment_hash, created_at, expanded_key, entropy
238
+ ) ?;
239
+ let builder: InvoiceBuilder < DerivedSigningPubkey > = builder. into ( ) ;
240
+
241
+ Ok ( builder)
242
+ }
243
+
244
+ fn create_blinded_paths ( & self , peers : Vec < MessageForwardNode > , context : MessageContext ) -> Result < Vec < BlindedMessagePath > , ( ) > {
245
+ let recipient = self . get_our_node_id ( ) ;
246
+ let secp_ctx = & self . secp_ctx ;
247
+
248
+ let peers = peers
249
+ . iter ( )
250
+ . map ( |node| node. node_id )
251
+ . collect :: < Vec < _ > > ( ) ;
252
+
253
+ self . message_router
254
+ . create_blinded_paths ( recipient, context, peers, secp_ctx)
255
+ . and_then ( |paths| ( !paths. is_empty ( ) ) . then ( || paths) . ok_or ( ( ) ) )
256
+ }
257
+
258
+ fn create_compact_blinded_paths ( & self , peers : Vec < MessageForwardNode > , context : OffersContext ) -> Result < Vec < BlindedMessagePath > , ( ) > {
259
+ let recipient = self . get_our_node_id ( ) ;
260
+ let secp_ctx = & self . secp_ctx ;
261
+
262
+ self . message_router
263
+ . create_compact_blinded_paths ( recipient, MessageContext :: Offers ( context) , peers, secp_ctx)
264
+ . and_then ( |paths| ( !paths. is_empty ( ) ) . then ( || paths) . ok_or ( ( ) ) )
265
+ }
266
+
267
+ fn create_blinded_paths_using_absolute_expiry ( & self , peers : Vec < MessageForwardNode > , context : OffersContext , absolute_expiry : Option < Duration > ) -> Result < Vec < BlindedMessagePath > , ( ) > {
268
+ let now = self . duration_since_epoch ( ) ;
269
+ let max_short_lived_absolute_expiry = now. saturating_add ( MAX_SHORT_LIVED_RELATIVE_EXPIRY ) ;
270
+
271
+ if absolute_expiry. unwrap_or ( Duration :: MAX ) <= max_short_lived_absolute_expiry {
272
+ self . create_compact_blinded_paths ( peers, context)
273
+ } else {
274
+ self . create_blinded_paths ( peers, MessageContext :: Offers ( context) )
275
+ }
276
+ }
277
+
278
+ fn enqueue_invoice_request (
279
+ & self , invoice_request : InvoiceRequest , reply_paths : Vec < BlindedMessagePath >
280
+ ) -> Result < ( ) , Bolt12SemanticError > {
281
+ let mut pending_offers_messages = self . pending_offers_messages . lock ( ) . unwrap ( ) ;
282
+ if !invoice_request. paths ( ) . is_empty ( ) {
283
+ reply_paths
284
+ . iter ( )
285
+ . flat_map ( |reply_path| invoice_request. paths ( ) . iter ( ) . map ( move |path| ( path, reply_path) ) )
286
+ . take ( OFFERS_MESSAGE_REQUEST_LIMIT )
287
+ . for_each ( |( path, reply_path) | {
288
+ let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
289
+ destination : Destination :: BlindedPath ( path. clone ( ) ) ,
290
+ reply_path : reply_path. clone ( ) ,
291
+ } ;
292
+ let message = OffersMessage :: InvoiceRequest ( invoice_request. clone ( ) ) ;
293
+ pending_offers_messages. push ( ( message, instructions) ) ;
294
+ } ) ;
295
+ } else if let Some ( node_id) = invoice_request. issuer_signing_pubkey ( ) {
296
+ for reply_path in reply_paths {
297
+ let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
298
+ destination : Destination :: Node ( node_id) ,
299
+ reply_path,
300
+ } ;
301
+ let message = OffersMessage :: InvoiceRequest ( invoice_request. clone ( ) ) ;
302
+ pending_offers_messages. push ( ( message, instructions) ) ;
303
+ }
304
+ } else {
305
+ debug_assert ! ( false ) ;
306
+ return Err ( Bolt12SemanticError :: MissingIssuerSigningPubkey ) ;
307
+ }
308
+
309
+ Ok ( ( ) )
310
+ }
311
+
312
+ fn enqueue_invoice (
313
+ & self , invoice : Bolt12Invoice , refund : & Refund , reply_paths : Vec < BlindedMessagePath >
314
+ ) -> Result < ( ) , Bolt12SemanticError > {
315
+ let mut pending_offers_messages = self . pending_offers_messages . lock ( ) . unwrap ( ) ;
316
+ if refund. paths ( ) . is_empty ( ) {
317
+ for reply_path in reply_paths {
318
+ let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
319
+ destination : Destination :: Node ( refund. payer_signing_pubkey ( ) ) ,
320
+ reply_path,
321
+ } ;
322
+ let message = OffersMessage :: Invoice ( invoice. clone ( ) ) ;
323
+ pending_offers_messages. push ( ( message, instructions) ) ;
324
+ }
325
+ } else {
326
+ reply_paths
327
+ . iter ( )
328
+ . flat_map ( |reply_path| refund. paths ( ) . iter ( ) . map ( move |path| ( path, reply_path) ) )
329
+ . take ( OFFERS_MESSAGE_REQUEST_LIMIT )
330
+ . for_each ( |( path, reply_path) | {
331
+ let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
332
+ destination : Destination :: BlindedPath ( path. clone ( ) ) ,
333
+ reply_path : reply_path. clone ( ) ,
334
+ } ;
335
+ let message = OffersMessage :: Invoice ( invoice. clone ( ) ) ;
336
+ pending_offers_messages. push ( ( message, instructions) ) ;
337
+ } ) ;
338
+ }
339
+
340
+ Ok ( ( ) )
341
+ }
342
+
343
+ fn enqueue_dns_onion_message (
344
+ & self , message : DNSSECQuery , dns_resolvers : Vec < Destination > , reply_paths : Vec < BlindedMessagePath >
345
+ ) -> Result < ( ) , Bolt12SemanticError > {
346
+ let message_params = dns_resolvers
347
+ . iter ( )
348
+ . flat_map ( |destination| reply_paths. iter ( ) . map ( move |path| ( path, destination) ) )
349
+ . take ( OFFERS_MESSAGE_REQUEST_LIMIT ) ;
350
+ for ( reply_path, destination) in message_params {
351
+ self . pending_dns_onion_messages . lock ( ) . unwrap ( ) . push ( (
352
+ DNSResolverMessage :: DNSSECQuery ( message. clone ( ) ) ,
353
+ MessageSendInstructions :: WithSpecifiedReplyPath {
354
+ destination : destination. clone ( ) ,
355
+ reply_path : reply_path. clone ( ) ,
356
+ } ,
357
+ ) ) ;
358
+ }
359
+
360
+ Ok ( ( ) )
361
+ }
362
+
363
+ fn get_and_clear_pending_offers_messages ( & self ) -> Vec < ( OffersMessage , MessageSendInstructions ) > {
364
+ core:: mem:: take ( & mut self . pending_offers_messages . lock ( ) . unwrap ( ) )
365
+ }
366
+
367
+ fn get_and_clear_pending_async_messages ( & self ) -> Vec < ( AsyncPaymentsMessage , MessageSendInstructions ) > {
368
+ core:: mem:: take ( & mut self . pending_async_payments_messages . lock ( ) . unwrap ( ) )
369
+ }
370
+
371
+ #[ cfg( feature = "dnssec" ) ]
372
+ fn get_and_clear_pending_dns_messages ( & self ) -> Vec < ( DNSResolverMessage , MessageSendInstructions ) > {
373
+ core:: mem:: take ( & mut self . pending_dns_onion_messages . lock ( ) . unwrap ( ) )
374
+ }
375
+ }
0 commit comments