@@ -67,7 +67,7 @@ use crate::ln::wire::Encode;
67
67
use crate::offers::invoice::{Bolt12Invoice, DerivedSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice, DEFAULT_RELATIVE_EXPIRY};
68
68
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
69
69
use crate::offers::nonce::Nonce;
70
- use crate::offers::offer::{ Offer, OfferBuilder} ;
70
+ use crate::offers::offer::Offer;
71
71
use crate::offers::parse::Bolt12SemanticError;
72
72
use crate::offers::refund::{Refund, RefundBuilder};
73
73
use crate::offers::signer;
@@ -94,7 +94,6 @@ use crate::onion_message::dns_resolution::{DNSResolverMessage, DNSResolverMessag
94
94
95
95
#[cfg(not(c_bindings))]
96
96
use {
97
- crate::offers::offer::DerivedMetadata,
98
97
crate::onion_message::messenger::DefaultMessageRouter,
99
98
crate::routing::router::DefaultRouter,
100
99
crate::routing::gossip::NetworkGraph,
@@ -1899,7 +1898,7 @@ where
1899
1898
///
1900
1899
/// ```
1901
1900
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
1902
- /// # use lightning::ln::channelmanager::{AChannelManager, Bolt11InvoiceParameters};
1901
+ /// # use lightning::ln::channelmanager::{AChannelManager, Bolt11InvoiceParameters, OffersMessageCommons };
1903
1902
/// #
1904
1903
/// # fn example<T: AChannelManager>(channel_manager: T) {
1905
1904
/// # let channel_manager = channel_manager.get_cm();
@@ -2001,55 +2000,7 @@ where
2001
2000
///
2002
2001
/// ## BOLT 12 Offers
2003
2002
///
2004
- /// The [`offers`] module is useful for creating BOLT 12 offers. An [`Offer`] is a precursor to a
2005
- /// [`Bolt12Invoice`], which must first be requested by the payer. The interchange of these messages
2006
- /// as defined in the specification is handled by [`ChannelManager`]. However, this only works with
2007
- /// an [`Offer`] created using a builder returned by [`create_offer_builder`]. With this approach,
2008
- /// BOLT 12 offers and invoices are stateless just as BOLT 11 invoices are.
2009
- ///
2010
- /// ```
2011
- /// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
2012
- /// # use lightning::ln::channelmanager::AChannelManager;
2013
- /// # use lightning::offers::parse::Bolt12SemanticError;
2014
- /// #
2015
- /// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
2016
- /// # let channel_manager = channel_manager.get_cm();
2017
- /// # let absolute_expiry = None;
2018
- /// let offer = channel_manager
2019
- /// .create_offer_builder(absolute_expiry)?
2020
- /// # ;
2021
- /// # // Needed for compiling for c_bindings
2022
- /// # let builder: lightning::offers::offer::OfferBuilder<_, _> = offer.into();
2023
- /// # let offer = builder
2024
- /// .description("coffee".to_string())
2025
- /// .amount_msats(10_000_000)
2026
- /// .build()?;
2027
- /// let bech32_offer = offer.to_string();
2028
- ///
2029
- /// // On the event processing thread
2030
- /// channel_manager.process_pending_events(&|event| {
2031
- /// match event {
2032
- /// Event::PaymentClaimable { payment_hash, purpose, .. } => match purpose {
2033
- /// PaymentPurpose::Bolt12OfferPayment { payment_preimage: Some(payment_preimage), .. } => {
2034
- /// println!("Claiming payment {}", payment_hash);
2035
- /// channel_manager.claim_funds(payment_preimage);
2036
- /// },
2037
- /// PaymentPurpose::Bolt12OfferPayment { payment_preimage: None, .. } => {
2038
- /// println!("Unknown payment hash: {}", payment_hash);
2039
- /// }
2040
- /// # _ => {},
2041
- /// },
2042
- /// Event::PaymentClaimed { payment_hash, amount_msat, .. } => {
2043
- /// println!("Claimed {} msats", amount_msat);
2044
- /// },
2045
- /// // ...
2046
- /// # _ => {},
2047
- /// }
2048
- /// Ok(())
2049
- /// });
2050
- /// # Ok(())
2051
- /// # }
2052
- /// ```
2003
+ /// For more information on creating offers, see [`create_offer_builder`].
2053
2004
///
2054
2005
/// Use [`pay_for_offer`] to initiated payment, which sends an [`InvoiceRequest`] for an [`Offer`]
2055
2006
/// and pays the [`Bolt12Invoice`] response.
@@ -2170,7 +2121,7 @@ where
2170
2121
///
2171
2122
/// ```
2172
2123
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
2173
- /// # use lightning::ln::channelmanager::AChannelManager;
2124
+ /// # use lightning::ln::channelmanager::{ AChannelManager, OffersMessageCommons} ;
2174
2125
/// # use lightning::offers::refund::Refund;
2175
2126
/// #
2176
2127
/// # fn example<T: AChannelManager>(channel_manager: T, refund: &Refund) {
@@ -2289,7 +2240,6 @@ where
2289
2240
/// [`claim_funds`]: Self::claim_funds
2290
2241
/// [`send_payment`]: Self::send_payment
2291
2242
/// [`offers`]: crate::offers
2292
- /// [`create_offer_builder`]: Self::create_offer_builder
2293
2243
/// [`pay_for_offer`]: Self::pay_for_offer
2294
2244
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
2295
2245
/// [`create_refund_builder`]: Self::create_refund_builder
@@ -2301,6 +2251,7 @@ where
2301
2251
/// [`update_channel`]: chain::Watch::update_channel
2302
2252
/// [`ChannelUpdate`]: msgs::ChannelUpdate
2303
2253
/// [`read`]: ReadableArgs::read
2254
+ /// [`create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2304
2255
//
2305
2256
// Lock order:
2306
2257
// The tree structure below illustrates the lock order requirements for the different locks of the
@@ -2791,11 +2742,13 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
2791
2742
/// The maximum expiration from the current time where an [`Offer`] or [`Refund`] is considered
2792
2743
/// short-lived, while anything with a greater expiration is considered long-lived.
2793
2744
///
2794
- /// Using [`ChannelManager ::create_offer_builder`] or [`ChannelManager::create_refund_builder`],
2745
+ /// Using [`OffersMessageFlow ::create_offer_builder`] or [`ChannelManager::create_refund_builder`],
2795
2746
/// will included a [`BlindedMessagePath`] created using:
2796
2747
/// - [`MessageRouter::create_compact_blinded_paths`] when short-lived, and
2797
2748
/// - [`MessageRouter::create_blinded_paths`] when long-lived.
2798
2749
///
2750
+ /// [`OffersMessageFlow::create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2751
+ ///
2799
2752
/// Using compact [`BlindedMessagePath`]s may provide better privacy as the [`MessageRouter`] could select
2800
2753
/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to
2801
2754
/// become invalid over time as channels are closed. Thus, they are only suitable for short-term use.
@@ -6818,7 +6771,7 @@ where
6818
6771
/// [`Event::PaymentClaimable::claim_deadline`]: crate::events::Event::PaymentClaimable::claim_deadline
6819
6772
/// [`Event::PaymentClaimed`]: crate::events::Event::PaymentClaimed
6820
6773
/// [`process_pending_events`]: EventsProvider::process_pending_events
6821
- /// [`create_inbound_payment`]: Self ::create_inbound_payment
6774
+ /// [`create_inbound_payment`]: ChannelManager ::create_inbound_payment
6822
6775
/// [`create_inbound_payment_for_hash`]: ChannelManager::create_inbound_payment_for_hash
6823
6776
/// [`claim_funds_with_known_custom_tlvs`]: ChannelManager::claim_funds_with_known_custom_tlvs
6824
6777
pub fn claim_funds(&self, payment_preimage: PaymentPreimage) {
@@ -9386,57 +9339,6 @@ impl Default for Bolt11InvoiceParameters {
9386
9339
}
9387
9340
}
9388
9341
9389
- macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
9390
- /// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
9391
- /// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer. The offer's
9392
- /// expiration will be `absolute_expiry` if `Some`, otherwise it will not expire.
9393
- ///
9394
- /// # Privacy
9395
- ///
9396
- /// Uses [`MessageRouter`] to construct a [`BlindedMessagePath`] for the offer based on the given
9397
- /// `absolute_expiry` according to [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. See those docs for
9398
- /// privacy implications as well as those of the parameterized [`Router`], which implements
9399
- /// [`MessageRouter`].
9400
- ///
9401
- /// Also, uses a derived signing pubkey in the offer for recipient privacy.
9402
- ///
9403
- /// # Limitations
9404
- ///
9405
- /// Requires a direct connection to the introduction node in the responding [`InvoiceRequest`]'s
9406
- /// reply path.
9407
- ///
9408
- /// # Errors
9409
- ///
9410
- /// Errors if the parameterized [`Router`] is unable to create a blinded path for the offer.
9411
- ///
9412
- /// [`Offer`]: crate::offers::offer::Offer
9413
- /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
9414
- pub fn create_offer_builder(
9415
- &$self, absolute_expiry: Option<Duration>
9416
- ) -> Result<$builder, Bolt12SemanticError> {
9417
- let node_id = $self.get_our_node_id();
9418
- let expanded_key = &$self.inbound_payment_key;
9419
- let entropy = &*$self.entropy_source;
9420
- let secp_ctx = &$self.secp_ctx;
9421
-
9422
- let nonce = Nonce::from_entropy_source(entropy);
9423
- let context = OffersContext::InvoiceRequest { nonce };
9424
- let path = $self.create_blinded_paths_using_absolute_expiry(context, absolute_expiry)
9425
- .and_then(|paths| paths.into_iter().next().ok_or(()))
9426
- .map_err(|_| Bolt12SemanticError::MissingPaths)?;
9427
- let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
9428
- .chain_hash($self.chain_hash)
9429
- .path(path);
9430
-
9431
- let builder = match absolute_expiry {
9432
- None => builder,
9433
- Some(absolute_expiry) => builder.absolute_expiry(absolute_expiry),
9434
- };
9435
-
9436
- Ok(builder.into())
9437
- }
9438
- } }
9439
-
9440
9342
macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
9441
9343
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
9442
9344
/// [`ChannelManager`] when handling [`Bolt12Invoice`] messages for the refund.
@@ -9519,7 +9421,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
9519
9421
} }
9520
9422
9521
9423
/// Functions commonly shared in usage between [`ChannelManager`] & [`OffersMessageFlow`]
9522
- ///
9424
+ ///
9523
9425
/// [`OffersMessageFlow`]: crate::offers::flow::OffersMessageFlow
9524
9426
pub trait OffersMessageCommons {
9525
9427
/// Get pending offers messages
@@ -9621,7 +9523,18 @@ pub trait OffersMessageCommons {
9621
9523
/// Get the current time determined by highest seen timestamp
9622
9524
fn get_current_blocktime(&self) -> Duration;
9623
9525
9526
+ /// Creates a collection of blinded paths by delegating to [`MessageRouter`] based on
9527
+ /// the path's intended lifetime.
9528
+ ///
9529
+ /// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
9530
+ /// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
9531
+ /// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
9532
+ fn create_blinded_paths_using_absolute_expiry(
9533
+ &self, context: OffersContext, absolute_expiry: Option<Duration>,
9534
+ ) -> Result<Vec<BlindedMessagePath>, ()>;
9624
9535
9536
+ /// Get the [`ChainHash`] of the chain
9537
+ fn get_chain_hash(&self) -> ChainHash;
9625
9538
}
9626
9539
9627
9540
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref> OffersMessageCommons for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
@@ -9786,6 +9699,23 @@ where
9786
9699
fn get_current_blocktime(&self) -> Duration {
9787
9700
Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64)
9788
9701
}
9702
+
9703
+ fn create_blinded_paths_using_absolute_expiry(
9704
+ &self, context: OffersContext, absolute_expiry: Option<Duration>,
9705
+ ) -> Result<Vec<BlindedMessagePath>, ()> {
9706
+ let now = self.duration_since_epoch();
9707
+ let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
9708
+
9709
+ if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
9710
+ self.create_compact_blinded_paths(context)
9711
+ } else {
9712
+ self.create_blinded_paths(MessageContext::Offers(context))
9713
+ }
9714
+ }
9715
+
9716
+ fn get_chain_hash(&self) -> ChainHash {
9717
+ self.chain_hash
9718
+ }
9789
9719
}
9790
9720
9791
9721
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -9807,13 +9737,9 @@ where
9807
9737
MR::Target: MessageRouter,
9808
9738
L::Target: Logger,
9809
9739
{
9810
- #[cfg(not(c_bindings))]
9811
- create_offer_builder!(self, OfferBuilder<DerivedMetadata, secp256k1::All>);
9812
9740
#[cfg(not(c_bindings))]
9813
9741
create_refund_builder!(self, RefundBuilder<secp256k1::All>);
9814
9742
9815
- #[cfg(c_bindings)]
9816
- create_offer_builder!(self, OfferWithDerivedMetadataBuilder);
9817
9743
#[cfg(c_bindings)]
9818
9744
create_refund_builder!(self, RefundMaybeWithDerivedMetadataBuilder);
9819
9745
@@ -10165,25 +10091,6 @@ where
10165
10091
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
10166
10092
}
10167
10093
10168
- /// Creates a collection of blinded paths by delegating to [`MessageRouter`] based on
10169
- /// the path's intended lifetime.
10170
- ///
10171
- /// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
10172
- /// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
10173
- /// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
10174
- fn create_blinded_paths_using_absolute_expiry(
10175
- &self, context: OffersContext, absolute_expiry: Option<Duration>,
10176
- ) -> Result<Vec<BlindedMessagePath>, ()> {
10177
- let now = self.duration_since_epoch();
10178
- let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
10179
-
10180
- if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
10181
- self.create_compact_blinded_paths(context)
10182
- } else {
10183
- self.create_blinded_paths(MessageContext::Offers(context))
10184
- }
10185
- }
10186
-
10187
10094
pub(super) fn duration_since_epoch(&self) -> Duration {
10188
10095
#[cfg(not(feature = "std"))]
10189
10096
let now = Duration::from_secs(
@@ -15158,7 +15065,7 @@ pub mod bench {
15158
15065
use crate::chain::chainmonitor::{ChainMonitor, Persist};
15159
15066
use crate::sign::{KeysManager, InMemorySigner};
15160
15067
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider};
15161
- use crate::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId, RecipientOnionFields, Retry};
15068
+ use crate::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, OffersMessageCommons, PaymentHash, PaymentPreimage, PaymentId, RecipientOnionFields, Retry};
15162
15069
use crate::ln::functional_test_utils::*;
15163
15070
use crate::ln::msgs::{ChannelMessageHandler, Init};
15164
15071
use crate::routing::gossip::NetworkGraph;
0 commit comments