Skip to content

Commit 78cc64f

Browse files
committed
Move pay_for_offer_human_readable to OffersMessageFlow
1 parent 43a3d52 commit 78cc64f

File tree

3 files changed

+116
-68
lines changed

3 files changed

+116
-68
lines changed

lightning-dns-resolver/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ mod test {
404404
let retry = Retry::Attempts(0);
405405
let amt = 42_000;
406406
nodes[0]
407-
.node
407+
.offers_handler
408408
.pay_for_offer_from_human_readable_name(name, amt, payment_id, retry, None, resolvers)
409409
.unwrap();
410410

lightning/src/ln/channelmanager.rs

Lines changed: 18 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9502,6 +9502,16 @@ where
95029502
self.pending_offers_messages.lock().expect("Mutex is locked by other thread.")
95039503
}
95049504

9505+
#[cfg(feature = "dnssec")]
9506+
fn get_pending_dns_onion_messages(&self) -> MutexGuard<'_, Vec<(DNSResolverMessage, MessageSendInstructions)>> {
9507+
self.pending_dns_onion_messages.lock().expect("Mutex is locked by other thread.")
9508+
}
9509+
9510+
#[cfg(feature = "dnssec")]
9511+
fn get_hrn_resolver(&self) -> &OMNameResolver {
9512+
&self.hrn_resolver
9513+
}
9514+
95059515
fn sign_bolt12_invoice(
95069516
&self, invoice: &UnsignedBolt12Invoice,
95079517
) -> Result<schnorr::Signature, ()> {
@@ -9571,6 +9581,14 @@ where
95719581
Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64)
95729582
}
95739583

9584+
#[cfg(feature = "dnssec")]
9585+
fn add_new_awaiting_offer(
9586+
&self, payment_id: PaymentId, expiration: StaleExpiration, retry_strategy: Retry,
9587+
max_total_routing_fee_msat: Option<u64>, amount_msats: u64,
9588+
) -> Result<(), ()> {
9589+
self.pending_outbound_payments.add_new_awaiting_offer(payment_id, expiration, retry_strategy, max_total_routing_fee_msat, amount_msats)
9590+
}
9591+
95749592
fn pay_for_offer_intern<CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>>(
95759593
&self, offer: &Offer, quantity: Option<u64>, amount_msats: Option<u64>,
95769594
payer_note: Option<String>, payment_id: PaymentId,
@@ -9682,73 +9700,6 @@ where
96829700
Ok(())
96839701
}
96849702

