Skip to content

Commit a59b356

Browse files
committed
Move pay_for_offer to OffersMessageFlow
1 parent 58b9fd2 commit a59b356

File tree

4 files changed

+206
-177
lines changed

4 files changed

+206
-177
lines changed

lightning/src/ln/channelmanager.rs

+41-154
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use crate::events::{Event, EventHandler, EventsProvider, MessageSendEvent, Messa
4848
// construct one themselves.
4949
use crate::ln::inbound_payment;
5050
use crate::ln::types::ChannelId;
51+
use crate::offers::offer::Offer;
5152
use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
5253
use crate::ln::channel::{self, Channel, ChannelPhase, ChannelError, ChannelUpdateStatus, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext};
5354
use crate::ln::channel_state::ChannelDetails;
@@ -67,7 +68,6 @@ use crate::ln::wire::Encode;
6768
use crate::offers::invoice::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, DerivedSigningPubkey, InvoiceBuilder};
6869
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestBuilder};
6970
use crate::offers::nonce::Nonce;
70-
use crate::offers::offer::Offer;
7171
use crate::offers::parse::Bolt12SemanticError;
7272
use crate::offers::refund::Refund;
7373
use crate::offers::signer;
@@ -1993,59 +1993,6 @@ where
19931993
/// # }
19941994
/// ```
19951995
///
1996-
/// ## BOLT 12 Offers
1997-
///
1998-
/// Use [`pay_for_offer`] to initiated payment, which sends an [`InvoiceRequest`] for an [`Offer`]
1999-
/// and pays the [`Bolt12Invoice`] response.
2000-
///
2001-
/// ```
2002-
/// # use lightning::events::{Event, EventsProvider};
2003-
/// # use lightning::ln::channelmanager::{AChannelManager, OffersMessageCommons, PaymentId, RecentPaymentDetails, Retry};
2004-
/// # use lightning::offers::offer::Offer;
2005-
/// #
2006-
/// # fn example<T: AChannelManager>(
2007-
/// # channel_manager: T, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
2008-
/// # payer_note: Option<String>, retry: Retry, max_total_routing_fee_msat: Option<u64>
2009-
/// # ) {
2010-
/// # let channel_manager = channel_manager.get_cm();
2011-
/// let payment_id = PaymentId([42; 32]);
2012-
/// match channel_manager.pay_for_offer(
2013-
/// offer, quantity, amount_msats, payer_note, payment_id, retry, max_total_routing_fee_msat
2014-
/// ) {
2015-
/// Ok(()) => println!("Requesting invoice for offer"),
2016-
/// Err(e) => println!("Unable to request invoice for offer: {:?}", e),
2017-
/// }
2018-
///
2019-
/// // First the payment will be waiting on an invoice
2020-
/// let expected_payment_id = payment_id;
2021-
/// assert!(
2022-
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
2023-
/// details,
2024-
/// RecentPaymentDetails::AwaitingInvoice { payment_id: expected_payment_id }
2025-
/// )).is_some()
2026-
/// );
2027-
///
2028-
/// // Once the invoice is received, a payment will be sent
2029-
/// assert!(
2030-
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
2031-
/// details,
2032-
/// RecentPaymentDetails::Pending { payment_id: expected_payment_id, .. }
2033-
/// )).is_some()
2034-
/// );
2035-
///
2036-
/// // On the event processing thread
2037-
/// channel_manager.process_pending_events(&|event| {
2038-
/// match event {
2039-
/// Event::PaymentSent { payment_id: Some(payment_id), .. } => println!("Paid {}", payment_id),
2040-
/// Event::PaymentFailed { payment_id, .. } => println!("Failed paying {}", payment_id),
2041-
/// // ...
2042-
/// # _ => {},
2043-
/// }
2044-
/// Ok(())
2045-
/// });
2046-
/// # }
2047-
/// ```
2048-
///
20491996
/// ## BOLT 12 Refunds
20501997
///
20511998
/// Use [`request_refund_payment`] to send a [`Bolt12Invoice`] for receiving the refund. Similar to
@@ -2172,7 +2119,7 @@ where
21722119
/// [`claim_funds`]: Self::claim_funds
21732120
/// [`send_payment`]: Self::send_payment
21742121
/// [`offers`]: crate::offers
2175-
/// [`pay_for_offer`]: Self::pay_for_offer
2122+
/// [`Offer`]: crate::offers::offer
21762123
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
21772124
/// [`request_refund_payment`]: Self::request_refund_payment
21782125
/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
@@ -2684,6 +2631,8 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
26842631
/// Using compact [`BlindedMessagePath`]s may provide better privacy as the [`MessageRouter`] could select
26852632
/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to
26862633
/// become invalid over time as channels are closed. Thus, they are only suitable for short-term use.
2634+
///
2635+
/// [`Offer`]: crate::offers::offer
26872636
pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY: Duration = Duration::from_secs(60 * 60 * 24);
26882637

