Skip to content

Commit 92e633a

Browse files
committed
Move create_offer_builder to OffersMessageFlow
1 parent 1e0ce24 commit 92e633a

File tree

7 files changed

+241
-163
lines changed

7 files changed

+241
-163
lines changed

fuzz/src/full_stack.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use lightning::ln::peer_handler::{
4949
};
5050
use lightning::ln::script::ShutdownScript;
5151
use lightning::ln::types::ChannelId;
52+
use lightning::offers::flow::OffersMessageCommons;
5253
use lightning::offers::invoice::UnsignedBolt12Invoice;
5354
use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessagePath};
5455
use lightning::routing::gossip::{NetworkGraph, P2PGossipSync};

lightning-dns-resolver/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ mod test {
391391
let name = HumanReadableName::from_encoded("[email protected]").unwrap();
392392

393393
// When we get the proof back, override its contents to an offer from nodes[1]
394-
let bs_offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
394+
let bs_offer = nodes[1].offers_handler.create_offer_builder(None).unwrap().build().unwrap();
395395
nodes[0]
396396
.node
397397
.testing_dnssec_proof_offer_resolution_override

lightning/src/ln/channelmanager.rs

Lines changed: 29 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use crate::ln::outbound_payment::{OutboundPayments, PendingOutboundPayment, Retr
6868
use crate::offers::invoice::{Bolt12Invoice, DerivedSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice, DEFAULT_RELATIVE_EXPIRY};
6969
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
7070
use crate::offers::nonce::Nonce;
71-
use crate::offers::offer::{Offer, OfferBuilder};
71+
use crate::offers::offer::Offer;
7272
use crate::offers::parse::Bolt12SemanticError;
7373
use crate::offers::refund::{Refund, RefundBuilder};
7474
use crate::offers::signer;
@@ -96,18 +96,14 @@ use crate::onion_message::dns_resolution::{DNSResolverMessage, DNSResolverMessag
9696

9797
#[cfg(not(c_bindings))]
9898
use {
99-
crate::offers::offer::DerivedMetadata,
10099
crate::onion_message::messenger::DefaultMessageRouter,
101100
crate::routing::router::DefaultRouter,
102101
crate::routing::gossip::NetworkGraph,
103102
crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters},
104103
crate::sign::KeysManager,
105104
};
106105
#[cfg(c_bindings)]
107-
use {
108-
crate::offers::offer::OfferWithDerivedMetadataBuilder,
109-
crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder,
110-
};
106+
use crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder;
111107

112108
use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, CreationError, Currency, Description, InvoiceBuilder as Bolt11InvoiceBuilder, SignOrCreationError, DEFAULT_EXPIRY_TIME};
113109

@@ -1923,6 +1919,7 @@ where
19231919
/// ```
19241920
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
19251921
/// # use lightning::ln::channelmanager::{AChannelManager, Bolt11InvoiceParameters};
1922+
/// # use lightning::offers::flow::OffersMessageCommons;
19261923
/// #
19271924
/// # fn example<T: AChannelManager>(channel_manager: T) {
19281925
/// # let channel_manager = channel_manager.get_cm();
@@ -2023,56 +2020,8 @@ where
20232020
/// ```
20242021
///
20252022
/// ## BOLT 12 Offers
2026-
///
2027-
/// The [`offers`] module is useful for creating BOLT 12 offers. An [`Offer`] is a precursor to a
2028-
/// [`Bolt12Invoice`], which must first be requested by the payer. The interchange of these messages
2029-
/// as defined in the specification is handled by [`ChannelManager`]. However, this only works with
2030-
/// an [`Offer`] created using a builder returned by [`create_offer_builder`]. With this approach,
2031-
/// BOLT 12 offers and invoices are stateless just as BOLT 11 invoices are.
2032-
///
2033-
/// ```
2034-
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
2035-
/// # use lightning::ln::channelmanager::AChannelManager;
2036-
/// # use lightning::offers::parse::Bolt12SemanticError;
2037-
/// #
2038-
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
2039-
/// # let channel_manager = channel_manager.get_cm();
2040-
/// # let absolute_expiry = None;
2041-
/// let offer = channel_manager
2042-
/// .create_offer_builder(absolute_expiry)?
2043-
/// # ;
2044-
/// # // Needed for compiling for c_bindings
2045-
/// # let builder: lightning::offers::offer::OfferBuilder<_, _> = offer.into();
2046-
/// # let offer = builder
2047-
/// .description("coffee".to_string())
2048-
/// .amount_msats(10_000_000)
2049-
/// .build()?;
2050-
/// let bech32_offer = offer.to_string();
2051-
///
2052-
/// // On the event processing thread
2053-
/// channel_manager.process_pending_events(&|event| {
2054-
/// match event {
2055-
/// Event::PaymentClaimable { payment_hash, purpose, .. } => match purpose {
2056-
/// PaymentPurpose::Bolt12OfferPayment { payment_preimage: Some(payment_preimage), .. } => {
2057-
/// println!("Claiming payment {}", payment_hash);
2058-
/// channel_manager.claim_funds(payment_preimage);
2059-
/// },
2060-
/// PaymentPurpose::Bolt12OfferPayment { payment_preimage: None, .. } => {
2061-
/// println!("Unknown payment hash: {}", payment_hash);
2062-
/// }
2063-
/// # _ => {},
2064-
/// },
2065-
/// Event::PaymentClaimed { payment_hash, amount_msat, .. } => {
2066-
/// println!("Claimed {} msats", amount_msat);
2067-
/// },
2068-
/// // ...
2069-
/// # _ => {},
2070-
/// }
2071-
/// Ok(())
2072-
/// });
2073-
/// # Ok(())
2074-
/// # }
2075-
/// ```
2023+
///
2024+
/// For more information on creating offers, see [`create_offer_builder`].
20762025
///
20772026
/// Use [`pay_for_offer`] to initiated payment, which sends an [`InvoiceRequest`] for an [`Offer`]
20782027
/// and pays the [`Bolt12Invoice`] response.
@@ -2194,6 +2143,7 @@ where
21942143
/// ```
21952144
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
21962145
/// # use lightning::ln::channelmanager::AChannelManager;
2146+
/// # use lightning::offers::flow::OffersMessageCommons;
21972147
/// # use lightning::offers::refund::Refund;
21982148
/// #
21992149
/// # fn example<T: AChannelManager>(channel_manager: T, refund: &Refund) {
@@ -2312,7 +2262,6 @@ where
23122262
/// [`claim_funds`]: Self::claim_funds
23132263
/// [`send_payment`]: Self::send_payment
23142264
/// [`offers`]: crate::offers
2315-
/// [`create_offer_builder`]: Self::create_offer_builder
23162265
/// [`pay_for_offer`]: Self::pay_for_offer
23172266
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
23182267
/// [`create_refund_builder`]: Self::create_refund_builder
@@ -2324,6 +2273,7 @@ where
23242273
/// [`update_channel`]: chain::Watch::update_channel
23252274
/// [`ChannelUpdate`]: msgs::ChannelUpdate
23262275
/// [`read`]: ReadableArgs::read
2276+
/// [`create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
23272277
//
23282278
// Lock order:
23292279
// The tree structure below illustrates the lock order requirements for the different locks of the
@@ -2822,11 +2772,13 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
28222772
/// The maximum expiration from the current time where an [`Offer`] or [`Refund`] is considered
28232773
/// short-lived, while anything with a greater expiration is considered long-lived.
28242774
///
2825-
/// Using [`ChannelManager::create_offer_builder`] or [`ChannelManager::create_refund_builder`],
2775+
/// Using [`OffersMessageFlow::create_offer_builder`] or [`ChannelManager::create_refund_builder`],
28262776
/// will included a [`BlindedMessagePath`] created using:
28272777
/// - [`MessageRouter::create_compact_blinded_paths`] when short-lived, and
28282778
/// - [`MessageRouter::create_blinded_paths`] when long-lived.
28292779
///
2780+
/// [`OffersMessageFlow::create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2781+
///
28302782
/// Using compact [`BlindedMessagePath`]s may provide better privacy as the [`MessageRouter`] could select
28312783
/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to
28322784
/// become invalid over time as channels are closed. Thus, they are only suitable for short-term use.
@@ -6795,7 +6747,7 @@ where
67956747
/// [`Event::PaymentClaimable::claim_deadline`]: crate::events::Event::PaymentClaimable::claim_deadline
67966748
/// [`Event::PaymentClaimed`]: crate::events::Event::PaymentClaimed
67976749
/// [`process_pending_events`]: EventsProvider::process_pending_events
6798-
/// [`create_inbound_payment`]: Self::create_inbound_payment
6750+
/// [`create_inbound_payment`]: ChannelManager::create_inbound_payment
67996751
/// [`create_inbound_payment_for_hash`]: ChannelManager::create_inbound_payment_for_hash
68006752
/// [`claim_funds_with_known_custom_tlvs`]: ChannelManager::claim_funds_with_known_custom_tlvs
68016753
pub fn claim_funds(&self, payment_preimage: PaymentPreimage) {
@@ -9719,57 +9671,6 @@ impl Default for Bolt11InvoiceParameters {
97199671
}
97209672
}
97219673

9722-
macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
9723-
/// Creates an [`OfferBuilder`] such that the [`Offer`] it builds is recognized by the
9724-
/// [`ChannelManager`] when handling [`InvoiceRequest`] messages for the offer. The offer's
9725-
/// expiration will be `absolute_expiry` if `Some`, otherwise it will not expire.
9726-
///
9727-
/// # Privacy
9728-
///
9729-
/// Uses [`MessageRouter`] to construct a [`BlindedMessagePath`] for the offer based on the given
9730-
/// `absolute_expiry` according to [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`]. See those docs for
9731-
/// privacy implications as well as those of the parameterized [`Router`], which implements
9732-
/// [`MessageRouter`].
9733-
///
9734-
/// Also, uses a derived signing pubkey in the offer for recipient privacy.
9735-
///
9736-
/// # Limitations
9737-
///
9738-
/// Requires a direct connection to the introduction node in the responding [`InvoiceRequest`]'s
9739-
/// reply path.
9740-
///
9741-
/// # Errors
9742-
///
9743-
/// Errors if the parameterized [`Router`] is unable to create a blinded path for the offer.
9744-
///
9745-
/// [`Offer`]: crate::offers::offer::Offer
9746-
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
9747-
pub fn create_offer_builder(
9748-
&$self, absolute_expiry: Option<Duration>
9749-
) -> Result<$builder, Bolt12SemanticError> {
9750-
let node_id = $self.get_our_node_id();
9751-
let expanded_key = &$self.inbound_payment_key;
9752-
let entropy = &*$self.entropy_source;
9753-
let secp_ctx = &$self.secp_ctx;
9754-
9755-
let nonce = Nonce::from_entropy_source(entropy);
9756-
let context = OffersContext::InvoiceRequest { nonce };
9757-
let path = $self.create_blinded_paths_using_absolute_expiry(context, absolute_expiry)
9758-
.and_then(|paths| paths.into_iter().next().ok_or(()))
9759-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9760-
let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
9761-
.chain_hash($self.chain_hash)
9762-
.path(path);
9763-
9764-
let builder = match absolute_expiry {
9765-
None => builder,
9766-
Some(absolute_expiry) => builder.absolute_expiry(absolute_expiry),
9767-
};
9768-
9769-
Ok(builder.into())
9770-
}
9771-
} }
9772-
97739674
macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
97749675
/// Creates a [`RefundBuilder`] such that the [`Refund`] it builds is recognized by the
97759676
/// [`ChannelManager`] when handling [`Bolt12Invoice`] messages for the refund.
@@ -10057,6 +9958,23 @@ where
100579958

