Skip to content

Commit d1469d8

Browse files
committed
Move reasonable-default arguments out of pay_for_offer.
`ChannelManager::pay_for_offer` and `ChannelManager::pay_for_offer_from_human_readable_name` have accumulated a handful of arguments, most of which we expect users to never actually set. Instead, here, we move `quantity` and `payer_note` (which we expect users to never set) as well as `route_params_config` and `retry_strategy` (which we expect users to generally stick with the defaults on) into a new struct, which implements `Default`. This cleans up a good bit of cruft on payment calls.
1 parent 6771d84 commit d1469d8

File tree

4 files changed

+102
-79
lines changed

4 files changed

+102
-79
lines changed

lightning-dns-resolver/src/lib.rs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ mod test {
162162
use lightning::blinded_path::message::{BlindedMessagePath, MessageContext};
163163
use lightning::blinded_path::NodeIdLookUp;
164164
use lightning::events::{Event, PaymentPurpose};
165-
use lightning::ln::channelmanager::{PaymentId, Retry};
165+
use lightning::ln::channelmanager::{OptionalOfferPaymentInfo, PaymentId};
166166
use lightning::ln::functional_test_utils::*;
167167
use lightning::ln::msgs::{
168168
BaseMessageHandler, ChannelMessageHandler, Init, OnionMessageHandler,
@@ -173,7 +173,6 @@ mod test {
173173
use lightning::onion_message::messenger::{
174174
AOnionMessenger, Destination, MessageRouter, OnionMessagePath, OnionMessenger,
175175
};
176-
use lightning::routing::router::RouteParametersConfig;
177176
use lightning::sign::{KeysManager, NodeSigner, Recipient};
178177
use lightning::types::features::InitFeatures;
179178
use lightning::types::payment::PaymentHash;
@@ -369,23 +368,18 @@ mod test {
369368
async fn pay_offer_flow<'a, 'b, 'c>(
370369
nodes: &[Node<'a, 'b, 'c>], resolver_messenger: &impl AOnionMessenger,
371370
resolver_id: PublicKey, payer_id: PublicKey, payee_id: PublicKey, offer: Offer,
372-
name: HumanReadableName, amt: u64, payment_id: PaymentId, payer_note: Option<String>,
373-
retry: Retry, params: RouteParametersConfig, resolvers: Vec<Destination>,
371+
name: HumanReadableName, payment_id: PaymentId, payer_note: Option<String>,
372+
resolvers: Vec<Destination>,
374373
) {
375374
// Override contents to offer provided
376375
let proof_override = &nodes[0].node.testing_dnssec_proof_offer_resolution_override;
377376
proof_override.lock().unwrap().insert(name.clone(), offer);
377+
let amt = 42_000;
378+
let mut opts = OptionalOfferPaymentInfo::default();
379+
opts.payer_note = payer_note.clone();
378380
nodes[0]
379381
.node
380-
.pay_for_offer_from_human_readable_name(
381-
name,
382-
amt,
383-
payment_id,
384-
payer_note.clone(),
385-
retry,
386-
params,
387-
resolvers,
388-
)
382+
.pay_for_offer_from_human_readable_name(name, amt, payment_id, opts, resolvers)
389383
.unwrap();
390384

391385
let query = nodes[0].onion_messenger.next_onion_message_for_peer(resolver_id).unwrap();
@@ -482,9 +476,6 @@ mod test {
482476

483477
let bs_offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
484478
let resolvers = vec![Destination::Node(resolver_id)];
485-
let retry = Retry::Attempts(0);
486-
let amt = 42_000;
487-
let params = RouteParametersConfig::default();
488479

489480
pay_offer_flow(
490481
&nodes,
@@ -494,11 +485,8 @@ mod test {
494485
payee_id,
495486
bs_offer.clone(),
496487
name.clone(),
497-
amt,
498488
PaymentId([42; 32]),
499489
None,
500-
retry,
501-
params,
502490
resolvers.clone(),
503491
)
504492
.await;
@@ -512,11 +500,8 @@ mod test {
512500
payee_id,
513501
bs_offer,
514502
name,
515-
amt,
516503
PaymentId([21; 32]),
517504
Some("foo".into()),
518-
retry,
519-
params,
520505
resolvers,
521506
)
522507
.await;

lightning/src/ln/channelmanager.rs

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,53 @@ impl Readable for InterceptId {
687687
}
688688
}
689689

690+
/// Optional arguments to [`ChannelManager::pay_for_offer`]
691+
#[cfg_attr(
692+
feature = "dnssec",
693+
doc = "and [`ChannelManager::pay_for_offer_from_human_readable_name`]"
694+
)]
695+
/// .
696+
///
697+
/// These fields will often not need to be set, and the provided [`Self::default`] can be used.
698+
pub struct OptionalOfferPaymentInfo {
699+
/// The quantity of the offer which we wish to pay for. This is communicated to the recipient
700+
/// and determines the minimum value which we must pay.
701+
///
702+
/// This must be set if we're paying for an offer that has [`Offer::expects_quantity`].
703+
///
704+
#[cfg_attr(
705+
feature = "dnssec",
706+
doc = "Note that setting this will cause [`ChannelManager::pay_for_offer_from_human_readable_name`] to fail."
707+
)]
708+
pub quantity: Option<u64>,
709+
/// A note which is communicated to the recipient about this payment via
710+
/// [`InvoiceRequest::payer_note`].
711+
pub payer_note: Option<String>,
712+
/// Pathfinding options which tweak how the path is constructed to the recipient.
713+
pub route_params_config: RouteParametersConfig,
714+
/// The number of tries or time during which we'll retry this payment if some paths to the
715+
/// recipient fail.
716+
///
717+
/// Once the retry limit is reached, further path failures will not be retried and the payment
718+
/// will ultimately fail once all pending paths have failed (generating an
719+
/// [`Event::PaymentFailed`]).
720+
pub retry_strategy: Retry,
721+
}
722+
723+
impl Default for OptionalOfferPaymentInfo {
724+
fn default() -> Self {
725+
Self {
726+
quantity: None,
727+
payer_note: None,
728+
route_params_config: Default::default(),
729+
#[cfg(feature = "std")]
730+
retry_strategy: Retry::Timeout(core::time::Duration::from_secs(2)),
731+
#[cfg(not(feature = "std"))]
732+
retry_strategy: Retry::Attempts(3),
733+
}
734+
}
735+
}
736+
690737
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
691738
/// Uniquely describes an HTLC by its source. Just the guaranteed-unique subset of [`HTLCSource`].
692739
pub(crate) enum SentHTLCId {
@@ -2256,18 +2303,16 @@ where
22562303
///
22572304
/// ```
22582305
/// # use lightning::events::{Event, EventsProvider};
2259-
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
2306+
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails};
22602307
/// # use lightning::offers::offer::Offer;
2261-
/// # use lightning::routing::router::RouteParametersConfig;
22622308
/// #
22632309
/// # fn example<T: AChannelManager>(
2264-
/// # channel_manager: T, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
2265-
/// # payer_note: Option<String>, retry: Retry, route_params_config: RouteParametersConfig
2310+
/// # channel_manager: T, offer: &Offer, amount_msats: Option<u64>,
22662311
/// # ) {
22672312
/// # let channel_manager = channel_manager.get_cm();
22682313
/// let payment_id = PaymentId([42; 32]);
22692314
/// match channel_manager.pay_for_offer(
2270-
/// offer, quantity, amount_msats, payer_note, payment_id, retry, route_params_config
2315+
/// offer, amount_msats, payment_id, Default::default(),
22712316
/// ) {
22722317
/// Ok(()) => println!("Requesting invoice for offer"),
22732318
/// Err(e) => println!("Unable to request invoice for offer: {:?}", e),
@@ -5024,6 +5069,9 @@ where
50245069
/// Sends a payment to the route found using the provided [`RouteParameters`], retrying failed
50255070
/// payment paths based on the provided `Retry`.
50265071
///
5072+
/// You should likely prefer [`Self::pay_for_bolt11_invoice`] or [`Self::pay_for_offer`] in
5073+
/// general, however this method may allow for slightly more customization.
5074+
///
50275075
/// May generate [`UpdateHTLCs`] message(s) event on success, which should be relayed (e.g. via
50285076
/// [`PeerManager::process_events`]).
50295077
///
@@ -11128,16 +11176,9 @@ where
1112811176
///
1112911177
/// Uses [`InvoiceRequestBuilder`] such that the [`InvoiceRequest`] it builds is recognized by
1113011178
/// the [`ChannelManager`] when handling a [`Bolt12Invoice`] message in response to the request.
11131-
/// The optional parameters are used in the builder, if `Some`:
11132-
/// - `quantity` for [`InvoiceRequest::quantity`] which must be set if
11133-
/// [`Offer::expects_quantity`] is `true`.
11134-
/// - `amount_msats` if overpaying what is required for the given `quantity` is desired, and
11135-
/// - `payer_note` for [`InvoiceRequest::payer_note`].
1113611179
///
11137-
/// # Custom Routing Parameters
11138-
///
11139-
/// Users can customize routing parameters via [`RouteParametersConfig`].
11140-
/// To use default settings, call the function with [`RouteParametersConfig::default`].
11180+
/// `amount_msats` allows you to overpay what is required to satisfy the offer, or may be
11181+
/// required if the offer does not require a specific amount.
1114111182
///
1114211183
/// # Payment
1114311184
///
@@ -11179,9 +11220,8 @@ where
1117911220
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
1118011221
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
1118111222
pub fn pay_for_offer(
11182-
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
11183-
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
11184-
route_params_config: RouteParametersConfig,
11223+
&self, offer: &Offer, amount_msats: Option<u64>, payment_id: PaymentId,
11224+
optional_info: OptionalOfferPaymentInfo,
1118511225
) -> Result<(), Bolt12SemanticError> {
1118611226
let create_pending_payment_fn = |invoice_request: &InvoiceRequest, nonce| {
1118711227
let expiration = StaleExpiration::TimerTicks(1);
@@ -11194,18 +11234,18 @@ where
1119411234
.add_new_awaiting_invoice(
1119511235
payment_id,
1119611236
expiration,
11197-
retry_strategy,
11198-
route_params_config,
11237+
optional_info.retry_strategy,
11238+
optional_info.route_params_config,
1119911239
Some(retryable_invoice_request),
1120011240
)
1120111241
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
1120211242
};
1120311243

1120411244
self.pay_for_offer_intern(
1120511245
offer,
11206-
quantity,
11246+
optional_info.quantity,
1120711247
amount_msats,
11208-
payer_note,
11248+
optional_info.payer_note,
1120911249
payment_id,
1121011250
None,
1121111251
create_pending_payment_fn,
@@ -11313,11 +11353,6 @@ where
1131311353
/// implementing [`DNSResolverMessageHandler`]) directly to look up a URI and then delegate to
1131411354
/// your normal URI handling.
1131511355
///
11316-
/// # Custom Routing Parameters
11317-
///
11318-
/// Users can customize routing parameters via [`RouteParametersConfig`].
11319-
/// To use default settings, call the function with [`RouteParametersConfig::default`].
11320-
///
1132111356
/// # Payment
1132211357
///
1132311358
/// The provided `payment_id` is used to ensure that only one invoice is paid for the request
@@ -11345,6 +11380,7 @@ where
1134511380
///
1134611381
/// Errors if:
1134711382
/// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
11383+
/// - [`OptionalOfferPaymentInfo.quantity`] is set.
1134811384
///
1134911385
/// [BIP 353]: https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki
1135011386
/// [bLIP 32]: https://github.com/lightning/blips/blob/master/blip-0032.md
@@ -11358,20 +11394,23 @@ where
1135811394
#[cfg(feature = "dnssec")]
1135911395
pub fn pay_for_offer_from_human_readable_name(
1136011396
&self, name: HumanReadableName, amount_msats: u64, payment_id: PaymentId,
11361-
payer_note: Option<String>, retry_strategy: Retry,
11362-
route_params_config: RouteParametersConfig, dns_resolvers: Vec<Destination>,
11397+
optional_info: OptionalOfferPaymentInfo, dns_resolvers: Vec<Destination>,
1136311398
) -> Result<(), ()> {
11399+
if optional_info.quantity.is_some() {
11400+
return Err(());
11401+
}
11402+
1136411403
let (onion_message, context) =
1136511404
self.flow.hrn_resolver.resolve_name(payment_id, name, &*self.entropy_source)?;
1136611405

1136711406
let expiration = StaleExpiration::TimerTicks(1);
1136811407
self.pending_outbound_payments.add_new_awaiting_offer(
1136911408
payment_id,
1137011409
expiration,
11371-
retry_strategy,
11372-
route_params_config,
11410+
optional_info.retry_strategy,
11411+
optional_info.route_params_config,
1137311412
amount_msats,
11374-
payer_note,
11413+
optional_info.payer_note,
1137511414
)?;
1137611415

1137711416
self.flow

lightning/src/ln/max_payment_path_len_tests.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::blinded_path::payment::{
1717
use crate::blinded_path::BlindedHop;
1818
use crate::events::Event;
1919
use crate::ln::blinded_payment_tests::get_blinded_route_parameters;
20-
use crate::ln::channelmanager::PaymentId;
20+
use crate::ln::channelmanager::{OptionalOfferPaymentInfo, PaymentId};
2121
use crate::ln::functional_test_utils::*;
2222
use crate::ln::msgs;
2323
use crate::ln::msgs::{BaseMessageHandler, OnionMessageHandler};
@@ -27,7 +27,7 @@ use crate::ln::outbound_payment::{RecipientOnionFields, Retry, RetryableSendFail
2727
use crate::offers::nonce::Nonce;
2828
use crate::prelude::*;
2929
use crate::routing::router::{
30-
PaymentParameters, RouteParameters, RouteParametersConfig, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
30+
PaymentParameters, RouteParameters, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
3131
};
3232
use crate::sign::NodeSigner;
3333
use crate::types::features::BlindedHopFeatures;
@@ -519,10 +519,9 @@ fn bolt12_invoice_too_large_blinded_paths() {
519519

520520
let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
521521
let payment_id = PaymentId([1; 32]);
522-
let route_config = RouteParametersConfig::default();
523522
nodes[0]
524523
.node
525-
.pay_for_offer(&offer, None, Some(5000), None, payment_id, Retry::Attempts(0), route_config)
524+
.pay_for_offer(&offer, Some(5000), payment_id, OptionalOfferPaymentInfo::default())
526525
.unwrap();
527526
let invreq_om = nodes[0]
528527
.onion_messenger

0 commit comments

Comments
 (0)