Skip to content

Commit d378166

Browse files
committed
Move Offer Payers to flow.rs
1 parent 4b5f947 commit d378166

File tree

5 files changed

+265
-274
lines changed

5 files changed

+265
-274
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: 16 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,10 @@ use crate::ln::msgs::{ChannelMessageHandler, CommitmentUpdate, DecodeError, Ligh
6666
use crate::ln::outbound_payment;
6767
use crate::ln::outbound_payment::{OutboundPayments, PendingOutboundPayment, RetryableInvoiceRequest, SendAlongPathArgs, StaleExpiration};
6868
use crate::offers::invoice::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, InvoiceBuilder, UnsignedBolt12Invoice};
69-
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
7069
use crate::offers::nonce::Nonce;
71-
use crate::offers::offer::Offer;
7270
use crate::offers::parse::Bolt12SemanticError;
7371
use crate::offers::refund::Refund;
7472
use crate::offers::signer;
75-
use crate::onion_message::dns_resolution::HumanReadableName;
7673
use crate::onion_message::messenger::{Destination, MessageRouter, MessageSendInstructions};
7774
use crate::onion_message::offers::OffersMessage;
7875
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
@@ -2045,62 +2042,13 @@ where
20452042
/// ```
20462043
///
20472044
/// ## BOLT 12 Offers
2048-
///
2049-
/// For more information on creating offers, see [`create_offer_builder`].
2050-
///
2051-
/// Use [`pay_for_offer`] to initiated payment, which sends an [`InvoiceRequest`] for an [`Offer`]
2052-
/// and pays the [`Bolt12Invoice`] response.
2053-
///
2054-
/// ```
2055-
/// # use lightning::events::{Event, EventsProvider};
2056-
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
2057-
/// # use lightning::offers::offer::Offer;
2058-
/// #
2059-
/// # fn example<T: AChannelManager>(
2060-
/// # channel_manager: T, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
2061-
/// # payer_note: Option<String>, retry: Retry, max_total_routing_fee_msat: Option<u64>
2062-
/// # ) {
2063-
/// # let channel_manager = channel_manager.get_cm();
2064-
/// let payment_id = PaymentId([42; 32]);
2065-
/// match channel_manager.pay_for_offer(
2066-
/// offer, quantity, amount_msats, payer_note, payment_id, retry, max_total_routing_fee_msat
2067-
/// ) {
2068-
/// Ok(()) => println!("Requesting invoice for offer"),
2069-
/// Err(e) => println!("Unable to request invoice for offer: {:?}", e),
2070-
/// }
20712045
///
2072-
/// // First the payment will be waiting on an invoice
2073-
/// let expected_payment_id = payment_id;
2074-
/// assert!(
2075-
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
2076-
/// details,
2077-
/// RecentPaymentDetails::AwaitingInvoice { payment_id: expected_payment_id }
2078-
/// )).is_some()
2079-
/// );
2080-
///
2081-
/// // Once the invoice is received, a payment will be sent
2082-
/// assert!(
2083-
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
2084-
/// details,
2085-
/// RecentPaymentDetails::Pending { payment_id: expected_payment_id, .. }
2086-
/// )).is_some()
2087-
/// );
2046+
/// For more information on creating offers, see [`create_offer_builder`].
20882047
///
2089-
/// // On the event processing thread
2090-
/// channel_manager.process_pending_events(&|event| {
2091-
/// match event {
2092-
/// Event::PaymentSent { payment_id: Some(payment_id), .. } => println!("Paid {}", payment_id),
2093-
/// Event::PaymentFailed { payment_id, .. } => println!("Failed paying {}", payment_id),
2094-
/// // ...
2095-
/// # _ => {},
2096-
/// }
2097-
/// Ok(())
2098-
/// });
2099-
/// # }
2100-
/// ```
2048+
/// For details on initiating payments for offers, see [`pay_for_offer`].
21012049
///
21022050
/// ## BOLT 12 Refunds
2103-
///
2051+
///
21042052
/// For more information on creating refunds, see [`create_refund_builder`].
21052053
///
21062054
/// Use [`request_refund_payment`] to send a [`Bolt12Invoice`] for receiving the refund. Similar to
@@ -2227,8 +2175,8 @@ where
22272175
/// [`claim_funds`]: Self::claim_funds
22282176
/// [`send_payment`]: Self::send_payment
22292177
/// [`offers`]: crate::offers
2178+
/// [`Offer`]: crate::offers::offer::Offer
22302179
/// [`create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2231-
/// [`pay_for_offer`]: Self::pay_for_offer
22322180
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
22332181
/// [`create_refund_builder`]: crate::offers::flow::OffersMessageFlow::create_refund_builder
22342182
/// [`request_refund_payment`]: Self::request_refund_payment
@@ -2239,6 +2187,7 @@ where
22392187
/// [`update_channel`]: chain::Watch::update_channel
22402188
/// [`ChannelUpdate`]: msgs::ChannelUpdate
22412189
/// [`read`]: ReadableArgs::read
2190+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
22422191
//
22432192
// Lock order:
22442193
// The tree structure below illustrates the lock order requirements for the different locks of the
@@ -2729,8 +2678,10 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
27292678
pub enum RecentPaymentDetails {
27302679
/// When an invoice was requested and thus a payment has not yet been sent.
27312680
AwaitingInvoice {
2732-
/// A user-provided identifier in [`ChannelManager::pay_for_offer`] used to uniquely identify a
2681+
/// A user-provided identifier in [`OffersMessageFlow::pay_for_offer`] used to uniquely identify a
27332682
/// payment and ensure idempotency in LDK.
2683+
///
2684+
/// [`OffersMessageFlow::pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27342685
payment_id: PaymentId,
27352686
},
27362687
/// When a payment is still being sent and awaiting successful delivery.
@@ -2739,7 +2690,7 @@ pub enum RecentPaymentDetails {
27392690
/// identify a payment and ensure idempotency in LDK.
27402691
///
27412692
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2742-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2693+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27432694
payment_id: PaymentId,
27442695
/// Hash of the payment that is currently being sent but has yet to be fulfilled or
27452696
/// abandoned.
@@ -2756,7 +2707,7 @@ pub enum RecentPaymentDetails {
27562707
/// identify a payment and ensure idempotency in LDK.
27572708
///
27582709
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2759-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2710+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27602711
payment_id: PaymentId,
27612712
/// Hash of the payment that was claimed. `None` for serializations of [`ChannelManager`]
27622713
/// made before LDK version 0.0.104.
@@ -2770,7 +2721,7 @@ pub enum RecentPaymentDetails {
27702721
/// identify a payment and ensure idempotency in LDK.
27712722
///
27722723
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2773-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2724+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27742725
payment_id: PaymentId,
27752726
/// Hash of the payment that we have given up trying to send.
27762727
payment_hash: PaymentHash,
@@ -4633,7 +4584,7 @@ where
46334584
///
46344585
/// # Requested Invoices
46354586
///
4636-
/// In the case of paying a [`Bolt12Invoice`] via [`ChannelManager::pay_for_offer`], abandoning
4587+
/// In the case of paying a [`Bolt12Invoice`] via [`OffersMessageFlow::pay_for_offer`], abandoning
46374588
/// the payment prior to receiving the invoice will result in an [`Event::PaymentFailed`] and
46384589
/// prevent any attempts at paying it once received.
46394590
///
@@ -4642,6 +4593,7 @@ where
46424593
/// If an [`Event::PaymentFailed`] is generated and we restart without first persisting the
46434594
/// [`ChannelManager`], another [`Event::PaymentFailed`] may be generated.
46444595
///
4596+
/// [`OffersMessageFlow::pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
46454597
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
46464598
pub fn abandon_payment(&self, payment_id: PaymentId) {
46474599
self.abandon_payment_with_reason(payment_id, PaymentFailureReason::UserAbandoned)
@@ -9568,7 +9520,7 @@ where
95689520
}
95699521

95709522
fn add_new_awaiting_invoice(
9571-
&self, payment_id: PaymentId, expiration: StaleExpiration, retry_strategy: Retry,
9523+
&self, payment_id: PaymentId, expiration: StaleExpiration, retry_strategy: Retry,
95729524
max_total_routing_fee_msat: Option<u64>, retryable_invoice_request: Option<RetryableInvoiceRequest>
95739525
) -> Result<(), ()> {
95749526
self.pending_outbound_payments.add_new_awaiting_invoice (
@@ -9629,18 +9581,6 @@ where
96299581
fn get_pending_offers_messages(&self) -> MutexGuard<'_, Vec<(OffersMessage, MessageSendInstructions)>> {
96309582
self.pending_offers_messages.lock().expect("Mutex is locked by other thread.")
96319583
}
9632-
9633-
fn enqueue_invoice_request(&self, invoice_request: InvoiceRequest, reply_paths: Vec<BlindedMessagePath>) -> Result<(), Bolt12SemanticError> {
9634-
self.enqueue_invoice_request(invoice_request, reply_paths)
9635-
}
9636-
9637-
fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>>(
9638-
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
9639-
payer_note: Option<String>, payment_id: PaymentId,
9640-
human_readable_name: Option<HumanReadableName>, create_pending_payment: CPP,
9641-
) -> Result<(), Bolt12SemanticError> {
9642-
self.pay_for_offer_intern(offer, quantity, amount_msats, payer_note, payment_id, human_readable_name, create_pending_payment)
9643-
}
96449584
}
96459585

96469586
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -9662,164 +9602,6 @@ where
96629602
MR::Target: MessageRouter,
96639603
L::Target: Logger,
96649604
{
9665-
/// Pays for an [`Offer`] using the given parameters by creating an [`InvoiceRequest`] and
9666-
/// enqueuing it to be sent via an onion message. [`ChannelManager`] will pay the actual
9667-
/// [`Bolt12Invoice`] once it is received.
9668-
///
9669-
/// Uses [`InvoiceRequestBuilder`] such that the [`InvoiceRequest`] it builds is recognized by
9670-
/// the [`ChannelManager`] when handling a [`Bolt12Invoice`] message in response to the request.
9671-
/// The optional parameters are used in the builder, if `Some`:
9672-
/// - `quantity` for [`InvoiceRequest::quantity`] which must be set if
9673-
/// [`Offer::expects_quantity`] is `true`.
9674-
/// - `amount_msats` if overpaying what is required for the given `quantity` is desired, and
9675-
/// - `payer_note` for [`InvoiceRequest::payer_note`].
9676-
///
9677-
/// If `max_total_routing_fee_msat` is not specified, The default from
9678-
/// [`RouteParameters::from_payment_params_and_value`] is applied.
9679-
///
9680-
/// # Payment
9681-
///
9682-
/// The provided `payment_id` is used to ensure that only one invoice is paid for the request
9683-
/// when received. See [Avoiding Duplicate Payments] for other requirements once the payment has
9684-
/// been sent.
9685-
///
9686-
/// To revoke the request, use [`ChannelManager::abandon_payment`] prior to receiving the
9687-
/// invoice. If abandoned, or an invoice isn't received in a reasonable amount of time, the
9688-
/// payment will fail with an [`Event::PaymentFailed`].
9689-
///
9690-
/// # Privacy
9691-
///
9692-
/// For payer privacy, uses a derived payer id and uses [`MessageRouter::create_blinded_paths`]
9693-
/// to construct a [`BlindedMessagePath`] for the reply path. For further privacy implications, see the
9694-
/// docs of the parameterized [`Router`], which implements [`MessageRouter`].
9695-
///
9696-
/// # Limitations
9697-
///
9698-
/// Requires a direct connection to an introduction node in [`Offer::paths`] or to
9699-
/// [`Offer::issuer_signing_pubkey`], if empty. A similar restriction applies to the responding
9700-
/// [`Bolt12Invoice::payment_paths`].
9701-
///
9702-
/// # Errors
9703-
///
9704-
/// Errors if:
9705-
/// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
9706-
/// - the provided parameters are invalid for the offer,
9707-
/// - the offer is for an unsupported chain, or
9708-
/// - the parameterized [`Router`] is unable to create a blinded reply path for the invoice
9709-
/// request.
9710-
///
9711-
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
9712-
/// [`InvoiceRequest::quantity`]: crate::offers::invoice_request::InvoiceRequest::quantity
9713-
/// [`InvoiceRequest::payer_note`]: crate::offers::invoice_request::InvoiceRequest::payer_note
9714-
/// [`InvoiceRequestBuilder`]: crate::offers::invoice_request::InvoiceRequestBuilder
9715-
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
9716-
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
9717-
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
9718-
pub fn pay_for_offer(
9719-
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
9720-
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
9721-
max_total_routing_fee_msat: Option<u64>
9722-
) -> Result<(), Bolt12SemanticError> {
9723-
self.pay_for_offer_intern(offer, quantity, amount_msats, payer_note, payment_id, None, |invoice_request, nonce| {
9724-
let expiration = StaleExpiration::TimerTicks(1);
9725-
let retryable_invoice_request = RetryableInvoiceRequest {
9726-
invoice_request: invoice_request.clone(),
9727-
nonce,
9728-
needs_retry: true,
9729-
};
9730-
self.pending_outbound_payments
9731-
.add_new_awaiting_invoice(
9732-
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
9733-
Some(retryable_invoice_request)
9734-
)
9735-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
9736-
})
9737-
}
9738-
9739-
fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>>(
9740-
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
9741-
payer_note: Option<String>, payment_id: PaymentId,
9742-
human_readable_name: Option<HumanReadableName>, create_pending_payment: CPP,
9743-
) -> Result<(), Bolt12SemanticError> {
9744-
let expanded_key = &self.inbound_payment_key;
9745-
let entropy = &*self.entropy_source;
9746-
let secp_ctx = &self.secp_ctx;
9747-
9748-
let nonce = Nonce::from_entropy_source(entropy);
9749-
let builder: InvoiceRequestBuilder<secp256k1::All> = offer
9750-
.request_invoice(expanded_key, nonce, secp_ctx, payment_id)?
9751-
.into();
9752-
let builder = builder.chain_hash(self.chain_hash)?;
9753-
9754-
let builder = match quantity {
9755-
None => builder,
9756-
Some(quantity) => builder.quantity(quantity)?,
9757-
};
9758-
let builder = match amount_msats {
9759-
None => builder,
9760-
Some(amount_msats) => builder.amount_msats(amount_msats)?,
9761-
};
9762-
let builder = match payer_note {
9763-
None => builder,
9764-
Some(payer_note) => builder.payer_note(payer_note),
9765-
};
9766-
let builder = match human_readable_name {
9767-
None => builder,
9768-
Some(hrn) => builder.sourced_from_human_readable_name(hrn),
9769-
};
9770-
let invoice_request = builder.build_and_sign()?;
9771-
9772-
let hmac = payment_id.hmac_for_offer_payment(nonce, expanded_key);
9773-
let context = MessageContext::Offers(
9774-
OffersContext::OutboundPayment { payment_id, nonce, hmac: Some(hmac) }
9775-
);
9776-
let reply_paths = self.create_blinded_paths(context)
9777-
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
9778-
9779-
// Temporarily removing this to find the best way to integrate the guard
9780-
// let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
9781-
9782-
create_pending_payment(&invoice_request, nonce)?;
9783-
9784-
self.enqueue_invoice_request(invoice_request, reply_paths)
9785-
}
9786-
9787-
fn enqueue_invoice_request(
9788-
&self,
9789-
invoice_request: InvoiceRequest,
9790-
reply_paths: Vec<BlindedMessagePath>,
9791-
) -> Result<(), Bolt12SemanticError> {
9792-
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
9793-
if !invoice_request.paths().is_empty() {
9794-
reply_paths
9795-
.iter()
9796-
.flat_map(|reply_path| invoice_request.paths().iter().map(move |path| (path, reply_path)))
9797-
.take(OFFERS_MESSAGE_REQUEST_LIMIT)
9798-
.for_each(|(path, reply_path)| {
9799-
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
9800-
destination: Destination::BlindedPath(path.clone()),
9801-
reply_path: reply_path.clone(),
9802-
};
9803-
let message = OffersMessage::InvoiceRequest(invoice_request.clone());
9804-
pending_offers_messages.push((message, instructions));
9805-
});
9806-
} else if let Some(node_id) = invoice_request.issuer_signing_pubkey() {
9807-
for reply_path in reply_paths {
9808-
let instructions = MessageSendInstructions::WithSpecifiedReplyPath {
9809-
destination: Destination::Node(node_id),
9810-
reply_path,
9811-
};
9812-
let message = OffersMessage::InvoiceRequest(invoice_request.clone());
9813-
pending_offers_messages.push((message, instructions));
9814-
}
9815-
} else {
9816-
debug_assert!(false);
9817-
return Err(Bolt12SemanticError::MissingIssuerSigningPubkey);
9818-
}
9819-
9820-
Ok(())
9821-
}
9822-
98239605
/// Creates a [`Bolt12Invoice`] for a [`Refund`] and enqueues it to be sent via an onion
98249606
/// message.
98259607
///
@@ -12295,6 +12077,8 @@ where
1229512077
pub router: R,
1229612078
/// The [`MessageRouter`] used for constructing [`BlindedMessagePath`]s for [`Offer`]s,
1229712079
/// [`Refund`]s, and any reply paths.
12080+
///
12081+
/// [`Offer`]: crate::offers::offer::Offer
1229812082
pub message_router: MR,
1229912083
/// The Logger for use in the ChannelManager and which may be used to log information during
1230012084
/// deserialization.

0 commit comments

Comments
 (0)