9685-
/// Pays for an [`Offer`] looked up using [BIP 353] Human Readable Names resolved by the DNS
9686-
/// resolver(s) at `dns_resolvers` which resolve names according to bLIP 32.
9687-
///
9688-
/// If the wallet supports paying on-chain schemes, you should instead use
9689-
/// [`OMNameResolver::resolve_name`] and [`OMNameResolver::handle_dnssec_proof_for_uri`] (by
9690-
/// implementing [`DNSResolverMessageHandler`]) directly to look up a URI and then delegate to
9691-
/// your normal URI handling.
9692-
///
9693-
/// If `max_total_routing_fee_msat` is not specified, the default from
9694-
/// [`RouteParameters::from_payment_params_and_value`] is applied.
9695-
///
9696-
/// # Payment
9697-
///
9698-
/// The provided `payment_id` is used to ensure that only one invoice is paid for the request
9699-
/// when received. See [Avoiding Duplicate Payments] for other requirements once the payment has
9700-
/// been sent.
9701-
///
9702-
/// To revoke the request, use [`ChannelManager::abandon_payment`] prior to receiving the
9703-
/// invoice. If abandoned, or an invoice isn't received in a reasonable amount of time, the
9704-
/// payment will fail with an [`Event::InvoiceRequestFailed`].
9705-
///
9706-
/// # Privacy
9707-
///
9708-
/// For payer privacy, uses a derived payer id and uses [`MessageRouter::create_blinded_paths`]
9709-
/// to construct a [`BlindedPath`] for the reply path. For further privacy implications, see the
9710-
/// docs of the parameterized [`Router`], which implements [`MessageRouter`].
9711-
///
9712-
/// # Limitations
9713-
///
9714-
/// Requires a direct connection to the given [`Destination`] as well as an introduction node in
9715-
/// [`Offer::paths`] or to [`Offer::signing_pubkey`], if empty. A similar restriction applies to
9716-
/// the responding [`Bolt12Invoice::payment_paths`].
9717-
///
9718-
/// # Errors
9719-
///
9720-
/// Errors if:
9721-
/// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
9722-
///
9723-
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
9724-
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
9725-
#[cfg(feature = "dnssec")]
9726-
pub fn pay_for_offer_from_human_readable_name(
9727-
&self, name: HumanReadableName, amount_msats: u64, payment_id: PaymentId,
9728-
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>,
9729-
dns_resolvers: Vec<Destination>,
9730-
) -> Result<(), ()> {
9731-
let (onion_message, context) =
9732-
self.hrn_resolver.resolve_name(payment_id, name, &*self.entropy_source)?;
9733-
let reply_paths = self.create_blinded_paths(MessageContext::DNSResolver(context))?;
9734-
let expiration = StaleExpiration::TimerTicks(1);
9735-
self.pending_outbound_payments.add_new_awaiting_offer(payment_id, expiration, retry_strategy, max_total_routing_fee_msat, amount_msats)?;
9736-
let message_params = dns_resolvers
9737-
.iter()
9738-
.flat_map(|destination| reply_paths.iter().map(move |path| (path, destination)))
9739-
.take(OFFERS_MESSAGE_REQUEST_LIMIT);
9740-
for (reply_path, destination) in message_params {
9741-
self.pending_dns_onion_messages.lock().unwrap().push((
9742-
DNSResolverMessage::DNSSECQuery(onion_message.clone()),
9743-
MessageSendInstructions::WithSpecifiedReplyPath {
9744-
destination: destination.clone(),
9745-
reply_path: reply_path.clone(),
9746-
},
9747-
));
9748-
}
9749-
Ok(())
9750-
}
9751-
97529703
/// Gets a payment secret and payment hash for use in an invoice given to a third party wishing
97539704
/// to pay us.
97549705
///

lightning/src/offers/flow.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ use {
7171
crate::offers::refund::RefundMaybeWithDerivedMetadataBuilder,
7272
};
7373

74+
#[cfg(feature = "dnssec")]
75+
use crate::onion_message::dns_resolution::{DNSResolverMessage, OMNameResolver};
76+
7477
/// Functions commonly shared in usage between [`ChannelManager`] & `OffersMessageFlow`
7578
///
7679
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
@@ -80,6 +83,16 @@ pub trait OffersMessageCommons {
8083
&self,
8184
) -> MutexGuard<'_, Vec<(OffersMessage, MessageSendInstructions)>>;
8285

