Skip to content

Introduce RouteParametersConfig #3342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lightning-dns-resolver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ mod test {
use lightning::onion_message::messenger::{
AOnionMessenger, Destination, MessageRouter, OnionMessagePath, OnionMessenger,
};
use lightning::routing::router::RouteParametersConfig;
use lightning::sign::{KeysManager, NodeSigner, Recipient};
use lightning::types::features::InitFeatures;
use lightning::types::payment::PaymentHash;
Expand Down Expand Up @@ -405,7 +406,14 @@ mod test {
let amt = 42_000;
nodes[0]
.node
.pay_for_offer_from_human_readable_name(name, amt, payment_id, retry, None, resolvers)
.pay_for_offer_from_human_readable_name(
name,
amt,
payment_id,
retry,
RouteParametersConfig::default(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: For stuff like this where rustfmt requires we blow up our code to cover 20 lines we should really create intermediate variables to see if we can avoid it.

resolvers,
)
.unwrap();

let query = nodes[0].onion_messenger.next_onion_message_for_peer(resolver_id).unwrap();
Expand Down
92 changes: 82 additions & 10 deletions lightning/src/ln/async_payments_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use crate::onion_message::messenger::{Destination, MessageRouter, MessageSendIns
use crate::onion_message::offers::OffersMessage;
use crate::onion_message::packet::ParsedOnionMessageContents;
use crate::prelude::*;
use crate::routing::router::{Payee, PaymentParameters};
use crate::routing::router::{Payee, PaymentParameters, RouteParametersConfig};
use crate::sign::NodeSigner;
use crate::sync::Mutex;
use crate::types::features::Bolt12InvoiceFeatures;
Expand Down Expand Up @@ -238,7 +238,15 @@ fn static_invoice_unknown_required_features() {
let payment_id = PaymentId([1; 32]);
nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(0),
RouteParametersConfig::default(),
)
.unwrap();

// Don't forward the invreq since we don't support retrieving the static invoice from the
Expand Down Expand Up @@ -298,7 +306,15 @@ fn ignore_unexpected_static_invoice() {
let payment_id = PaymentId([1; 32]);
nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(0),
RouteParametersConfig::default(),
)
.unwrap();

// Don't forward the invreq since we don't support retrieving the static invoice from the
Expand Down Expand Up @@ -415,7 +431,15 @@ fn async_receive_flow_success() {
let payment_id = PaymentId([1; 32]);
nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(0),
RouteParametersConfig::default(),
)
.unwrap();
let release_held_htlc_om =
pass_async_payments_oms(static_invoice, &nodes[0], &nodes[1], &nodes[2]).1;
Expand Down Expand Up @@ -463,7 +487,15 @@ fn expired_static_invoice_fail() {
let payment_id = PaymentId([1; 32]);
nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(0),
RouteParametersConfig::default(),
)
.unwrap();

let invreq_om = nodes[0]
Expand Down Expand Up @@ -546,7 +578,15 @@ fn async_receive_mpp() {
let payment_id = PaymentId([1; 32]);
nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(1), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(1),
RouteParametersConfig::default(),
)
.unwrap();
let release_held_htlc_om_3_0 =
pass_async_payments_oms(static_invoice, &nodes[0], &nodes[1], &nodes[3]).1;
Expand Down Expand Up @@ -630,7 +670,15 @@ fn amount_doesnt_match_invreq() {
let payment_id = PaymentId([1; 32]);
nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(1), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(1),
RouteParametersConfig::default(),
)
.unwrap();
let release_held_htlc_om_3_0 =
pass_async_payments_oms(static_invoice, &nodes[0], &nodes[1], &nodes[3]).1;
Expand Down Expand Up @@ -859,7 +907,15 @@ fn invalid_async_receive_with_retry<F1, F2>(

nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(2), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(2),
RouteParametersConfig::default(),
)
.unwrap();
let release_held_htlc_om_2_0 =
pass_async_payments_oms(static_invoice, &nodes[0], &nodes[1], &nodes[2]).1;
Expand Down Expand Up @@ -948,7 +1004,15 @@ fn expired_static_invoice_message_path() {
let payment_id = PaymentId([1; 32]);
nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(1), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(1),
RouteParametersConfig::default(),
)
.unwrap();

// While the invoice is unexpired, respond with release_held_htlc.
Expand Down Expand Up @@ -1052,7 +1116,15 @@ fn expired_static_invoice_payment_path() {
let payment_id = PaymentId([1; 32]);
nodes[0]
.node
.pay_for_offer(&offer, None, Some(amt_msat), None, payment_id, Retry::Attempts(0), None)
.pay_for_offer(
&offer,
None,
Some(amt_msat),
None,
payment_id,
Retry::Attempts(0),
RouteParametersConfig::default(),
)
.unwrap();
let release_held_htlc_om =
pass_async_payments_oms(static_invoice, &nodes[0], &nodes[1], &nodes[2]).1;
Expand Down
25 changes: 14 additions & 11 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use crate::types::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelType
use crate::types::features::Bolt11InvoiceFeatures;
#[cfg(trampoline)]
use crate::routing::gossip::NodeId;
use crate::routing::router::{BlindedTail, FixedRouter, InFlightHtlcs, Path, Payee, PaymentParameters, Route, RouteParameters, Router};
use crate::routing::router::{BlindedTail, FixedRouter, InFlightHtlcs, Path, Payee, PaymentParameters, Route, RouteParameters, RouteParametersConfig, Router};
use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, InboundHTLCErr, NextPacketDetails};
use crate::ln::msgs;
use crate::ln::onion_utils;
Expand Down Expand Up @@ -2096,6 +2096,7 @@ where
/// # use lightning::events::{Event, EventsProvider, PaymentPurpose};
/// # use lightning::ln::channelmanager::AChannelManager;
/// # use lightning::offers::parse::Bolt12SemanticError;
/// # use lightning::routing::router::RouteParametersConfig;
/// #
/// # fn example<T: AChannelManager>(channel_manager: T) -> Result<(), Bolt12SemanticError> {
/// # let channel_manager = channel_manager.get_cm();
Expand Down Expand Up @@ -2143,15 +2144,16 @@ where
/// # use lightning::events::{Event, EventsProvider};
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
/// # use lightning::offers::offer::Offer;
/// # use lightning::routing::router::RouteParametersConfig;
/// #
/// # fn example<T: AChannelManager>(
/// # channel_manager: T, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
/// # payer_note: Option<String>, retry: Retry, max_total_routing_fee_msat: Option<u64>
/// # payer_note: Option<String>, retry: Retry, route_params_config: RouteParametersConfig
/// # ) {
/// # let channel_manager = channel_manager.get_cm();
/// let payment_id = PaymentId([42; 32]);
/// match channel_manager.pay_for_offer(
/// offer, quantity, amount_msats, payer_note, payment_id, retry, max_total_routing_fee_msat
/// offer, quantity, amount_msats, payer_note, payment_id, retry, route_params_config
/// ) {
/// Ok(()) => println!("Requesting invoice for offer"),
/// Err(e) => println!("Unable to request invoice for offer: {:?}", e),
Expand Down Expand Up @@ -2199,16 +2201,17 @@ where
/// # use lightning::events::{Event, EventsProvider};
/// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, Retry};
/// # use lightning::offers::parse::Bolt12SemanticError;
/// # use lightning::routing::router::RouteParametersConfig;
/// #
/// # fn example<T: AChannelManager>(
/// # channel_manager: T, amount_msats: u64, absolute_expiry: Duration, retry: Retry,
/// # max_total_routing_fee_msat: Option<u64>
/// # route_params_config: RouteParametersConfig
/// # ) -> Result<(), Bolt12SemanticError> {
/// # let channel_manager = channel_manager.get_cm();
/// let payment_id = PaymentId([42; 32]);
/// let refund = channel_manager
/// .create_refund_builder(
/// amount_msats, absolute_expiry, payment_id, retry, max_total_routing_fee_msat
/// amount_msats, absolute_expiry, payment_id, retry, route_params_config
/// )?
/// # ;
/// # // Needed for compiling for c_bindings
Expand Down Expand Up @@ -9983,7 +9986,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
pub fn create_refund_builder(
&$self, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId,
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>
retry_strategy: Retry, route_params_config: RouteParametersConfig
) -> Result<$builder, Bolt12SemanticError> {
let node_id = $self.get_our_node_id();
let expanded_key = &$self.inbound_payment_key;
Expand All @@ -10008,7 +10011,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
let expiration = StaleExpiration::AbsoluteTimeout(absolute_expiry);
$self.pending_outbound_payments
.add_new_awaiting_invoice(
payment_id, expiration, retry_strategy, max_total_routing_fee_msat, None,
payment_id, expiration, retry_strategy, route_params_config, None,
)
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;

Expand Down Expand Up @@ -10184,7 +10187,7 @@ where
pub fn pay_for_offer(
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
payer_note: Option<String>, payment_id: PaymentId, retry_strategy: Retry,
max_total_routing_fee_msat: Option<u64>
route_params_config: RouteParametersConfig
) -> Result<(), Bolt12SemanticError> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK no needed option here but: what do you think about having the function call like pay_for_offer(offer, OfferParams::default()) where OfferParams is something like that

struct OfferParams {
    quantity: Option<u64>,
    amount_msats: Option<u64>,
    manual_routing_params: Option<ManualRoutingParameters>,
}

I think is a lot of more verbose in this way, but I also this that this will be a lot of cleaner.

Now I do not think this will fit well in this PR maybe can be a followup one, but with this patter, it is possible to hide future updates to offers (e.g: recurrence or market place feature) without breaking too much the code

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a great improvement! It will help keep the function signature cleaner while remaining maintainable for future parameter increases.

Maybe we can take this in a follow-up. @TheBlueMatt, what do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No strong opinions.

self.pay_for_offer_intern(offer, quantity, amount_msats, payer_note, payment_id, None, |invoice_request, nonce| {
let expiration = StaleExpiration::TimerTicks(1);
Expand All @@ -10195,7 +10198,7 @@ where
};
self.pending_outbound_payments
.add_new_awaiting_invoice(
payment_id, expiration, retry_strategy, max_total_routing_fee_msat,
payment_id, expiration, retry_strategy, route_params_config,
Some(retryable_invoice_request)
)
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
Expand Down Expand Up @@ -10428,14 +10431,14 @@ where
#[cfg(feature = "dnssec")]
pub fn pay_for_offer_from_human_readable_name(
&self, name: HumanReadableName, amount_msats: u64, payment_id: PaymentId,
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>,
retry_strategy: Retry, route_params_config: RouteParametersConfig,
dns_resolvers: Vec<Destination>,
) -> Result<(), ()> {
let (onion_message, context) =
self.hrn_resolver.resolve_name(payment_id, name, &*self.entropy_source)?;
let reply_paths = self.create_blinded_paths(MessageContext::DNSResolver(context))?;
let expiration = StaleExpiration::TimerTicks(1);
self.pending_outbound_payments.add_new_awaiting_offer(payment_id, expiration, retry_strategy, max_total_routing_fee_msat, amount_msats)?;
self.pending_outbound_payments.add_new_awaiting_offer(payment_id, expiration, retry_strategy, route_params_config, amount_msats)?;
let message_params = dns_resolvers
.iter()
.flat_map(|destination| reply_paths.iter().map(move |path| (path, destination)))
Expand Down
4 changes: 2 additions & 2 deletions lightning/src/ln/max_payment_path_len_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::ln::onion_utils::MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY;
use crate::ln::outbound_payment::{RecipientOnionFields, Retry, RetryableSendFailure};
use crate::offers::nonce::Nonce;
use crate::prelude::*;
use crate::routing::router::{DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA, PaymentParameters, RouteParameters};
use crate::routing::router::{PaymentParameters, RouteParameters, RouteParametersConfig, DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA};
use crate::sign::NodeSigner;
use crate::util::errors::APIError;
use crate::util::ser::Writeable;
Expand Down Expand Up @@ -393,7 +393,7 @@ fn bolt12_invoice_too_large_blinded_paths() {

let offer = nodes[1].node.create_offer_builder(None).unwrap().build().unwrap();
let payment_id = PaymentId([1; 32]);
nodes[0].node.pay_for_offer(&offer, None, Some(5000), None, payment_id, Retry::Attempts(0), None).unwrap();
nodes[0].node.pay_for_offer(&offer, None, Some(5000), None, payment_id, Retry::Attempts(0), RouteParametersConfig::default()).unwrap();
let invreq_om = nodes[0].onion_messenger.next_onion_message_for_peer(nodes[1].node.get_our_node_id()).unwrap();
nodes[1].onion_messenger.handle_onion_message(nodes[0].node.get_our_node_id(), &invreq_om);

Expand Down
Loading
Loading