1use core::ops::Deref;
14use core::sync::atomic::{AtomicUsize, Ordering};
15use core::time::Duration;
16
17use bitcoin::block::Header;
18use bitcoin::constants::ChainHash;
19use bitcoin::secp256k1::{self, PublicKey, Secp256k1};
20
21use crate::blinded_path::message::{
22 AsyncPaymentsContext, BlindedMessagePath, MessageContext, MessageForwardNode, OffersContext,
23};
24use crate::blinded_path::payment::{
25 AsyncBolt12OfferContext, BlindedPaymentPath, Bolt12OfferContext, Bolt12RefundContext,
26 PaymentConstraints, PaymentContext, UnauthenticatedReceiveTlvs,
27};
28use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS;
29
30#[allow(unused_imports)]
31use crate::prelude::*;
32
33use crate::chain::BestBlock;
34use crate::ln::channel_state::ChannelDetails;
35use crate::ln::channelmanager::{InterceptId, PaymentId, CLTV_FAR_FAR_AWAY};
36use crate::ln::inbound_payment;
37use crate::offers::async_receive_offer_cache::AsyncReceiveOfferCache;
38use crate::offers::invoice::{
39 Bolt12Invoice, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder,
40 UnsignedBolt12Invoice, DEFAULT_RELATIVE_EXPIRY,
41};
42use crate::offers::invoice_error::InvoiceError;
43use crate::offers::invoice_request::{
44 InvoiceRequest, InvoiceRequestBuilder, VerifiedInvoiceRequest,
45};
46use crate::offers::nonce::Nonce;
47use crate::offers::offer::{Amount, DerivedMetadata, Offer, OfferBuilder};
48use crate::offers::parse::Bolt12SemanticError;
49use crate::offers::refund::{Refund, RefundBuilder};
50use crate::onion_message::async_payments::{
51 AsyncPaymentsMessage, HeldHtlcAvailable, OfferPaths, OfferPathsRequest, ServeStaticInvoice,
52 StaticInvoicePersisted,
53};
54use crate::onion_message::messenger::{
55 Destination, MessageRouter, MessageSendInstructions, Responder, PADDED_PATH_LENGTH,
56};
57use crate::onion_message::offers::OffersMessage;
58use crate::onion_message::packet::OnionMessageContents;
59use crate::routing::router::Router;
60use crate::sign::{EntropySource, NodeSigner, ReceiveAuthKey};
61
62use crate::offers::static_invoice::{StaticInvoice, StaticInvoiceBuilder};
63use crate::sync::{Mutex, RwLock};
64use crate::types::payment::{PaymentHash, PaymentSecret};
65use crate::util::logger::Logger;
66use crate::util::ser::Writeable;
67
68#[cfg(feature = "dnssec")]
69use {
70 crate::blinded_path::message::DNSResolverContext,
71 crate::onion_message::dns_resolution::{DNSResolverMessage, DNSSECQuery, OMNameResolver},
72};
73
74pub struct OffersMessageFlow<MR: Deref, L: Deref>
80where
81 MR::Target: MessageRouter,
82 L::Target: Logger,
83{
84 chain_hash: ChainHash,
85 best_block: RwLock<BestBlock>,
86
87 our_network_pubkey: PublicKey,
88 highest_seen_timestamp: AtomicUsize,
89 inbound_payment_key: inbound_payment::ExpandedKey,
90
91 receive_auth_key: ReceiveAuthKey,
92
93 secp_ctx: Secp256k1<secp256k1::All>,
94 message_router: MR,
95
96 #[cfg(not(any(test, feature = "_test_utils")))]
97 pending_offers_messages: Mutex<Vec<(OffersMessage, MessageSendInstructions)>>,
98 #[cfg(any(test, feature = "_test_utils"))]
99 pub(crate) pending_offers_messages: Mutex<Vec<(OffersMessage, MessageSendInstructions)>>,
100
101 pending_async_payments_messages: Mutex<Vec<(AsyncPaymentsMessage, MessageSendInstructions)>>,
102 async_receive_offer_cache: Mutex<AsyncReceiveOfferCache>,
103
104 #[cfg(feature = "dnssec")]
105 pub(crate) hrn_resolver: OMNameResolver,
106 #[cfg(feature = "dnssec")]
107 pending_dns_onion_messages: Mutex<Vec<(DNSResolverMessage, MessageSendInstructions)>>,
108
109 logger: L,
110}
111
112impl<MR: Deref, L: Deref> OffersMessageFlow<MR, L>
113where
114 MR::Target: MessageRouter,
115 L::Target: Logger,
116{
117 pub fn new(
119 chain_hash: ChainHash, best_block: BestBlock, our_network_pubkey: PublicKey,
120 current_timestamp: u32, inbound_payment_key: inbound_payment::ExpandedKey,
121 receive_auth_key: ReceiveAuthKey, secp_ctx: Secp256k1<secp256k1::All>, message_router: MR,
122 logger: L,
123 ) -> Self {
124 Self {
125 chain_hash,
126 best_block: RwLock::new(best_block),
127
128 our_network_pubkey,
129 highest_seen_timestamp: AtomicUsize::new(current_timestamp as usize),
130 inbound_payment_key,
131
132 receive_auth_key,
133
134 secp_ctx,
135 message_router,
136
137 pending_offers_messages: Mutex::new(Vec::new()),
138 pending_async_payments_messages: Mutex::new(Vec::new()),
139
140 #[cfg(feature = "dnssec")]
141 hrn_resolver: OMNameResolver::new(current_timestamp, best_block.height),
142 #[cfg(feature = "dnssec")]
143 pending_dns_onion_messages: Mutex::new(Vec::new()),
144
145 async_receive_offer_cache: Mutex::new(AsyncReceiveOfferCache::new()),
146
147 logger,
148 }
149 }
150
151 pub fn with_async_payments_offers_cache(
157 mut self, async_receive_offer_cache: AsyncReceiveOfferCache,
158 ) -> Self {
159 self.async_receive_offer_cache = Mutex::new(async_receive_offer_cache);
160 self
161 }
162
163 pub fn set_paths_to_static_invoice_server(
173 &self, paths_to_static_invoice_server: Vec<BlindedMessagePath>,
174 peers: Vec<MessageForwardNode>,
175 ) -> Result<(), ()> {
176 let mut cache = self.async_receive_offer_cache.lock().unwrap();
177 cache.set_paths_to_static_invoice_server(paths_to_static_invoice_server.clone())?;
178 core::mem::drop(cache);
179
180 let _ = self.check_refresh_async_offers(peers, false);
183
184 Ok(())
185 }
186
187 fn get_our_node_id(&self) -> PublicKey {
189 self.our_network_pubkey
190 }
191
192 fn get_receive_auth_key(&self) -> ReceiveAuthKey {
193 self.receive_auth_key
194 }
195
196 fn duration_since_epoch(&self) -> Duration {
197 #[cfg(not(feature = "std"))]
198 let now = Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64);
199 #[cfg(feature = "std")]
200 let now = std::time::SystemTime::now()
201 .duration_since(std::time::SystemTime::UNIX_EPOCH)
202 .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
203 now
204 }
205
206 pub fn best_block_updated(&self, header: &Header, _height: u32) {
214 let timestamp = &self.highest_seen_timestamp;
215 let block_time = header.time as usize;
216
217 loop {
218 let old_serial = timestamp.load(Ordering::Acquire);
224 if old_serial >= block_time {
225 break;
226 }
227 if timestamp
228 .compare_exchange(old_serial, block_time, Ordering::AcqRel, Ordering::Relaxed)
229 .is_ok()
230 {
231 break;
232 }
233 }
234
235 #[cfg(feature = "dnssec")]
236 {
237 let updated_time = timestamp.load(Ordering::Acquire) as u32;
238 self.hrn_resolver.new_best_block(_height, updated_time);
239 }
240 }
241}
242
243pub const MAX_STATIC_INVOICE_SIZE_BYTES: usize = 5 * 1024;
246
247const OFFERS_MESSAGE_REQUEST_LIMIT: usize = 10;
253
254#[cfg(test)]
255pub(crate) const TEST_OFFERS_MESSAGE_REQUEST_LIMIT: usize = OFFERS_MESSAGE_REQUEST_LIMIT;
256
257const TEMP_REPLY_PATH_RELATIVE_EXPIRY: Duration = Duration::from_secs(2 * 60 * 60);
260
261#[cfg(test)]
262pub(crate) const TEST_TEMP_REPLY_PATH_RELATIVE_EXPIRY: Duration = TEMP_REPLY_PATH_RELATIVE_EXPIRY;
263
264const DEFAULT_ASYNC_RECEIVE_OFFER_EXPIRY: Duration = Duration::from_secs(365 * 24 * 60 * 60);
266
267#[cfg(test)]
268pub(crate) const TEST_DEFAULT_ASYNC_RECEIVE_OFFER_EXPIRY: Duration =
269 DEFAULT_ASYNC_RECEIVE_OFFER_EXPIRY;
270
271impl<MR: Deref, L: Deref> OffersMessageFlow<MR, L>
272where
273 MR::Target: MessageRouter,
274 L::Target: Logger,
275{
276 pub fn blinded_paths_for_async_recipient(
286 &self, recipient_id: Vec<u8>, relative_expiry: Option<Duration>,
287 peers: Vec<MessageForwardNode>,
288 ) -> Result<Vec<BlindedMessagePath>, ()> {
289 if recipient_id.len() > 1024 {
290 log_trace!(self.logger, "Async recipient ID exceeds 1024 bytes");
291 return Err(());
292 }
293
294 let path_absolute_expiry =
295 relative_expiry.map(|exp| exp.saturating_add(self.duration_since_epoch()));
296
297 let context = MessageContext::AsyncPayments(AsyncPaymentsContext::OfferPathsRequest {
298 recipient_id,
299 path_absolute_expiry,
300 });
301 self.create_blinded_paths(peers, context)
302 }
303
304 fn create_blinded_paths(
309 &self, peers: Vec<MessageForwardNode>, context: MessageContext,
310 ) -> Result<Vec<BlindedMessagePath>, ()> {
311 let recipient = self.get_our_node_id();
312 let receive_key = self.get_receive_auth_key();
313 let secp_ctx = &self.secp_ctx;
314
315 self.message_router
316 .create_blinded_paths(recipient, receive_key, context, peers, secp_ctx)
317 .and_then(|paths| (!paths.is_empty()).then(|| paths).ok_or(()))
318 }
319
320 fn create_blinded_payment_paths<ES: Deref, R: Deref>(
323 &self, router: &R, entropy_source: ES, usable_channels: Vec<ChannelDetails>,
324 amount_msats: Option<u64>, payment_secret: PaymentSecret, payment_context: PaymentContext,
325 relative_expiry_seconds: u32,
326 ) -> Result<Vec<BlindedPaymentPath>, ()>
327 where
328 ES::Target: EntropySource,
329 R::Target: Router,
330 {
331 let expanded_key = &self.inbound_payment_key;
332 let entropy = &*entropy_source;
333 let secp_ctx = &self.secp_ctx;
334
335 let payee_node_id = self.get_our_node_id();
336
337 const SECONDS_PER_BLOCK: u32 = 9 * 60;
339 let relative_expiry_blocks = relative_expiry_seconds / SECONDS_PER_BLOCK;
340 let max_cltv_expiry = core::cmp::max(relative_expiry_blocks, CLTV_FAR_FAR_AWAY)
341 .saturating_add(LATENCY_GRACE_PERIOD_BLOCKS)
342 .saturating_add(self.best_block.read().unwrap().height);
343
344 let payee_tlvs = UnauthenticatedReceiveTlvs {
345 payment_secret,
346 payment_constraints: PaymentConstraints { max_cltv_expiry, htlc_minimum_msat: 1 },
347 payment_context,
348 };
349 let nonce = Nonce::from_entropy_source(entropy);
350 let payee_tlvs = payee_tlvs.authenticate(nonce, expanded_key);
351
352 router.create_blinded_payment_paths(
353 payee_node_id,
354 usable_channels,
355 payee_tlvs,
356 amount_msats,
357 secp_ctx,
358 )
359 }
360
361 #[cfg(test)]
362 pub(crate) fn test_create_blinded_payment_paths<ES: Deref, R: Deref>(
365 &self, router: &R, entropy_source: ES, usable_channels: Vec<ChannelDetails>,
366 amount_msats: Option<u64>, payment_secret: PaymentSecret, payment_context: PaymentContext,
367 relative_expiry_seconds: u32,
368 ) -> Result<Vec<BlindedPaymentPath>, ()>
369 where
370 ES::Target: EntropySource,
371 R::Target: Router,
372 {
373 self.create_blinded_payment_paths(
374 router,
375 entropy_source,
376 usable_channels,
377 amount_msats,
378 payment_secret,
379 payment_context,
380 relative_expiry_seconds,
381 )
382 }
383}
384
385fn enqueue_onion_message_with_reply_paths<T: OnionMessageContents + Clone>(
386 message: T, message_paths: &[BlindedMessagePath], reply_paths: Vec<BlindedMessagePath>,
387 queue: &mut Vec<(T, MessageSendInstructions)>,
388) {
389 reply_paths
390 .iter()
391 .flat_map(|reply_path| message_paths.iter().map(move |path| (path, reply_path)))
392 .take(OFFERS_MESSAGE_REQUEST_LIMIT)
393 .for_each(|(path, reply_path)| {
394 let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
395 destination: Destination::BlindedPath(path.clone()),
396 reply_path: reply_path.clone(),
397 };
398 queue.push((message.clone(), instructions));
399 });
400}
401
402pub enum InvreqResponseInstructions {
404 SendInvoice(VerifiedInvoiceRequest),
407 SendStaticInvoice {
413 recipient_id: Vec<u8>,
417 invoice_slot: u16,
419 invoice_request: InvoiceRequest,
423 },
424}
425
426pub enum HeldHtlcReplyPath {
428 ToUs {
430 payment_id: PaymentId,
432 peers: Vec<MessageForwardNode>,
434 },
435 ToCounterparty {
441 path: BlindedMessagePath,
443 },
444}
445
446impl<MR: Deref, L: Deref> OffersMessageFlow<MR, L>
447where
448 MR::Target: MessageRouter,
449 L::Target: Logger,
450{
451 pub fn verify_invoice_request(
463 &self, invoice_request: InvoiceRequest, context: Option<OffersContext>,
464 ) -> Result<InvreqResponseInstructions, ()> {
465 let secp_ctx = &self.secp_ctx;
466 let expanded_key = &self.inbound_payment_key;
467
468 let nonce = match context {
469 None if invoice_request.metadata().is_some() => None,
470 Some(OffersContext::InvoiceRequest { nonce }) => Some(nonce),
471 Some(OffersContext::StaticInvoiceRequested {
472 recipient_id,
473 invoice_slot,
474 path_absolute_expiry,
475 }) => {
476 if path_absolute_expiry < self.duration_since_epoch() {
477 log_trace!(self.logger, "Static invoice request has expired");
478 return Err(());
479 }
480
481 return Ok(InvreqResponseInstructions::SendStaticInvoice {
482 recipient_id,
483 invoice_slot,
484 invoice_request,
485 });
486 },
487 _ => return Err(()),
488 };
489
490 let invoice_request = match nonce {
491 Some(nonce) => {
492 invoice_request.verify_using_recipient_data(nonce, expanded_key, secp_ctx)
493 },
494 None => invoice_request.verify_using_metadata(expanded_key, secp_ctx),
495 }?;
496
497 Ok(InvreqResponseInstructions::SendInvoice(invoice_request))
498 }
499
500 pub fn verify_bolt12_invoice(
509 &self, invoice: &Bolt12Invoice, context: Option<&OffersContext>,
510 ) -> Result<PaymentId, ()> {
511 let secp_ctx = &self.secp_ctx;
512 let expanded_key = &self.inbound_payment_key;
513
514 match context {
515 None if invoice.is_for_refund_without_paths() => {
516 invoice.verify_using_metadata(expanded_key, secp_ctx)
517 },
518 Some(&OffersContext::OutboundPayment { payment_id, nonce, .. }) => {
519 invoice.verify_using_payer_data(payment_id, nonce, expanded_key, secp_ctx)
520 },
521 _ => Err(()),
522 }
523 }
524
525 pub fn verify_inbound_async_payment_context(
535 &self, context: AsyncPaymentsContext,
536 ) -> Result<(), ()> {
537 match context {
538 AsyncPaymentsContext::InboundPayment { path_absolute_expiry } => {
539 if self.duration_since_epoch() > path_absolute_expiry {
540 return Err(());
541 }
542 Ok(())
543 },
544 _ => Err(()),
545 }
546 }
547
548 fn create_offer_builder_intern<ES: Deref, PF, I>(
549 &self, entropy_source: ES, make_paths: PF,
550 ) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
551 where
552 ES::Target: EntropySource,
553 PF: FnOnce(
554 PublicKey,
555 MessageContext,
556 &secp256k1::Secp256k1<secp256k1::All>,
557 ) -> Result<I, Bolt12SemanticError>,
558 I: IntoIterator<Item = BlindedMessagePath>,
559 {
560 let node_id = self.get_our_node_id();
561 let expanded_key = &self.inbound_payment_key;
562 let entropy = entropy_source;
563 let secp_ctx = &self.secp_ctx;
564
565 let nonce = Nonce::from_entropy_source(entropy);
566 let context = MessageContext::Offers(OffersContext::InvoiceRequest { nonce });
567
568 let mut builder =
569 OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
570 .chain_hash(self.chain_hash);
571
572 for path in make_paths(node_id, context, secp_ctx)? {
573 builder = builder.path(path)
574 }
575
576 Ok((builder.into(), nonce))
577 }
578
579 pub fn create_offer_builder<ES: Deref>(
606 &self, entropy_source: ES, peers: Vec<MessageForwardNode>,
607 ) -> Result<OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Bolt12SemanticError>
608 where
609 ES::Target: EntropySource,
610 {
611 self.create_offer_builder_intern(&*entropy_source, |_, context, _| {
612 self.create_blinded_paths(peers, context)
613 .map(|paths| paths.into_iter().take(1))
614 .map_err(|_| Bolt12SemanticError::MissingPaths)
615 })
616 .map(|(builder, _)| builder)
617 }
618
619 pub fn create_offer_builder_using_router<ME: Deref, ES: Deref>(
629 &self, router: ME, entropy_source: ES, peers: Vec<MessageForwardNode>,
630 ) -> Result<OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Bolt12SemanticError>
631 where
632 ME::Target: MessageRouter,
633 ES::Target: EntropySource,
634 {
635 let receive_key = self.get_receive_auth_key();
636 self.create_offer_builder_intern(&*entropy_source, |node_id, context, secp_ctx| {
637 router
638 .create_blinded_paths(node_id, receive_key, context, peers, secp_ctx)
639 .map(|paths| paths.into_iter().take(1))
640 .map_err(|_| Bolt12SemanticError::MissingPaths)
641 })
642 .map(|(builder, _)| builder)
643 }
644
645 pub fn create_async_receive_offer_builder<ES: Deref>(
656 &self, entropy_source: ES, message_paths_to_always_online_node: Vec<BlindedMessagePath>,
657 ) -> Result<(OfferBuilder<'_, DerivedMetadata, secp256k1::All>, Nonce), Bolt12SemanticError>
658 where
659 ES::Target: EntropySource,
660 {
661 self.create_offer_builder_intern(&*entropy_source, |_, _, _| {
662 Ok(message_paths_to_always_online_node)
663 })
664 }
665
666 fn create_refund_builder_intern<ES: Deref, PF, I>(
667 &self, entropy_source: ES, make_paths: PF, amount_msats: u64, absolute_expiry: Duration,
668 payment_id: PaymentId,
669 ) -> Result<RefundBuilder<'_, secp256k1::All>, Bolt12SemanticError>
670 where
671 ES::Target: EntropySource,
672 PF: FnOnce(
673 PublicKey,
674 MessageContext,
675 &secp256k1::Secp256k1<secp256k1::All>,
676 ) -> Result<I, Bolt12SemanticError>,
677 I: IntoIterator<Item = BlindedMessagePath>,
678 {
679 let node_id = self.get_our_node_id();
680 let expanded_key = &self.inbound_payment_key;
681 let entropy = &*entropy_source;
682 let secp_ctx = &self.secp_ctx;
683
684 let nonce = Nonce::from_entropy_source(entropy);
685 let context = MessageContext::Offers(OffersContext::OutboundPayment { payment_id, nonce });
686
687 let mut builder = RefundBuilder::deriving_signing_pubkey(
689 node_id,
690 expanded_key,
691 nonce,
692 secp_ctx,
693 amount_msats,
694 payment_id,
695 )?
696 .chain_hash(self.chain_hash)
697 .absolute_expiry(absolute_expiry);
698
699 for path in make_paths(node_id, context, secp_ctx)? {
700 builder = builder.path(path);
701 }
702
703 Ok(builder.into())
704 }
705
706 pub fn create_refund_builder<ES: Deref>(
742 &self, entropy_source: ES, amount_msats: u64, absolute_expiry: Duration,
743 payment_id: PaymentId, peers: Vec<MessageForwardNode>,
744 ) -> Result<RefundBuilder<'_, secp256k1::All>, Bolt12SemanticError>
745 where
746 ES::Target: EntropySource,
747 {
748 self.create_refund_builder_intern(
749 &*entropy_source,
750 |_, context, _| {
751 self.create_blinded_paths(peers, context)
752 .map(|paths| paths.into_iter().take(1))
753 .map_err(|_| Bolt12SemanticError::MissingPaths)
754 },
755 amount_msats,
756 absolute_expiry,
757 payment_id,
758 )
759 }
760
761 pub fn create_refund_builder_using_router<ES: Deref, ME: Deref>(
783 &self, router: ME, entropy_source: ES, amount_msats: u64, absolute_expiry: Duration,
784 payment_id: PaymentId, peers: Vec<MessageForwardNode>,
785 ) -> Result<RefundBuilder<'_, secp256k1::All>, Bolt12SemanticError>
786 where
787 ME::Target: MessageRouter,
788 ES::Target: EntropySource,
789 {
790 let receive_key = self.get_receive_auth_key();
791 self.create_refund_builder_intern(
792 &*entropy_source,
793 |node_id, context, secp_ctx| {
794 router
795 .create_blinded_paths(node_id, receive_key, context, peers, secp_ctx)
796 .map(|paths| paths.into_iter().take(1))
797 .map_err(|_| Bolt12SemanticError::MissingPaths)
798 },
799 amount_msats,
800 absolute_expiry,
801 payment_id,
802 )
803 }
804
805 pub fn create_invoice_request_builder<'a>(
815 &'a self, offer: &'a Offer, nonce: Nonce, payment_id: PaymentId,
816 ) -> Result<InvoiceRequestBuilder<'a, 'a, secp256k1::All>, Bolt12SemanticError> {
817 let expanded_key = &self.inbound_payment_key;
818 let secp_ctx = &self.secp_ctx;
819
820 let builder: InvoiceRequestBuilder<secp256k1::All> =
821 offer.request_invoice(expanded_key, nonce, secp_ctx, payment_id)?.into();
822 let builder = builder.chain_hash(self.chain_hash)?;
823
824 Ok(builder)
825 }
826
827 pub fn create_static_invoice_builder<'a, ES: Deref, R: Deref>(
832 &self, router: &R, entropy_source: ES, offer: &'a Offer, offer_nonce: Nonce,
833 payment_secret: PaymentSecret, relative_expiry_secs: u32,
834 usable_channels: Vec<ChannelDetails>, peers: Vec<MessageForwardNode>,
835 ) -> Result<StaticInvoiceBuilder<'a>, Bolt12SemanticError>
836 where
837 ES::Target: EntropySource,
838 R::Target: Router,
839 {
840 let expanded_key = &self.inbound_payment_key;
841 let entropy = &*entropy_source;
842 let secp_ctx = &self.secp_ctx;
843
844 let payment_context =
845 PaymentContext::AsyncBolt12Offer(AsyncBolt12OfferContext { offer_nonce });
846
847 let amount_msat = offer.amount().and_then(|amount| match amount {
848 Amount::Bitcoin { amount_msats } => Some(amount_msats),
849 Amount::Currency { .. } => None,
850 });
851
852 let created_at = self.duration_since_epoch();
853
854 let payment_paths = self
855 .create_blinded_payment_paths(
856 router,
857 entropy,
858 usable_channels,
859 amount_msat,
860 payment_secret,
861 payment_context,
862 relative_expiry_secs,
863 )
864 .map_err(|()| Bolt12SemanticError::MissingPaths)?;
865
866 let path_absolute_expiry = Duration::from_secs(inbound_payment::calculate_absolute_expiry(
867 created_at.as_secs(),
868 relative_expiry_secs,
869 ));
870
871 let context = MessageContext::AsyncPayments(AsyncPaymentsContext::InboundPayment {
872 path_absolute_expiry,
873 });
874
875 let async_receive_message_paths = self
876 .create_blinded_paths(peers, context)
877 .map_err(|()| Bolt12SemanticError::MissingPaths)?;
878
879 StaticInvoiceBuilder::for_offer_using_derived_keys(
880 offer,
881 payment_paths,
882 async_receive_message_paths,
883 created_at,
884 expanded_key,
885 offer_nonce,
886 secp_ctx,
887 )
888 .map(|inv| inv.allow_mpp().relative_expiry(relative_expiry_secs))
889 }
890
891 pub fn create_invoice_builder_from_refund<'a, ES: Deref, R: Deref>(
906 &'a self, router: &R, entropy_source: ES, refund: &'a Refund, payment_hash: PaymentHash,
907 payment_secret: PaymentSecret, usable_channels: Vec<ChannelDetails>,
908 ) -> Result<InvoiceBuilder<'a, DerivedSigningPubkey>, Bolt12SemanticError>
909 where
910 ES::Target: EntropySource,
911 R::Target: Router,
912 {
913 if refund.chain() != self.chain_hash {
914 return Err(Bolt12SemanticError::UnsupportedChain);
915 }
916
917 let expanded_key = &self.inbound_payment_key;
918 let entropy = &*entropy_source;
919
920 let amount_msats = refund.amount_msats();
921 let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
922
923 let payment_context = PaymentContext::Bolt12Refund(Bolt12RefundContext {});
924 let payment_paths = self
925 .create_blinded_payment_paths(
926 router,
927 entropy,
928 usable_channels,
929 Some(amount_msats),
930 payment_secret,
931 payment_context,
932 relative_expiry,
933 )
934 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
935
936 #[cfg(feature = "std")]
937 let builder = refund.respond_using_derived_keys(
938 payment_paths,
939 payment_hash,
940 expanded_key,
941 entropy,
942 )?;
943
944 #[cfg(not(feature = "std"))]
945 let created_at = Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64);
946 #[cfg(not(feature = "std"))]
947 let builder = refund.respond_using_derived_keys_no_std(
948 payment_paths,
949 payment_hash,
950 created_at,
951 expanded_key,
952 entropy,
953 )?;
954
955 Ok(builder.into())
956 }
957
958 pub fn create_response_for_invoice_request<ES: Deref, NS: Deref, R: Deref>(
967 &self, signer: &NS, router: &R, entropy_source: ES,
968 invoice_request: VerifiedInvoiceRequest, amount_msats: u64, payment_hash: PaymentHash,
969 payment_secret: PaymentSecret, usable_channels: Vec<ChannelDetails>,
970 ) -> (OffersMessage, Option<MessageContext>)
971 where
972 ES::Target: EntropySource,
973 NS::Target: NodeSigner,
974 R::Target: Router,
975 {
976 let entropy = &*entropy_source;
977 let secp_ctx = &self.secp_ctx;
978
979 let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32;
980
981 let context = PaymentContext::Bolt12Offer(Bolt12OfferContext {
982 offer_id: invoice_request.offer_id,
983 invoice_request: invoice_request.fields(),
984 });
985
986 let payment_paths = match self.create_blinded_payment_paths(
987 router,
988 entropy,
989 usable_channels,
990 Some(amount_msats),
991 payment_secret,
992 context,
993 relative_expiry,
994 ) {
995 Ok(paths) => paths,
996 Err(_) => {
997 let error = InvoiceError::from(Bolt12SemanticError::MissingPaths);
998 return (OffersMessage::InvoiceError(error.into()), None);
999 },
1000 };
1001
1002 #[cfg(not(feature = "std"))]
1003 let created_at = Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64);
1004
1005 let response = if invoice_request.keys.is_some() {
1006 #[cfg(feature = "std")]
1007 let builder = invoice_request.respond_using_derived_keys(payment_paths, payment_hash);
1008 #[cfg(not(feature = "std"))]
1009 let builder = invoice_request.respond_using_derived_keys_no_std(
1010 payment_paths,
1011 payment_hash,
1012 created_at,
1013 );
1014 builder
1015 .map(InvoiceBuilder::<DerivedSigningPubkey>::from)
1016 .and_then(|builder| builder.allow_mpp().build_and_sign(secp_ctx))
1017 .map_err(InvoiceError::from)
1018 } else {
1019 #[cfg(feature = "std")]
1020 let builder = invoice_request.respond_with(payment_paths, payment_hash);
1021 #[cfg(not(feature = "std"))]
1022 let builder = invoice_request.respond_with_no_std(payment_paths, payment_hash, created_at);
1023 builder
1024 .map(InvoiceBuilder::<ExplicitSigningPubkey>::from)
1025 .and_then(|builder| builder.allow_mpp().build())
1026 .map_err(InvoiceError::from)
1027 .and_then(|invoice| {
1028 #[cfg(c_bindings)]
1029 let mut invoice = invoice;
1030 invoice
1031 .sign(|invoice: &UnsignedBolt12Invoice| signer.sign_bolt12_invoice(invoice))
1032 .map_err(InvoiceError::from)
1033 })
1034 };
1035
1036 match response {
1037 Ok(invoice) => {
1038 let context =
1039 MessageContext::Offers(OffersContext::InboundPayment { payment_hash });
1040
1041 (OffersMessage::Invoice(invoice), Some(context))
1042 },
1043 Err(error) => (OffersMessage::InvoiceError(error.into()), None),
1044 }
1045 }
1046
1047 pub fn enqueue_invoice_request(
1073 &self, invoice_request: InvoiceRequest, payment_id: PaymentId, nonce: Nonce,
1074 peers: Vec<MessageForwardNode>,
1075 ) -> Result<(), Bolt12SemanticError> {
1076 let context = MessageContext::Offers(OffersContext::OutboundPayment { payment_id, nonce });
1077 let reply_paths = self
1078 .create_blinded_paths(peers, context)
1079 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
1080
1081 let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
1082 if !invoice_request.paths().is_empty() {
1083 let message = OffersMessage::InvoiceRequest(invoice_request.clone());
1084 enqueue_onion_message_with_reply_paths(
1085 message,
1086 invoice_request.paths(),
1087 reply_paths,
1088 &mut pending_offers_messages,
1089 );
1090 } else if let Some(node_id) = invoice_request.issuer_signing_pubkey() {
1091 for reply_path in reply_paths {
1092 let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
1093 destination: Destination::Node(node_id),
1094 reply_path,
1095 };
1096 let message = OffersMessage::InvoiceRequest(invoice_request.clone());
1097 pending_offers_messages.push((message, instructions));
1098 }
1099 } else {
1100 debug_assert!(false);
1101 return Err(Bolt12SemanticError::MissingIssuerSigningPubkey);
1102 }
1103
1104 Ok(())
1105 }
1106
1107 pub fn enqueue_invoice(
1118 &self, invoice: Bolt12Invoice, refund: &Refund, peers: Vec<MessageForwardNode>,
1119 ) -> Result<(), Bolt12SemanticError> {
1120 let payment_hash = invoice.payment_hash();
1121
1122 let context = MessageContext::Offers(OffersContext::InboundPayment { payment_hash });
1123
1124 let reply_paths = self
1125 .create_blinded_paths(peers, context)
1126 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
1127
1128 let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
1129
1130 if refund.paths().is_empty() {
1131 for reply_path in reply_paths {
1132 let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
1133 destination: Destination::Node(refund.payer_signing_pubkey()),
1134 reply_path,
1135 };
1136 let message = OffersMessage::Invoice(invoice.clone());
1137 pending_offers_messages.push((message, instructions));
1138 }
1139 } else {
1140 let message = OffersMessage::Invoice(invoice);
1141 enqueue_onion_message_with_reply_paths(
1142 message,
1143 refund.paths(),
1144 reply_paths,
1145 &mut pending_offers_messages,
1146 );
1147 }
1148
1149 Ok(())
1150 }
1151
1152 pub fn enqueue_static_invoice(
1156 &self, invoice: StaticInvoice, responder: Responder,
1157 ) -> Result<(), Bolt12SemanticError> {
1158 let duration_since_epoch = self.duration_since_epoch();
1159 if invoice.is_expired_no_std(duration_since_epoch) {
1160 return Err(Bolt12SemanticError::AlreadyExpired);
1161 }
1162 if invoice.is_offer_expired_no_std(duration_since_epoch) {
1163 return Err(Bolt12SemanticError::AlreadyExpired);
1164 }
1165
1166 let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
1167 let message = OffersMessage::StaticInvoice(invoice);
1168 pending_offers_messages.push((message, responder.respond().into_instructions()));
1169
1170 Ok(())
1171 }
1172
1173 pub fn enqueue_invoice_request_to_forward(
1183 &self, invoice_request: InvoiceRequest, destination: BlindedMessagePath,
1184 reply_path: Responder,
1185 ) {
1186 let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
1187 let message = OffersMessage::InvoiceRequest(invoice_request);
1188 let instructions = MessageSendInstructions::ForwardedMessage {
1189 destination: Destination::BlindedPath(destination),
1190 reply_path: Some(reply_path.into_blinded_path()),
1191 };
1192 pending_offers_messages.push((message, instructions));
1193 }
1194
1195 pub fn enqueue_held_htlc_available(
1201 &self, invoice: &StaticInvoice, reply_path_params: HeldHtlcReplyPath,
1202 ) -> Result<(), Bolt12SemanticError> {
1203 let reply_path_terminates_at_us =
1204 matches!(reply_path_params, HeldHtlcReplyPath::ToUs { .. });
1205
1206 let reply_paths = match reply_path_params {
1207 HeldHtlcReplyPath::ToUs { payment_id, peers } => {
1208 let context =
1209 MessageContext::AsyncPayments(AsyncPaymentsContext::OutboundPayment {
1210 payment_id,
1211 });
1212 self.create_blinded_paths(peers, context)
1213 .map_err(|_| {
1214 log_trace!(self.logger, "Failed to create blinded paths when enqueueing held_htlc_available message");
1215 Bolt12SemanticError::MissingPaths
1216 })?
1217 },
1218 HeldHtlcReplyPath::ToCounterparty { path } => vec![path],
1219 };
1220
1221 log_trace!(
1222 self.logger,
1223 "Sending held_htlc_available message for async HTLC, with reply_path terminating at {}",
1224 if reply_path_terminates_at_us { "our node" } else { "our always-online counterparty" }
1225 );
1226 let mut pending_async_payments_messages =
1227 self.pending_async_payments_messages.lock().unwrap();
1228 let message = AsyncPaymentsMessage::HeldHtlcAvailable(HeldHtlcAvailable {});
1229 enqueue_onion_message_with_reply_paths(
1230 message,
1231 invoice.message_paths(),
1232 reply_paths,
1233 &mut pending_async_payments_messages,
1234 );
1235
1236 Ok(())
1237 }
1238
1239 pub fn path_for_release_held_htlc<ES: Deref>(
1246 &self, intercept_id: InterceptId, prev_outbound_scid_alias: u64, htlc_id: u64, entropy: ES,
1247 ) -> BlindedMessagePath
1248 where
1249 ES::Target: EntropySource,
1250 {
1251 let context = MessageContext::AsyncPayments(AsyncPaymentsContext::ReleaseHeldHtlc {
1253 intercept_id,
1254 prev_outbound_scid_alias,
1255 htlc_id,
1256 });
1257 let num_dummy_hops = PADDED_PATH_LENGTH.saturating_sub(1);
1258 BlindedMessagePath::new_with_dummy_hops(
1259 &[],
1260 self.get_our_node_id(),
1261 num_dummy_hops,
1262 self.receive_auth_key,
1263 context,
1264 &*entropy,
1265 &self.secp_ctx,
1266 )
1267 }
1268
1269 #[cfg(feature = "dnssec")]
1279 pub fn enqueue_dns_onion_message(
1280 &self, message: DNSSECQuery, context: DNSResolverContext, dns_resolvers: Vec<Destination>,
1281 peers: Vec<MessageForwardNode>,
1282 ) -> Result<(), Bolt12SemanticError> {
1283 let reply_paths = self
1284 .create_blinded_paths(peers, MessageContext::DNSResolver(context))
1285 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
1286
1287 let message_params = dns_resolvers
1288 .iter()
1289 .flat_map(|destination| reply_paths.iter().map(move |path| (path, destination)))
1290 .take(OFFERS_MESSAGE_REQUEST_LIMIT);
1291 for (reply_path, destination) in message_params {
1292 self.pending_dns_onion_messages.lock().unwrap().push((
1293 DNSResolverMessage::DNSSECQuery(message.clone()),
1294 MessageSendInstructions::WithSpecifiedReplyPath {
1295 destination: destination.clone(),
1296 reply_path: reply_path.clone(),
1297 },
1298 ));
1299 }
1300
1301 Ok(())
1302 }
1303
1304 pub fn release_pending_offers_messages(&self) -> Vec<(OffersMessage, MessageSendInstructions)> {
1306 core::mem::take(&mut self.pending_offers_messages.lock().unwrap())
1307 }
1308
1309 pub fn release_pending_async_messages(
1311 &self,
1312 ) -> Vec<(AsyncPaymentsMessage, MessageSendInstructions)> {
1313 core::mem::take(&mut self.pending_async_payments_messages.lock().unwrap())
1314 }
1315
1316 #[cfg(feature = "dnssec")]
1318 pub fn release_pending_dns_messages(
1319 &self,
1320 ) -> Vec<(DNSResolverMessage, MessageSendInstructions)> {
1321 core::mem::take(&mut self.pending_dns_onion_messages.lock().unwrap())
1322 }
1323
1324 pub fn get_async_receive_offer(&self) -> Result<(Offer, bool), ()> {
1331 let mut cache = self.async_receive_offer_cache.lock().unwrap();
1332 cache.get_async_receive_offer(self.duration_since_epoch())
1333 }
1334
1335 #[cfg(test)]
1336 pub(crate) fn test_get_async_receive_offers(&self) -> Vec<Offer> {
1337 self.async_receive_offer_cache.lock().unwrap().test_get_payable_offers()
1338 }
1339
1340 pub fn check_refresh_async_receive_offer_cache<ES: Deref, R: Deref>(
1352 &self, peers: Vec<MessageForwardNode>, usable_channels: Vec<ChannelDetails>, entropy: ES,
1353 router: R, timer_tick_occurred: bool,
1354 ) -> Result<(), ()>
1355 where
1356 ES::Target: EntropySource,
1357 R::Target: Router,
1358 {
1359 {
1361 let cache = self.async_receive_offer_cache.lock().unwrap();
1362 if cache.paths_to_static_invoice_server().is_empty() {
1363 return Ok(());
1364 }
1365 }
1366
1367 self.check_refresh_async_offers(peers.clone(), timer_tick_occurred)?;
1368
1369 if timer_tick_occurred {
1370 self.check_refresh_static_invoices(peers, usable_channels, entropy, router);
1371 }
1372
1373 Ok(())
1374 }
1375
1376 fn check_refresh_async_offers(
1377 &self, peers: Vec<MessageForwardNode>, timer_tick_occurred: bool,
1378 ) -> Result<(), ()> {
1379 let duration_since_epoch = self.duration_since_epoch();
1380 let mut cache = self.async_receive_offer_cache.lock().unwrap();
1381
1382 let needs_new_offer_slot =
1385 match cache.prune_expired_offers(duration_since_epoch, timer_tick_occurred) {
1386 Some(idx) => idx,
1387 None => return Ok(()),
1388 };
1389
1390 let context = MessageContext::AsyncPayments(AsyncPaymentsContext::OfferPaths {
1392 path_absolute_expiry: duration_since_epoch
1393 .saturating_add(TEMP_REPLY_PATH_RELATIVE_EXPIRY),
1394 invoice_slot: needs_new_offer_slot,
1395 });
1396 let reply_paths = match self.create_blinded_paths(peers, context) {
1397 Ok(paths) => paths,
1398 Err(()) => {
1399 log_error!(
1400 self.logger,
1401 "Failed to create blinded paths for OfferPathsRequest message"
1402 );
1403 return Err(());
1404 },
1405 };
1406
1407 cache.new_offers_requested();
1409
1410 let mut pending_async_payments_messages =
1411 self.pending_async_payments_messages.lock().unwrap();
1412 let message = AsyncPaymentsMessage::OfferPathsRequest(OfferPathsRequest {
1413 invoice_slot: needs_new_offer_slot,
1414 });
1415 enqueue_onion_message_with_reply_paths(
1416 message,
1417 cache.paths_to_static_invoice_server(),
1418 reply_paths,
1419 &mut pending_async_payments_messages,
1420 );
1421
1422 Ok(())
1423 }
1424
1425 fn check_refresh_static_invoices<ES: Deref, R: Deref>(
1428 &self, peers: Vec<MessageForwardNode>, usable_channels: Vec<ChannelDetails>, entropy: ES,
1429 router: R,
1430 ) where
1431 ES::Target: EntropySource,
1432 R::Target: Router,
1433 {
1434 let mut serve_static_invoice_msgs = Vec::new();
1435 {
1436 let duration_since_epoch = self.duration_since_epoch();
1437 let cache = self.async_receive_offer_cache.lock().unwrap();
1438 for offer_and_metadata in cache.offers_needing_invoice_refresh(duration_since_epoch) {
1439 let (offer, offer_nonce, update_static_invoice_path) = offer_and_metadata;
1440
1441 let (invoice, forward_invreq_path) = match self.create_static_invoice_for_server(
1442 offer,
1443 offer_nonce,
1444 peers.clone(),
1445 usable_channels.clone(),
1446 &*entropy,
1447 &*router,
1448 ) {
1449 Ok((invoice, path)) => (invoice, path),
1450 Err(()) => continue,
1451 };
1452
1453 let reply_path_context = {
1454 MessageContext::AsyncPayments(AsyncPaymentsContext::StaticInvoicePersisted {
1455 invoice_created_at: invoice.created_at(),
1456 offer_id: offer.id(),
1457 })
1458 };
1459
1460 let serve_invoice_message = ServeStaticInvoice {
1461 invoice,
1462 forward_invoice_request_path: forward_invreq_path,
1463 };
1464 serve_static_invoice_msgs.push((
1465 serve_invoice_message,
1466 update_static_invoice_path.clone(),
1467 reply_path_context,
1468 ));
1469 }
1470 }
1471
1472 for (serve_invoice_msg, serve_invoice_path, reply_path_ctx) in serve_static_invoice_msgs {
1475 let reply_paths = match self.create_blinded_paths(peers.clone(), reply_path_ctx) {
1476 Ok(paths) => paths,
1477 Err(()) => continue,
1478 };
1479
1480 let message = AsyncPaymentsMessage::ServeStaticInvoice(serve_invoice_msg);
1481 enqueue_onion_message_with_reply_paths(
1482 message,
1483 &[serve_invoice_path.into_blinded_path()],
1484 reply_paths,
1485 &mut self.pending_async_payments_messages.lock().unwrap(),
1486 );
1487 }
1488 }
1489
1490 pub fn handle_offer_paths_request(
1494 &self, request: &OfferPathsRequest, context: AsyncPaymentsContext,
1495 peers: Vec<MessageForwardNode>,
1496 ) -> Option<(OfferPaths, MessageContext)> {
1497 let duration_since_epoch = self.duration_since_epoch();
1498
1499 let recipient_id = match context {
1500 AsyncPaymentsContext::OfferPathsRequest { recipient_id, path_absolute_expiry } => {
1501 if duration_since_epoch > path_absolute_expiry.unwrap_or(Duration::MAX) {
1502 return None;
1503 }
1504 recipient_id
1505 },
1506 _ => return None,
1507 };
1508
1509 let (offer_paths, paths_expiry) = {
1511 let path_absolute_expiry =
1512 duration_since_epoch.saturating_add(DEFAULT_ASYNC_RECEIVE_OFFER_EXPIRY);
1513 let context = MessageContext::Offers(OffersContext::StaticInvoiceRequested {
1514 recipient_id: recipient_id.clone(),
1515 path_absolute_expiry,
1516 invoice_slot: request.invoice_slot,
1517 });
1518
1519 match self.create_blinded_paths(peers, context) {
1520 Ok(paths) => (paths, path_absolute_expiry),
1521 Err(()) => {
1522 log_error!(
1523 self.logger,
1524 "Failed to create blinded paths for OfferPaths message"
1525 );
1526 return None;
1527 },
1528 }
1529 };
1530
1531 let reply_path_context = {
1535 let path_absolute_expiry =
1536 duration_since_epoch.saturating_add(DEFAULT_ASYNC_RECEIVE_OFFER_EXPIRY);
1537 MessageContext::AsyncPayments(AsyncPaymentsContext::ServeStaticInvoice {
1538 recipient_id,
1539 invoice_slot: request.invoice_slot,
1540 path_absolute_expiry,
1541 })
1542 };
1543
1544 let offer_paths_om =
1545 OfferPaths { paths: offer_paths, paths_absolute_expiry: Some(paths_expiry.as_secs()) };
1546 return Some((offer_paths_om, reply_path_context));
1547 }
1548
1549 pub fn handle_offer_paths<ES: Deref, R: Deref>(
1556 &self, message: OfferPaths, context: AsyncPaymentsContext, responder: Responder,
1557 peers: Vec<MessageForwardNode>, usable_channels: Vec<ChannelDetails>, entropy: ES,
1558 router: R,
1559 ) -> Option<(ServeStaticInvoice, MessageContext)>
1560 where
1561 ES::Target: EntropySource,
1562 R::Target: Router,
1563 {
1564 let duration_since_epoch = self.duration_since_epoch();
1565 let invoice_slot = match context {
1566 AsyncPaymentsContext::OfferPaths { invoice_slot, path_absolute_expiry } => {
1567 if duration_since_epoch > path_absolute_expiry {
1568 return None;
1569 }
1570 invoice_slot
1571 },
1572 _ => return None,
1573 };
1574
1575 {
1576 let mut cache = self.async_receive_offer_cache.lock().unwrap();
1578 cache.prune_expired_offers(duration_since_epoch, false);
1579 if !cache.should_build_offer_with_paths(
1580 &message.paths[..],
1581 message.paths_absolute_expiry,
1582 invoice_slot,
1583 duration_since_epoch,
1584 ) {
1585 return None;
1586 }
1587 }
1588
1589 let (mut offer_builder, offer_nonce) =
1590 match self.create_async_receive_offer_builder(&*entropy, message.paths) {
1591 Ok((builder, nonce)) => (builder, nonce),
1592 Err(_) => return None, };
1594 if let Some(paths_absolute_expiry) = message.paths_absolute_expiry {
1595 offer_builder =
1596 offer_builder.absolute_expiry(Duration::from_secs(paths_absolute_expiry));
1597 }
1598 let (offer_id, offer) = match offer_builder.build() {
1599 Ok(offer) => (offer.id(), offer),
1600 Err(_) => {
1601 log_error!(self.logger, "Failed to build async receive offer");
1602 debug_assert!(false);
1603 return None;
1604 },
1605 };
1606
1607 let (invoice, forward_invoice_request_path) = match self.create_static_invoice_for_server(
1608 &offer,
1609 offer_nonce,
1610 peers,
1611 usable_channels,
1612 &*entropy,
1613 router,
1614 ) {
1615 Ok(res) => res,
1616 Err(()) => {
1617 log_error!(self.logger, "Failed to create static invoice for server");
1618 return None;
1619 },
1620 };
1621
1622 if let Err(()) = self.async_receive_offer_cache.lock().unwrap().cache_pending_offer(
1623 offer,
1624 message.paths_absolute_expiry,
1625 offer_nonce,
1626 responder,
1627 duration_since_epoch,
1628 invoice_slot,
1629 ) {
1630 log_error!(self.logger, "Failed to cache pending offer");
1631 return None;
1632 }
1633
1634 let reply_path_context = {
1635 MessageContext::AsyncPayments(AsyncPaymentsContext::StaticInvoicePersisted {
1636 offer_id,
1637 invoice_created_at: invoice.created_at(),
1638 })
1639 };
1640
1641 let serve_invoice_message = ServeStaticInvoice { invoice, forward_invoice_request_path };
1642 Some((serve_invoice_message, reply_path_context))
1643 }
1644
1645 fn create_static_invoice_for_server<ES: Deref, R: Deref>(
1648 &self, offer: &Offer, offer_nonce: Nonce, peers: Vec<MessageForwardNode>,
1649 usable_channels: Vec<ChannelDetails>, entropy: ES, router: R,
1650 ) -> Result<(StaticInvoice, BlindedMessagePath), ()>
1651 where
1652 ES::Target: EntropySource,
1653 R::Target: Router,
1654 {
1655 let expanded_key = &self.inbound_payment_key;
1656 let duration_since_epoch = self.duration_since_epoch();
1657 let secp_ctx = &self.secp_ctx;
1658
1659 let offer_relative_expiry = offer
1660 .absolute_expiry()
1661 .map(|exp| exp.saturating_sub(duration_since_epoch).as_secs())
1662 .map(|exp_u64| exp_u64.try_into().unwrap_or(u32::MAX))
1663 .unwrap_or(u32::MAX);
1664
1665 let payment_secret = inbound_payment::create_for_spontaneous_payment(
1669 expanded_key,
1670 None, offer_relative_expiry,
1672 duration_since_epoch.as_secs(),
1673 None,
1674 )?;
1675
1676 let invoice = self
1677 .create_static_invoice_builder(
1678 &router,
1679 &*entropy,
1680 &offer,
1681 offer_nonce,
1682 payment_secret,
1683 offer_relative_expiry,
1684 usable_channels,
1685 peers.clone(),
1686 )
1687 .and_then(|builder| builder.build_and_sign(secp_ctx))
1688 .map_err(|_| ())?;
1689
1690 let context = MessageContext::Offers(OffersContext::InvoiceRequest { nonce: offer_nonce });
1691 let forward_invoice_request_path = self
1692 .create_blinded_paths(peers, context)
1693 .and_then(|paths| paths.into_iter().next().ok_or(()))?;
1694
1695 Ok((invoice, forward_invoice_request_path))
1696 }
1697
1698 pub fn verify_serve_static_invoice_message(
1710 &self, message: &ServeStaticInvoice, context: AsyncPaymentsContext,
1711 ) -> Result<(Vec<u8>, u16), ()> {
1712 if message.invoice.is_expired_no_std(self.duration_since_epoch()) {
1713 log_trace!(self.logger, "Received expired StaticInvoice");
1714 return Err(());
1715 }
1716 if message.invoice.serialized_length() > MAX_STATIC_INVOICE_SIZE_BYTES {
1717 return Err(());
1718 }
1719 match context {
1720 AsyncPaymentsContext::ServeStaticInvoice {
1721 recipient_id,
1722 invoice_slot,
1723 path_absolute_expiry,
1724 } => {
1725 if self.duration_since_epoch() > path_absolute_expiry {
1726 log_trace!(self.logger, "Received expired StaticInvoice path");
1727 return Err(());
1728 }
1729
1730 return Ok((recipient_id, invoice_slot));
1731 },
1732 _ => return Err(()),
1733 };
1734 }
1735
1736 pub fn static_invoice_persisted(&self, responder: Responder) {
1741 let mut pending_async_payments_messages =
1742 self.pending_async_payments_messages.lock().unwrap();
1743 let message = AsyncPaymentsMessage::StaticInvoicePersisted(StaticInvoicePersisted {});
1744 pending_async_payments_messages.push((message, responder.respond().into_instructions()));
1745 }
1746
1747 pub fn handle_static_invoice_persisted(&self, context: AsyncPaymentsContext) -> bool {
1753 let mut cache = self.async_receive_offer_cache.lock().unwrap();
1754 cache.static_invoice_persisted(context)
1755 }
1756
1757 pub fn writeable_async_receive_offer_cache(&self) -> Vec<u8> {
1759 self.async_receive_offer_cache.encode()
1760 }
1761}