86+
#[cfg(feature = "dnssec")]
87+
/// Get pending DNS onion messages
88+
fn get_pending_dns_onion_messages(
89+
&self,
90+
) -> MutexGuard<'_, Vec<(DNSResolverMessage, MessageSendInstructions)>>;
91+
92+
#[cfg(feature = "dnssec")]
93+
/// Get hrn resolver
94+
fn get_hrn_resolver(&self) -> &OMNameResolver;
95+
8396
/// Signs the [`TaggedHash`] of a BOLT 12 invoice.
8497
///
8598
/// May be called by a function passed to [`UnsignedBolt12Invoice::sign`] where `invoice` is the
@@ -202,6 +215,13 @@ pub trait OffersMessageCommons {
202215
/// Get the approximate current time using the highest seen timestamp
203216
fn get_highest_seen_timestamp(&self) -> Duration;
204217

218+
#[cfg(feature = "dnssec")]
219+
/// Add new awaiting offer
220+
fn add_new_awaiting_offer(
221+
&self, payment_id: PaymentId, expiration: StaleExpiration, retry_strategy: Retry,
222+
max_total_routing_fee_msat: Option<u64>, amount_msats: u64,
223+
) -> Result<(), ()>;
224+
205225
/// Internal pay_for_offer
206226
fn pay_for_offer_intern<
207227
CPP: FnOnce(&InvoiceRequest, Nonce) -> Result<(), Bolt12SemanticError>,
@@ -1383,4 +1403,81 @@ where
13831403
Err(()) => Err(Bolt12SemanticError::InvalidAmount),
13841404
}
13851405
}
1406+
1407+
/// Pays for an [`Offer`] looked up using [BIP 353] Human Readable Names resolved by the DNS
1408+
/// resolver(s) at `dns_resolvers` which resolve names according to bLIP 32.
1409+
///
1410+
/// If the wallet supports paying on-chain schemes, you should instead use
1411+
/// [`OMNameResolver::resolve_name`] and [`OMNameResolver::handle_dnssec_proof_for_uri`] (by
1412+
/// implementing [`DNSResolverMessageHandler`]) directly to look up a URI and then delegate to
1413+
/// your normal URI handling.
1414+
///
1415+
/// If `max_total_routing_fee_msat` is not specified, the default from
1416+
/// [`RouteParameters::from_payment_params_and_value`] is applied.
1417+
///
1418+
/// # Payment
1419+
///
1420+
/// The provided `payment_id` is used to ensure that only one invoice is paid for the request
1421+
/// when received. See [Avoiding Duplicate Payments] for other requirements once the payment has
1422+
/// been sent.
1423+
///
1424+
/// To revoke the request, use [`ChannelManager::abandon_payment`] prior to receiving the
1425+
/// invoice. If abandoned, or an invoice isn't received in a reasonable amount of time, the
1426+
/// payment will fail with an [`Event::InvoiceRequestFailed`].
1427+
///
1428+
/// # Privacy
1429+
///
1430+
/// For payer privacy, uses a derived payer id and uses [`MessageRouter::create_blinded_paths`]
1431+
/// to construct a [`BlindedPath`] for the reply path. For further privacy implications, see the
1432+
/// docs of the parameterized [`Router`], which implements [`MessageRouter`].
1433+
///
1434+
/// # Limitations
1435+
///
1436+
/// Requires a direct connection to the given [`Destination`] as well as an introduction node in
1437+
/// [`Offer::paths`] or to [`Offer::signing_pubkey`], if empty. A similar restriction applies to
1438+
/// the responding [`Bolt12Invoice::payment_paths`].
1439+
///
1440+
/// # Errors
1441+
///
1442+
/// Errors if:
1443+
/// - a duplicate `payment_id` is provided given the caveats in the aforementioned link,
1444+
///
1445+
/// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths
1446+
/// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments
1447+
#[cfg(feature = "dnssec")]
1448+
pub fn pay_for_offer_from_human_readable_name(
1449+
&self, name: HumanReadableName, amount_msats: u64, payment_id: PaymentId,
1450+
retry_strategy: Retry, max_total_routing_fee_msat: Option<u64>,
1451+
dns_resolvers: Vec<Destination>,
1452+
) -> Result<(), ()> {
1453+
let (onion_message, context) = self.commons.get_hrn_resolver().resolve_name(
1454+
payment_id,
1455+
name,
1456+
&*self.entropy_source,
1457+
)?;
1458+
let reply_paths =
1459+
self.commons.create_blinded_paths(MessageContext::DNSResolver(context))?;
1460+
let expiration = StaleExpiration::TimerTicks(1);
1461+
self.commons.add_new_awaiting_offer(
1462+
payment_id,
1463+
expiration,
1464+
retry_strategy,
1465+
max_total_routing_fee_msat,
1466+
amount_msats,
1467+
)?;
1468+
let message_params = dns_resolvers
1469+
.iter()
1470+
.flat_map(|destination| reply_paths.iter().map(move |path| (path, destination)))
1471+
.take(OFFERS_MESSAGE_REQUEST_LIMIT);
1472+
for (reply_path, destination) in message_params {
1473+
self.commons.get_pending_dns_onion_messages().push((
1474+
DNSResolverMessage::DNSSECQuery(onion_message.clone()),
1475+
MessageSendInstructions::WithSpecifiedReplyPath {
1476+
destination: destination.clone(),
1477+
reply_path: reply_path.clone(),
1478+
},
1479+
));
1480+
}
1481+
Ok(())
1482+
}
13861483
}

0 commit comments

Comments
 (0)