100589959
res
100599960
}
9961+
9962+
fn create_blinded_paths_using_absolute_expiry(
9963+
&self, context: OffersContext, absolute_expiry: Option<Duration>,
9964+
) -> Result<Vec<BlindedMessagePath>, ()> {
9965+
let now = self.duration_since_epoch();
9966+
let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
9967+
9968+
if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
9969+
self.create_compact_blinded_paths(context)
9970+
} else {
9971+
self.create_blinded_paths(MessageContext::Offers(context))
9972+
}
9973+
}
9974+
9975+
fn get_chain_hash(&self) -> ChainHash {
9976+
self.chain_hash
9977+
}
100609978
}
100619979

100629980
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -10078,13 +9996,9 @@ where
100789996
MR::Target: MessageRouter,
100799997
L::Target: Logger,
100809998
{
10081-
#[cfg(not(c_bindings))]
10082-
create_offer_builder!(self, OfferBuilder<DerivedMetadata, secp256k1::All>);
100839999
#[cfg(not(c_bindings))]
1008410000
create_refund_builder!(self, RefundBuilder<secp256k1::All>);
1008510001

10086-
#[cfg(c_bindings)]
10087-
create_offer_builder!(self, OfferWithDerivedMetadataBuilder);
1008810002
#[cfg(c_bindings)]
1008910003
create_refund_builder!(self, RefundMaybeWithDerivedMetadataBuilder);
1009010004

@@ -10436,25 +10350,6 @@ where
1043610350
inbound_payment::get_payment_preimage(payment_hash, payment_secret, &self.inbound_payment_key)
1043710351
}
1043810352

