Skip to content

Commit 5af7a66

Browse files
committed
Move pay_for_offer to OffersMessageFlow
1 parent 9f31819 commit 5af7a66

File tree

6 files changed

+211
-164
lines changed

6 files changed

+211
-164
lines changed

lightning/src/ln/async_payments_tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ fn static_invoice_unknown_required_features() {
170170
let amt_msat = 5000;
171171
let payment_id = PaymentId([1; 32]);
172172
nodes[0]
173-
.node
173+
.offers_handler
174174
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
175175
.unwrap();
176176

@@ -230,7 +230,7 @@ fn ignore_unexpected_static_invoice() {
230230
let amt_msat = 5000;
231231
let payment_id = PaymentId([1; 32]);
232232
nodes[0]
233-
.node
233+
.offers_handler
234234
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
235235
.unwrap();
236236

@@ -339,7 +339,7 @@ fn pays_static_invoice() {
339339
let amt_msat = 5000;
340340
let payment_id = PaymentId([1; 32]);
341341
nodes[0]
342-
.node
342+
.offers_handler
343343
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
344344
.unwrap();
345345

@@ -433,7 +433,7 @@ fn expired_static_invoice_fail() {
433433
let amt_msat = 5000;
434434
let payment_id = PaymentId([1; 32]);
435435
nodes[0]
436-
.node
436+
.offers_handler
437437
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
438438
.unwrap();
439439

lightning/src/ln/channelmanager.rs

Lines changed: 26 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ use crate::events::{self, Event, EventHandler, EventsProvider, InboundChannelFun
4747
// construct one themselves.
4848
use crate::ln::inbound_payment;
4949
use crate::ln::types::ChannelId;
50+
use crate::offers::offer::Offer;
5051
use crate::offers::flow::OffersMessageCommons;
5152
use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
5253
use crate::ln::channel::{self, Channel, ChannelError, ChannelUpdateStatus, FundedChannel, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, ReconnectionMsg, InboundV1Channel, WithChannelContext};
@@ -68,7 +69,6 @@ use crate::ln::outbound_payment::{OutboundPayments, PendingOutboundPayment, Retr
6869
use crate::offers::invoice::{Bolt12Invoice, DerivedSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice, DEFAULT_RELATIVE_EXPIRY};
6970
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
7071
use crate::offers::nonce::Nonce;
71-
use crate::offers::offer::Offer;
7272
use crate::offers::parse::Bolt12SemanticError;
7373
use crate::offers::refund::Refund;
7474
use crate::offers::signer;
@@ -2053,57 +2053,7 @@ where
20532053
///
20542054
/// For more information on creating offers, see [`create_offer_builder`].
20552055
///
2056-
/// Use [`pay_for_offer`] to initiated payment, which sends an [`InvoiceRequest`] for an [`Offer`]
2057-
/// and pays the [`Bolt12Invoice`] response.
2058-
///
2059-
/// ```
2060-
/// # use lightning::events::{Event, EventsProvider};
2061-
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
2062-
/// # use lightning::offers::flow::OffersMessageCommons;
2063-
/// # use lightning::offers::offer::Offer;
2064-
/// #
2065-
/// # fn example<T: AChannelManager>(
2066-
/// # channel_manager: T, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
2067-
/// # payer_note: Option<String>, retry: Retry, max_total_routing_fee_msat: Option<u64>
2068-
/// # ) {
2069-
/// # let channel_manager = channel_manager.get_cm();
2070-
/// let payment_id = PaymentId([42; 32]);
2071-
/// match channel_manager.pay_for_offer(
2072-
/// offer, quantity, amount_msats, payer_note, payment_id, retry, max_total_routing_fee_msat
2073-
/// ) {
2074-
/// Ok(()) => println!("Requesting invoice for offer"),
2075-
/// Err(e) => println!("Unable to request invoice for offer: {:?}", e),
2076-
/// }
2077-
///
2078-
/// // First the payment will be waiting on an invoice
2079-
/// let expected_payment_id = payment_id;
2080-
/// assert!(
2081-
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
2082-
/// details,
2083-
/// RecentPaymentDetails::AwaitingInvoice { payment_id: expected_payment_id }
2084-
/// )).is_some()
2085-
/// );
2086-
///
2087-
/// // Once the invoice is received, a payment will be sent
2088-
/// assert!(
2089-
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
2090-
/// details,
2091-
/// RecentPaymentDetails::Pending { payment_id: expected_payment_id, .. }
2092-
/// )).is_some()
2093-
/// );
2094-
///
2095-
/// // On the event processing thread
2096-
/// channel_manager.process_pending_events(&|event| {
2097-
/// match event {
2098-
/// Event::PaymentSent { payment_id: Some(payment_id), .. } => println!("Paid {}", payment_id),
2099-
/// Event::PaymentFailed { payment_id, .. } => println!("Failed paying {}", payment_id),
2100-
/// // ...
2101-
/// # _ => {},
2102-
/// }
2103-
/// Ok(())
2104-
/// });
2105-
/// # }
2106-
/// ```
2056+
/// For details on initiating payments for offers, see [`pay_for_offer`].
21072057
///
21082058
/// ## BOLT 12 Refunds
21092059
///
@@ -2234,7 +2184,7 @@ where
22342184
/// [`claim_funds`]: Self::claim_funds
22352185
/// [`send_payment`]: Self::send_payment
22362186
/// [`offers`]: crate::offers
2237-
/// [`pay_for_offer`]: Self::pay_for_offer
2187+
/// [`Offer`]: crate::offers::offer
22382188
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
22392189
/// [`request_refund_payment`]: Self::request_refund_payment
22402190
/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
@@ -2245,6 +2195,7 @@ where
22452195
/// [`ChannelUpdate`]: msgs::ChannelUpdate
22462196
/// [`read`]: ReadableArgs::read
22472197
/// [`create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2198+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
22482199
/// [`create_refund_builder`]: crate::offers::flow::OffersMessageFlow::create_refund_builder
22492200
//
22502201
// Lock order:
@@ -2753,6 +2704,8 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
27532704
/// Using compact [`BlindedMessagePath`]s may provide better privacy as the [`MessageRouter`] could select
27542705
/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to
27552706
/// become invalid over time as channels are closed. Thus, they are only suitable for short-term use.
2707+
///
2708+
/// [`Offer`]: crate::offers::offer
27562709
pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY: Duration = Duration::from_secs(60 * 60 * 24);
27572710

27582711
/// Used by [`ChannelManager::list_recent_payments`] to express the status of recent payments.
@@ -2761,8 +2714,10 @@ pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY: Duration = Duration::from_secs(60 * 6
27612714
pub enum RecentPaymentDetails {
27622715
/// When an invoice was requested and thus a payment has not yet been sent.
27632716
AwaitingInvoice {
2764-
/// A user-provided identifier in [`ChannelManager::pay_for_offer`] used to uniquely identify a
2717+
/// A user-provided identifier in [`OffersMessageFlow::pay_for_offer`] used to uniquely identify a
27652718
/// payment and ensure idempotency in LDK.
2719+
///
2720+
/// [`OffersMessageFlow::pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27662721
payment_id: PaymentId,
27672722
},
27682723
/// When a payment is still being sent and awaiting successful delivery.
@@ -2771,7 +2726,7 @@ pub enum RecentPaymentDetails {
27712726
/// identify a payment and ensure idempotency in LDK.
27722727
///
27732728
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2774-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2729+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27752730
payment_id: PaymentId,
27762731
/// Hash of the payment that is currently being sent but has yet to be fulfilled or
27772732
/// abandoned.
@@ -2788,7 +2743,7 @@ pub enum RecentPaymentDetails {
27882743
/// identify a payment and ensure idempotency in LDK.
27892744
///
27902745
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2791-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2746+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27922747
payment_id: PaymentId,
27932748
/// Hash of the payment that was claimed. `None` for serializations of [`ChannelManager`]
27942749
/// made before LDK version 0.0.104.
@@ -2802,7 +2757,7 @@ pub enum RecentPaymentDetails {
28022757
/// identify a payment and ensure idempotency in LDK.
28032758
///
28042759
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2805-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2760+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
28062761
payment_id: PaymentId,
28072762
/// Hash of the payment that we have given up trying to send.
28082763
payment_hash: PaymentHash,
@@ -4702,7 +4657,7 @@ where
47024657
///
47034658
/// # Requested Invoices
47044659
///
4705-
/// In the case of paying a [`Bolt12Invoice`] via [`ChannelManager::pay_for_offer`], abandoning
4660+
/// In the case of paying a [`Bolt12Invoice`] via [`OffersMessageFlow::pay_for_offer`], abandoning
47064661
/// the payment prior to receiving the invoice will result in an [`Event::PaymentFailed`] and
47074662
/// prevent any attempts at paying it once received.
47084663
///
@@ -4712,6 +4667,7 @@ where
47124667
/// [`ChannelManager`], another [`Event::PaymentFailed`] may be generated.
47134668
///
47144669
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
4670+
/// [`OffersMessageFlow::pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
47154671
pub fn abandon_payment(&self, payment_id: PaymentId) {
47164672
self.abandon_payment_with_reason(payment_id, PaymentFailureReason::UserAbandoned)
47174673
}
@@ -9649,7 +9605,6 @@ where
96499605
}
96509606

96519607
fn add_new_awaiting_invoice(&self, payment_id: PaymentId, expiration: StaleExpiration, retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>, retryable_invoice_request: Option<RetryableInvoiceRequest>) -> Result<(), ()> {
9652-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
96539608
self.pending_outbound_payments.add_new_awaiting_invoice (
96549609
payment_id, expiration, retry_strategy, max_total_routing_fee_msat, retryable_invoice_request,
96559610
)
@@ -9659,6 +9614,14 @@ where
96599614
fn get_highest_seen_timestamp(&self) -> Duration {
96609615
Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64)
96619616
}
9617+
9618+
fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>>(
9619+
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
9620+
payer_note: Option<String>, payment_id: PaymentId,
9621+
human_readable_name: Option<HumanReadableName>, create_pending_payment: CPP,
9622+
) -> Result<(), Bolt12SemanticError> {
9623+
self.pay_for_offer_intern(offer, quantity, amount_msats, payer_note, payment_id, human_readable_name, create_pending_payment)
9624+
}
96629625
}
96639626

96649627
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -9680,81 +9643,8 @@ where
96809643
MR::Target: MessageRouter,
96819644
L::Target: Logger,
96829645
{
9683-
/// Pays for an [`Offer`] using the given parameters by creating an [`InvoiceRequest`] and
9684-
/// enqueuing it to be sent via an onion message. [`ChannelManager`] will pay the actual
9685-
/// [`Bolt12Invoice`] once it is received.
9686-
///
9687-
/// Uses [`InvoiceRequestBuilder`] such that the [`InvoiceRequest`] it builds is recognized by
9688-
/// the [`ChannelManager`] when handling a [`Bolt12Invoice`] message in response to the request.
9689-
/// The optional parameters are used in the builder, if `Some`:
9690-
/// - `quantity` for [`InvoiceRequest::quantity`] which must be set if
9691-
/// [`Offer::expects_quantity`] is `true`.
9692-
/// - `amount_msats` if overpaying what is required for the given `quantity` is desired, and
9693-
/// - `payer_note` for [`InvoiceRequest::payer_note`].
9694-
///
9695-
/// If `max_total_routing_fee_msat` is not specified, The default from
9696-
/// [`RouteParameters::from_payment_params_and_value`] is applied.
9697-
///
9698-
/// # Payment
9699-
///
9700-
/// The provided `payment_id` is used to ensure that only one invoice is paid for the request
9701-
/// when received. See [Avoiding Duplicate Payments] for other requirements once the payment has
9702-
/// been sent.
9703-
///
9704-
/// To revoke the request, use [`ChannelManager::abandon_payment`] prior to receiving the
9705-
/// invoice. If abandoned, or an invoice isn't received in a reasonable amount of time, the
9706-
/// payment will fail with an [`Event::PaymentFailed`].
9707-
///
9708-
/// # Privacy
9709-
///
9710-
/// For payer privacy, uses a derived payer id and uses [`MessageRouter::create_blinded_paths`]
9711-
/// to construct a [`BlindedMessagePath`] for the reply path. For further privacy implications, see the
9712-
/// docs of the parameterized [`Router`], which implements [`MessageRouter`].
9713-
///
9714-
/// # Limitations
9715-
///
9716-
/// Requires a direct connection to an introduction node in [`Offer::paths`] or to
9717-
/// [`Offer::issuer_signing_pubkey`], if empty. A similar restriction applies to the responding
9718-
/// [`Bolt12Invoice::payment_paths`].
9719-
///
9720-
/// # Errors
9721-
///
9722-
/// Errors if:
9723-
/// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
9724-
/// - the provided parameters are invalid for the offer,
9725-
/// - the offer is for an unsupported chain, or
9726-
/// - the parameterized [`Router`] is unable to create a blinded reply path for the invoice
9727-
/// request.
9728-
///
9729-
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
9730-
/// [`InvoiceRequest::quantity`]: crate::offers::invoice_request::InvoiceRequest::quantity
9731-
/// [`InvoiceRequest::payer_note`]: crate::offers::invoice_request::InvoiceRequest::payer_note
9732-
/// [`InvoiceRequestBuilder`]: crate::offers::invoice_request::InvoiceRequestBuilder
9733-
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
9734-
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
9735-
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
9736-
pub fn pay_for_offer(
9737-
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
9738-
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
9739-
max_total_routing_fee_msat: Option<u64>
9740-
) -> Result<(), Bolt12SemanticError> {
9741-
self.pay_for_offer_intern(offer, quantity, amount_msats, payer_note, payment_id, None, |invoice_request, nonce| {
9742-
let expiration = StaleExpiration::TimerTicks(1);
9743-
let retryable_invoice_request = RetryableInvoiceRequest {
9744-
invoice_request: invoice_request.clone(),
9745-
nonce,
9746-
needs_retry: true,
9747-
};
9748-
self.pending_outbound_payments
9749-
.add_new_awaiting_invoice(
9750-
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
9751-
Some(retryable_invoice_request)
9752-
)
9753-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
9754-
})
9755-
}
9756-
9757-
fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>>(
9646+
/// Internal pay_for_offer
9647+
pub fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>>(
97589648
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
97599649
payer_note: Option<String>, payment_id: PaymentId,
97609650
human_readable_name: Option<HumanReadableName>, create_pending_payment: CPP,
@@ -9833,7 +9723,6 @@ where
98339723
debug_assert!(false);
98349724
return Err(Bolt12SemanticError::MissingIssuerSigningPubkey);
98359725
}
9836-
98379726
Ok(())
98389727
}
98399728

@@ -12531,6 +12420,8 @@ where
1253112420
pub router: R,
1253212421
/// The [`MessageRouter`] used for constructing [`BlindedMessagePath`]s for [`Offer`]s,
1253312422
/// [`Refund`]s, and any reply paths.
12423+
///
12424+
/// [`Offer`]: crate::offers::offer
1253412425
pub message_router: MR,
1253512426
/// The Logger for use in the ChannelManager and which may be used to log information during
1253612427
/// deserialization.

lightning/src/ln/max_payment_path_len_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ fn bolt12_invoice_too_large_blinded_paths() {
392392

393393
let offer = nodes[1].offers_handler.create_offer_builder(None).unwrap().build().unwrap();
394394
let payment_id = PaymentId([1; 32]);
395-
nodes[0].node.pay_for_offer(&offer, None, Some(5000), None, payment_id, Retry::Attempts(0), None).unwrap();
395+
nodes[0].offers_handler.pay_for_offer(&offer, None, Some(5000), None, payment_id, Retry::Attempts(0), None).unwrap();
396396
let invreq_om = nodes[0].onion_messenger.next_onion_message_for_peer(nodes[1].node.get_our_node_id()).unwrap();
397397
nodes[1].onion_messenger.handle_onion_message(nodes[0].node.get_our_node_id(), &invreq_om);
398398

0 commit comments

Comments
 (0)