@@ -8542,16 +8542,15 @@ where
85428542
85438543macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
85448544 /// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
8545- /// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer. The offer will
8546- /// not have an expiration unless otherwise set on the builder .
8545+ /// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer. The offer's
8546+ /// expiration will be `absolute_expiry` if `Some`, otherwise it will not expire .
85478547 ///
85488548 /// # Privacy
85498549 ///
8550- /// Uses [`MessageRouter::create_compact_blinded_paths`] to construct a [`BlindedPath`] for the
8551- /// offer. However, if one is not found, uses a one-hop [`BlindedPath`] with
8552- /// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case,
8553- /// the node must be announced, otherwise, there is no way to find a path to the introduction in
8554- /// order to send the [`InvoiceRequest`].
8550+ /// Uses [`MessageRouter`] to construct a [`BlindedPath`] for the offer. However, if one is not
8551+ /// found, uses a one-hop [`BlindedPath`] with [`ChannelManager::get_our_node_id`] as the
8552+ /// introduction node instead. In the latter case, the node must be announced, otherwise, there
8553+ /// is no way to find a path to the introduction in order to send the [`InvoiceRequest`].
85558554 ///
85568555 /// Also, uses a derived signing pubkey in the offer for recipient privacy.
85578556 ///
@@ -8566,20 +8565,27 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
85668565 ///
85678566 /// [`Offer`]: crate::offers::offer::Offer
85688567 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
8569- pub fn create_offer_builder(&$self) -> Result<$builder, Bolt12SemanticError> {
8568+ pub fn create_offer_builder(
8569+ &$self, absolute_expiry: Option<Duration>
8570+ ) -> Result<$builder, Bolt12SemanticError> {
85708571 let node_id = $self.get_our_node_id();
85718572 let expanded_key = &$self.inbound_payment_key;
85728573 let entropy = &*$self.entropy_source;
85738574 let secp_ctx = &$self.secp_ctx;
85748575
8575- let path = $self.create_compact_blinded_path( )
8576+ let path = $self.create_blinded_path_using_absolute_expiry(absolute_expiry )
85768577 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
85778578 let builder = OfferBuilder::deriving_signing_pubkey(
85788579 node_id, expanded_key, entropy, secp_ctx
85798580 )
85808581 .chain_hash($self.chain_hash)
85818582 .path(path);
85828583
8584+ let builder = match absolute_expiry {
8585+ None => builder,
8586+ Some(absolute_expiry) => builder.absolute_expiry(absolute_expiry),
8587+ };
8588+
85838589 Ok(builder.into())
85848590 }
85858591} }
@@ -8607,11 +8613,10 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
86078613 ///
86088614 /// # Privacy
86098615 ///
8610- /// Uses [`MessageRouter::create_compact_blinded_paths`] to construct a [`BlindedPath`] for the
8611- /// refund. However, if one is not found, uses a one-hop [`BlindedPath`] with
8612- /// [`ChannelManager::get_our_node_id`] as the introduction node instead. In the latter case,
8613- /// the node must be announced, otherwise, there is no way to find a path to the introduction in
8614- /// order to send the [`Bolt12Invoice`].
8616+ /// Uses [`MessageRouter`] to construct a [`BlindedPath`] for the refund. However, if one is not
8617+ /// found, uses a one-hop [`BlindedPath`] with [`ChannelManager::get_our_node_id`] as the
8618+ /// introduction node instead. In the latter case, the node must be announced, otherwise, there
8619+ /// is no way to find a path to the introduction in order to send the [`Bolt12Invoice`].
86158620 ///
86168621 /// Also, uses a derived payer id in the refund for payer privacy.
86178622 ///
@@ -8640,7 +8645,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
86408645 let entropy = &*$self.entropy_source;
86418646 let secp_ctx = &$self.secp_ctx;
86428647
8643- let path = $self.create_compact_blinded_path( )
8648+ let path = $self.create_blinded_path_using_absolute_expiry(Some(absolute_expiry) )
86448649 .map_err(|_| Bolt12SemanticError::MissingPaths)?;
86458650 let builder = RefundBuilder::deriving_payer_id(
86468651 node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id
@@ -8990,6 +8995,33 @@ where
89908995 inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
89918996 }
89928997
8998+ /// Creates a blinded path by delegating to [`MessageRouter`] based on the path's intended
8999+ /// lifetime.
9000+ ///
9001+ /// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
9002+ /// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch.
9003+ fn create_blinded_path_using_absolute_expiry(
9004+ &self, absolute_expiry: Option<Duration>
9005+ ) -> Result<BlindedPath, ()> {
9006+ const MAX_SHORT_LIVED_RELATIVE_EXPIRY: Duration = Duration::from_secs(60 * 60 * 24);
9007+
9008+ #[cfg(not(feature = "std"))]
9009+ let now = Duration::from_secs(
9010+ self.highest_seen_timestamp.load(Ordering::Acquire) as u64
9011+ );
9012+ #[cfg(feature = "std")]
9013+ let now = std::time::SystemTime::now()
9014+ .duration_since(std::time::SystemTime::UNIX_EPOCH)
9015+ .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
9016+
9017+ let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
9018+ if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
9019+ self.create_compact_blinded_path()
9020+ } else {
9021+ self.create_blinded_path()
9022+ }
9023+ }
9024+
89939025 /// Creates a blinded path by delegating to [`MessageRouter::create_blinded_paths`].
89949026 ///
89959027 /// Errors if the `MessageRouter` errors or returns an empty `Vec`.
0 commit comments