10439-
/// Creates a collection of blinded paths by delegating to [`MessageRouter`] based on
10440-
/// the path's intended lifetime.
10441-
///
10442-
/// Whether or not the path is compact depends on whether the path is short-lived or long-lived,
10443-
/// respectively, based on the given `absolute_expiry` as seconds since the Unix epoch. See
10444-
/// [`MAX_SHORT_LIVED_RELATIVE_EXPIRY`].
10445-
fn create_blinded_paths_using_absolute_expiry(
10446-
&self, context: OffersContext, absolute_expiry: Option<Duration>,
10447-
) -> Result<Vec<BlindedMessagePath>, ()> {
10448-
let now = self.duration_since_epoch();
10449-
let max_short_lived_absolute_expiry = now.saturating_add(MAX_SHORT_LIVED_RELATIVE_EXPIRY);
10450-
10451-
if absolute_expiry.unwrap_or(Duration::MAX) <= max_short_lived_absolute_expiry {
10452-
self.create_compact_blinded_paths(context)
10453-
} else {
10454-
self.create_blinded_paths(MessageContext::Offers(context))
10455-
}
10456-
}
10457-
1045810353
pub(super) fn duration_since_epoch(&self) -> Duration {
1045910354
#[cfg(not(feature = "std"))]
1046010355
let now = Duration::from_secs(
@@ -15427,6 +15322,7 @@ pub mod bench {
1542715322
use crate::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId, RecipientOnionFields, Retry};
1542815323
use crate::ln::functional_test_utils::*;
1542915324
use crate::ln::msgs::{ChannelMessageHandler, Init};
15325+
use crate::offers::flow::OffersMessageCommons;
1543015326
use crate::routing::gossip::NetworkGraph;
1543115327
use crate::routing::router::{PaymentParameters, RouteParameters};
1543215328
use crate::util::test_utils;

lightning/src/ln/max_payment_path_len_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ fn bolt12_invoice_too_large_blinded_paths() {
385385
)
386386
]);
387387

388-
let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
388+
let offer = nodes[1].offers_handler.create_offer_builder(None).unwrap().build().unwrap();
389389
let payment_id = PaymentId([1; 32]);
390390
nodes[0].node.pay_for_offer(&offer, None, Some(5000), None, payment_id, Retry::Attempts(0), None).unwrap();
391391
let invreq_om = nodes[0].onion_messenger.next_onion_message_for_peer(nodes[1].node.get_our_node_id()).unwrap();

0 commit comments

Comments
 (0)