26892638
/// Used by [`ChannelManager::list_recent_payments`] to express the status of recent payments.
@@ -2692,8 +2641,10 @@ pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY: Duration = Duration::from_secs(60 * 6
26922641
pub enum RecentPaymentDetails {
26932642
/// When an invoice was requested and thus a payment has not yet been sent.
26942643
AwaitingInvoice {
2695-
/// A user-provided identifier in [`ChannelManager::pay_for_offer`] used to uniquely identify a
2644+
/// A user-provided identifier in [`OffersMessageFlow::pay_for_offer`] used to uniquely identify a
26962645
/// payment and ensure idempotency in LDK.
2646+
///
2647+
/// [`OffersMessageFlow::pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
26972648
payment_id: PaymentId,
26982649
},
26992650
/// When a payment is still being sent and awaiting successful delivery.
@@ -2702,7 +2653,7 @@ pub enum RecentPaymentDetails {
27022653
/// identify a payment and ensure idempotency in LDK.
27032654
///
27042655
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2705-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2656+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27062657
payment_id: PaymentId,
27072658
/// Hash of the payment that is currently being sent but has yet to be fulfilled or
27082659
/// abandoned.
@@ -2719,7 +2670,7 @@ pub enum RecentPaymentDetails {
27192670
/// identify a payment and ensure idempotency in LDK.
27202671
///
27212672
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2722-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2673+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27232674
payment_id: PaymentId,
27242675
/// Hash of the payment that was claimed. `None` for serializations of [`ChannelManager`]
27252676
/// made before LDK version 0.0.104.
@@ -2733,7 +2684,7 @@ pub enum RecentPaymentDetails {
27332684
/// identify a payment and ensure idempotency in LDK.
27342685
///
27352686
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2736-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2687+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27372688
payment_id: PaymentId,
27382689
/// Hash of the payment that we have given up trying to send.
27392690
payment_hash: PaymentHash,
@@ -4607,7 +4558,7 @@ where
46074558
///
46084559
/// # Requested Invoices
46094560
///
4610-
/// In the case of paying a [`Bolt12Invoice`] via [`ChannelManager::pay_for_offer`], abandoning
4561+
/// In the case of paying a [`Bolt12Invoice`] via [`OffersMessageFlow::pay_for_offer`], abandoning
46114562
/// the payment prior to receiving the invoice will result in an [`Event::PaymentFailed`] and
46124563
/// prevent any attempts at paying it once received.
46134564
///
@@ -4617,6 +4568,7 @@ where
46174568
/// [`ChannelManager`], another [`Event::PaymentFailed`] may be generated.
46184569
///
46194570
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
4571+
/// [`OffersMessageFlow::pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
46204572
pub fn abandon_payment(&self, payment_id: PaymentId) {
46214573
self.abandon_payment_with_reason(payment_id, PaymentFailureReason::UserAbandoned)
46224574
}
@@ -9348,6 +9300,13 @@ pub trait OffersMessageCommons {
93489300
///
93499301
/// [`Event::PaymentSent`]: events::Event::PaymentSent
93509302
fn list_recent_payments(&self) -> Vec<RecentPaymentDetails>;
9303+
9304+
/// Internal pay_for_offer
9305+
fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>> (
9306+
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
9307+
payer_note: Option<String>, payment_id: PaymentId,
9308+
human_readable_name: Option<HumanReadableName>, create_pending_payment: CPP,
9309+
) -> Result<(), Bolt12SemanticError>;
93519310
}
93529311

93539312
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>
@@ -9525,7 +9484,6 @@ where
95259484
}
95269485

95279486
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<(), ()> {
9528-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
95299487
self.pending_outbound_payments.add_new_awaiting_invoice (
95309488
payment_id, expiration, retry_strategy, max_total_routing_fee_msat, retryable_invoice_request,
95319489
)
@@ -9561,99 +9519,6 @@ where
95619519
})
95629520
.collect()
95639521
}
9564-
}
9565-
9566-
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
9567-
/// along different paths.
9568-
/// Sending multiple requests increases the chances of successful delivery in case some
9569-
/// paths are unavailable. However, only one invoice for a given [`PaymentId`] will be paid,
9570-
/// even if multiple invoices are received.
9571-
const OFFERS_MESSAGE_REQUEST_LIMIT: usize = 10;
9572-
9573-
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
9574-
where
9575-
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
9576-
T::Target: BroadcasterInterface,
9577-
ES::Target: EntropySource,
9578-
NS::Target: NodeSigner,
9579-
SP::Target: SignerProvider,
9580-
F::Target: FeeEstimator,
9581-
R::Target: Router,
9582-
MR::Target: MessageRouter,
9583-
L::Target: Logger,
9584-
{
9585-
/// Pays for an [`Offer`] using the given parameters by creating an [`InvoiceRequest`] and
9586-
/// enqueuing it to be sent via an onion message. [`ChannelManager`] will pay the actual
9587-
/// [`Bolt12Invoice`] once it is received.
9588-
///
9589-
/// Uses [`InvoiceRequestBuilder`] such that the [`InvoiceRequest`] it builds is recognized by
9590-
/// the [`ChannelManager`] when handling a [`Bolt12Invoice`] message in response to the request.
9591-
/// The optional parameters are used in the builder, if `Some`:
9592-
/// - `quantity` for [`InvoiceRequest::quantity`] which must be set if
9593-
/// [`Offer::expects_quantity`] is `true`.
9594-
/// - `amount_msats` if overpaying what is required for the given `quantity` is desired, and
9595-
/// - `payer_note` for [`InvoiceRequest::payer_note`].
9596-
///
9597-
/// If `max_total_routing_fee_msat` is not specified, The default from
9598-
/// [`RouteParameters::from_payment_params_and_value`] is applied.
9599-
///
9600-
/// # Payment
9601-
///
9602-
/// The provided `payment_id` is used to ensure that only one invoice is paid for the request
9603-
/// when received. See [Avoiding Duplicate Payments] for other requirements once the payment has
9604-
/// been sent.
9605-
///
9606-
/// To revoke the request, use [`ChannelManager::abandon_payment`] prior to receiving the
9607-
/// invoice. If abandoned, or an invoice isn't received in a reasonable amount of time, the
9608-
/// payment will fail with an [`Event::PaymentFailed`].
9609-
///
9610-
/// # Privacy
9611-
///
9612-
/// For payer privacy, uses a derived payer id and uses [`MessageRouter::create_blinded_paths`]
9613-
/// to construct a [`BlindedMessagePath`] for the reply path. For further privacy implications, see the
9614-
/// docs of the parameterized [`Router`], which implements [`MessageRouter`].
9615-
///
9616-
/// # Limitations
9617-
///
9618-
/// Requires a direct connection to an introduction node in [`Offer::paths`] or to
9619-
/// [`Offer::issuer_signing_pubkey`], if empty. A similar restriction applies to the responding
9620-
/// [`Bolt12Invoice::payment_paths`].
9621-
///
9622-
/// # Errors
9623-
///
9624-
/// Errors if:
9625-
/// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
9626-
/// - the provided parameters are invalid for the offer,
9627-
/// - the offer is for an unsupported chain, or
9628-
/// - the parameterized [`Router`] is unable to create a blinded reply path for the invoice
9629-
/// request.
9630-
///
9631-
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
9632-
/// [`InvoiceRequest::quantity`]: crate::offers::invoice_request::InvoiceRequest::quantity
9633-
/// [`InvoiceRequest::payer_note`]: crate::offers::invoice_request::InvoiceRequest::payer_note
9634-
/// [`InvoiceRequestBuilder`]: crate::offers::invoice_request::InvoiceRequestBuilder
9635-
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
9636-
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
9637-
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
9638-
pub fn pay_for_offer(
9639-
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
9640-
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
9641-
max_total_routing_fee_msat: Option<u64>
9642-
) -> Result<(), Bolt12SemanticError> {
9643-
self.pay_for_offer_intern(offer, quantity, amount_msats, payer_note, payment_id, None, |invoice_request, nonce| {
9644-
let expiration = StaleExpiration::TimerTicks(1);
9645-
let retryable_invoice_request = RetryableInvoiceRequest {
9646-
invoice_request: invoice_request.clone(),
9647-
nonce,
9648-
};
9649-
self.pending_outbound_payments
9650-
.add_new_awaiting_invoice(
9651-
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
9652-
Some(retryable_invoice_request)
9653-
)
9654-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
9655-
})
9656-
}
96579522

96589523
fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>>(
96599524
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
@@ -9701,7 +9566,27 @@ where
97019566

97029567
self.enqueue_invoice_request(invoice_request, reply_paths)
97039568
}
9569+
}
97049570

9571+
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
9572+
/// along different paths.
9573+
/// Sending multiple requests increases the chances of successful delivery in case some
9574+
/// paths are unavailable. However, only one invoice for a given [`PaymentId`] will be paid,
9575+
/// even if multiple invoices are received.
9576+
const OFFERS_MESSAGE_REQUEST_LIMIT: usize = 10;
9577+
9578+
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref> ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
9579+
where
9580+
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
9581+
T::Target: BroadcasterInterface,
9582+
ES::Target: EntropySource,
9583+
NS::Target: NodeSigner,
9584+
SP::Target: SignerProvider,
9585+
F::Target: FeeEstimator,
9586+
R::Target: Router,
9587+
MR::Target: MessageRouter,
9588+
L::Target: Logger,
9589+
{
97059590
/// Creates a [`Bolt12Invoice`] for a [`Refund`] and enqueues it to be sent via an onion
97069591
/// message.
97079592
///
@@ -12246,6 +12131,8 @@ where
1224612131
pub router: R,
1224712132
/// The [`MessageRouter`] used for constructing [`BlindedMessagePath`]s for [`Offer`]s,
1224812133
/// [`Refund`]s, and any reply paths.
12134+
///
12135+
/// [`Offer`]: crate::offers::offer
1224912136
pub message_router: MR,
1225012137
/// The Logger for use in the ChannelManager and which may be used to log information during
1225112138
/// deserialization.

lightning/src/ln/max_payment_path_len_tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ fn bolt12_invoice_too_large_blinded_paths() {
387387

388388
let offer = nodes[1].offers_handler.create_offer_builder(None).unwrap().build().unwrap();
389389
let payment_id = PaymentId([1; 32]);
390-
nodes[0].node.pay_for_offer(&offer, None, Some(5000), None, payment_id, Retry::Attempts(0), None).unwrap();
390+
nodes[0].offers_handler.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();
392392
nodes[1].onion_messenger.handle_onion_message(nodes[0].node.get_our_node_id(), &invreq_om);
393393

0 commit comments

Comments
 (0)