Skip to content

Commit 8e7c5f1

Browse files
committed
Move pay_for_offer to OffersMessageFlow
1 parent 9c5d746 commit 8e7c5f1

File tree

4 files changed

+211
-174
lines changed

4 files changed

+211
-174
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 36 additions & 152 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, ChannelPhase, ChannelError, ChannelUpdateStatus, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext, InboundV2Channel, InteractivelyFunded as _};
@@ -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;
@@ -2022,57 +2022,7 @@ where
20222022
///
20232023
/// For more information on creating offers, see [`create_offer_builder`].
20242024
///
2025-
/// Use [`pay_for_offer`] to initiated payment, which sends an [`InvoiceRequest`] for an [`Offer`]
2026-
/// and pays the [`Bolt12Invoice`] response.
2027-
///
2028-
/// ```
2029-
/// # use lightning::events::{Event, EventsProvider};
2030-
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
2031-
/// # use lightning::offers::flow::OffersMessageCommons;
2032-
/// # use lightning::offers::offer::Offer;
2033-
/// #
2034-
/// # fn example<T: AChannelManager>(
2035-
/// # channel_manager: T, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
2036-
/// # payer_note: Option<String>, retry: Retry, max_total_routing_fee_msat: Option<u64>
2037-
/// # ) {
2038-
/// # let channel_manager = channel_manager.get_cm();
2039-
/// let payment_id = PaymentId([42; 32]);
2040-
/// match channel_manager.pay_for_offer(
2041-
/// offer, quantity, amount_msats, payer_note, payment_id, retry, max_total_routing_fee_msat
2042-
/// ) {
2043-
/// Ok(()) => println!("Requesting invoice for offer"),
2044-
/// Err(e) => println!("Unable to request invoice for offer: {:?}", e),
2045-
/// }
2046-
///
2047-
/// // First the payment will be waiting on an invoice
2048-
/// let expected_payment_id = payment_id;
2049-
/// assert!(
2050-
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
2051-
/// details,
2052-
/// RecentPaymentDetails::AwaitingInvoice { payment_id: expected_payment_id }
2053-
/// )).is_some()
2054-
/// );
2055-
///
2056-
/// // Once the invoice is received, a payment will be sent
2057-
/// assert!(
2058-
/// channel_manager.list_recent_payments().iter().find(|details| matches!(
2059-
/// details,
2060-
/// RecentPaymentDetails::Pending { payment_id: expected_payment_id, .. }
2061-
/// )).is_some()
2062-
/// );
2063-
///
2064-
/// // On the event processing thread
2065-
/// channel_manager.process_pending_events(&|event| {
2066-
/// match event {
2067-
/// Event::PaymentSent { payment_id: Some(payment_id), .. } => println!("Paid {}", payment_id),
2068-
/// Event::PaymentFailed { payment_id, .. } => println!("Failed paying {}", payment_id),
2069-
/// // ...
2070-
/// # _ => {},
2071-
/// }
2072-
/// Ok(())
2073-
/// });
2074-
/// # }
2075-
/// ```
2025+
/// For details on initiating payments for offers, see [`pay_for_offer`].
20762026
///
20772027
/// ## BOLT 12 Refunds
20782028
///
@@ -2203,7 +2153,7 @@ where
22032153
/// [`claim_funds`]: Self::claim_funds
22042154
/// [`send_payment`]: Self::send_payment
22052155
/// [`offers`]: crate::offers
2206-
/// [`pay_for_offer`]: Self::pay_for_offer
2156+
/// [`Offer`]: crate::offers::offer
22072157
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
22082158
/// [`request_refund_payment`]: Self::request_refund_payment
22092159
/// [`peer_disconnected`]: msgs::ChannelMessageHandler::peer_disconnected
@@ -2214,6 +2164,7 @@ where
22142164
/// [`ChannelUpdate`]: msgs::ChannelUpdate
22152165
/// [`read`]: ReadableArgs::read
22162166
/// [`create_offer_builder`]: crate::offers::flow::OffersMessageFlow::create_offer_builder
2167+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
22172168
/// [`create_refund_builder`]: crate::offers::flow::OffersMessageFlow::create_refund_builder
22182169
//
22192170
// Lock order:
@@ -2725,6 +2676,8 @@ const MAX_NO_CHANNEL_PEERS: usize = 250;
27252676
/// Using compact [`BlindedMessagePath`]s may provide better privacy as the [`MessageRouter`] could select
27262677
/// more hops. However, since they use short channel ids instead of pubkeys, they are more likely to
27272678
/// become invalid over time as channels are closed. Thus, they are only suitable for short-term use.
2679+
///
2680+
/// [`Offer`]: crate::offers::offer
27282681
pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY: Duration = Duration::from_secs(60 * 60 * 24);
27292682

27302683
/// Used by [`ChannelManager::list_recent_payments`] to express the status of recent payments.
@@ -2733,8 +2686,10 @@ pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY: Duration = Duration::from_secs(60 * 6
27332686
pub enum RecentPaymentDetails {
27342687
/// When an invoice was requested and thus a payment has not yet been sent.
27352688
AwaitingInvoice {
2736-
/// A user-provided identifier in [`ChannelManager::pay_for_offer`] used to uniquely identify a
2689+
/// A user-provided identifier in [`OffersMessageFlow::pay_for_offer`] used to uniquely identify a
27372690
/// payment and ensure idempotency in LDK.
2691+
///
2692+
/// [`OffersMessageFlow::pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27382693
payment_id: PaymentId,
27392694
},
27402695
/// When a payment is still being sent and awaiting successful delivery.
@@ -2743,7 +2698,7 @@ pub enum RecentPaymentDetails {
27432698
/// identify a payment and ensure idempotency in LDK.
27442699
///
27452700
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2746-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2701+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27472702
payment_id: PaymentId,
27482703
/// Hash of the payment that is currently being sent but has yet to be fulfilled or
27492704
/// abandoned.
@@ -2760,7 +2715,7 @@ pub enum RecentPaymentDetails {
27602715
/// identify a payment and ensure idempotency in LDK.
27612716
///
27622717
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2763-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2718+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27642719
payment_id: PaymentId,
27652720
/// Hash of the payment that was claimed. `None` for serializations of [`ChannelManager`]
27662721
/// made before LDK version 0.0.104.
@@ -2774,7 +2729,7 @@ pub enum RecentPaymentDetails {
27742729
/// identify a payment and ensure idempotency in LDK.
27752730
///
27762731
/// [`send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
2777-
/// [`pay_for_offer`]: crate::ln::channelmanager::ChannelManager::pay_for_offer
2732+
/// [`pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
27782733
payment_id: PaymentId,
27792734
/// Hash of the payment that we have given up trying to send.
27802735
payment_hash: PaymentHash,
@@ -4674,7 +4629,7 @@ where
46744629
///
46754630
/// # Requested Invoices
46764631
///
4677-
/// In the case of paying a [`Bolt12Invoice`] via [`ChannelManager::pay_for_offer`], abandoning
4632+
/// In the case of paying a [`Bolt12Invoice`] via [`OffersMessageFlow::pay_for_offer`], abandoning
46784633
/// the payment prior to receiving the invoice will result in an [`Event::PaymentFailed`] and
46794634
/// prevent any attempts at paying it once received.
46804635
///
@@ -4684,6 +4639,7 @@ where
46844639
/// [`ChannelManager`], another [`Event::PaymentFailed`] may be generated.
46854640
///
46864641
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
4642+
/// [`OffersMessageFlow::pay_for_offer`]: crate::offers::flow::OffersMessageFlow::pay_for_offer
46874643
pub fn abandon_payment(&self, payment_id: PaymentId) {
46884644
self.abandon_payment_with_reason(payment_id, PaymentFailureReason::UserAbandoned)
46894645
}
@@ -9839,104 +9795,10 @@ where
98399795
}
98409796

98419797
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<(), ()> {
9842-
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
98439798
self.pending_outbound_payments.add_new_awaiting_invoice (
98449799
payment_id, expiration, retry_strategy, max_total_routing_fee_msat, retryable_invoice_request,
98459800
)
98469801
}
9847-
}
9848-
9849-
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
9850-
/// along different paths.
9851-
/// Sending multiple requests increases the chances of successful delivery in case some
9852-
/// paths are unavailable. However, only one invoice for a given [`PaymentId`] will be paid,
9853-
/// even if multiple invoices are received.
9854-
const OFFERS_MESSAGE_REQUEST_LIMIT: usize = 10;
9855-
9856-
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>
9857-
where
9858-
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
9859-
T::Target: BroadcasterInterface,
9860-
ES::Target: EntropySource,
9861-
NS::Target: NodeSigner,
9862-
SP::Target: SignerProvider,
9863-
F::Target: FeeEstimator,
9864-
R::Target: Router,
9865-
MR::Target: MessageRouter,
9866-
L::Target: Logger,
9867-
{
9868-
/// Pays for an [`Offer`] using the given parameters by creating an [`InvoiceRequest`] and
9869-
/// enqueuing it to be sent via an onion message. [`ChannelManager`] will pay the actual
9870-
/// [`Bolt12Invoice`] once it is received.
9871-
///
9872-
/// Uses [`InvoiceRequestBuilder`] such that the [`InvoiceRequest`] it builds is recognized by
9873-
/// the [`ChannelManager`] when handling a [`Bolt12Invoice`] message in response to the request.
9874-
/// The optional parameters are used in the builder, if `Some`:
9875-
/// - `quantity` for [`InvoiceRequest::quantity`] which must be set if
9876-
/// [`Offer::expects_quantity`] is `true`.
9877-
/// - `amount_msats` if overpaying what is required for the given `quantity` is desired, and
9878-
/// - `payer_note` for [`InvoiceRequest::payer_note`].
9879-
///
9880-
/// If `max_total_routing_fee_msat` is not specified, The default from
9881-
/// [`RouteParameters::from_payment_params_and_value`] is applied.
9882-
///
9883-
/// # Payment
9884-
///
9885-
/// The provided `payment_id` is used to ensure that only one invoice is paid for the request
9886-
/// when received. See [Avoiding Duplicate Payments] for other requirements once the payment has
9887-
/// been sent.
9888-
///
9889-
/// To revoke the request, use [`ChannelManager::abandon_payment`] prior to receiving the
9890-
/// invoice. If abandoned, or an invoice isn't received in a reasonable amount of time, the
9891-
/// payment will fail with an [`Event::PaymentFailed`].
9892-
///
9893-
/// # Privacy
9894-
///
9895-
/// For payer privacy, uses a derived payer id and uses [`MessageRouter::create_blinded_paths`]
9896-
/// to construct a [`BlindedMessagePath`] for the reply path. For further privacy implications, see the
9897-
/// docs of the parameterized [`Router`], which implements [`MessageRouter`].
9898-
///
9899-
/// # Limitations
9900-
///
9901-
/// Requires a direct connection to an introduction node in [`Offer::paths`] or to
9902-
/// [`Offer::issuer_signing_pubkey`], if empty. A similar restriction applies to the responding
9903-
/// [`Bolt12Invoice::payment_paths`].
9904-
///
9905-
/// # Errors
9906-
///
9907-
/// Errors if:
9908-
/// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
9909-
/// - the provided parameters are invalid for the offer,
9910-
/// - the offer is for an unsupported chain, or
9911-
/// - the parameterized [`Router`] is unable to create a blinded reply path for the invoice
9912-
/// request.
9913-
///
9914-
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
9915-
/// [`InvoiceRequest::quantity`]: crate::offers::invoice_request::InvoiceRequest::quantity
9916-
/// [`InvoiceRequest::payer_note`]: crate::offers::invoice_request::InvoiceRequest::payer_note
9917-
/// [`InvoiceRequestBuilder`]: crate::offers::invoice_request::InvoiceRequestBuilder
9918-
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
9919-
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
9920-
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
9921-
pub fn pay_for_offer(
9922-
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
9923-
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
9924-
max_total_routing_fee_msat: Option<u64>
9925-
) -> Result<(), Bolt12SemanticError> {
9926-
self.pay_for_offer_intern(offer, quantity, amount_msats, payer_note, payment_id, None, |invoice_request, nonce| {
9927-
let expiration = StaleExpiration::TimerTicks(1);
9928-
let retryable_invoice_request = RetryableInvoiceRequest {
9929-
invoice_request: invoice_request.clone(),
9930-
nonce,
9931-
};
9932-
self.pending_outbound_payments
9933-
.add_new_awaiting_invoice(
9934-
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
9935-
Some(retryable_invoice_request)
9936-
)
9937-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
9938-
})
9939-
}
99409802

99419803
fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>>(
99429804
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
@@ -9984,7 +9846,27 @@ where
99849846

99859847
self.enqueue_invoice_request(invoice_request, reply_paths)
99869848
}
9849+
}
9850+
9851+
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
9852+
/// along different paths.
9853+
/// Sending multiple requests increases the chances of successful delivery in case some
9854+
/// paths are unavailable. However, only one invoice for a given [`PaymentId`] will be paid,
9855+
/// even if multiple invoices are received.
9856+
const OFFERS_MESSAGE_REQUEST_LIMIT: usize = 10;
99879857

9858+
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>
9859+
where
9860+
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
9861+
T::Target: BroadcasterInterface,
9862+
ES::Target: EntropySource,
9863+
NS::Target: NodeSigner,
9864+
SP::Target: SignerProvider,
9865+
F::Target: FeeEstimator,
9866+
R::Target: Router,
9867+
MR::Target: MessageRouter,
9868+
L::Target: Logger,
9869+
{
99889870
/// Creates a [`Bolt12Invoice`] for a [`Refund`] and enqueues it to be sent via an onion
99899871
/// message.
99909872
///
@@ -12552,6 +12434,8 @@ where
1255212434
pub router: R,
1255312435
/// The [`MessageRouter`] used for constructing [`BlindedMessagePath`]s for [`Offer`]s,
1255412436
/// [`Refund`]s, and any reply paths.
12437+
///
12438+
/// [`Offer`]: crate::offers::offer
1255512439
pub message_router: MR,
1255612440
/// The Logger for use in the ChannelManager and which may be used to log information during
1255712441
/// deserialization.

lightning/src/ln/max_payment_path_len_tests.rs

Lines changed: 1 addition & 1 deletion
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)