Skip to content

Commit 7b23df1

Browse files
committed
Move DNSResolverMessageHandler impl to OffersMessageFlow
1 parent bbe104f commit 7b23df1

File tree

4 files changed

+123
-87
lines changed

4 files changed

+123
-87
lines changed

lightning-dns-resolver/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ mod test {
393393
// When we get the proof back, override its contents to an offer from nodes[1]
394394
let bs_offer = nodes[1].offers_handler.create_offer_builder(None).unwrap().build().unwrap();
395395
nodes[0]
396-
.node
396+
.offers_handler
397397
.testing_dnssec_proof_offer_resolution_override
398398
.lock()
399399
.unwrap()

lightning/src/ln/channelmanager.rs

Lines changed: 26 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ use crate::offers::signer;
7373
use crate::offers::static_invoice::StaticInvoice;
7474
use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
7575
use crate::onion_message::dns_resolution::HumanReadableName;
76-
use crate::onion_message::messenger::{Destination, MessageRouter, Responder, ResponseInstruction, MessageSendInstructions};
76+
use crate::onion_message::messenger::{DefaultMessageRouter, Destination, MessageRouter, MessageSendInstructions, Responder, ResponseInstruction};
7777
use crate::onion_message::offers::OffersMessage;
7878
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
7979
use crate::sign::ecdsa::EcdsaChannelSigner;
@@ -87,13 +87,10 @@ use crate::util::logger::{Level, Logger, WithContext};
8787
use crate::util::errors::APIError;
8888

8989
#[cfg(feature = "dnssec")]
90-
use crate::blinded_path::message::DNSResolverContext;
91-
#[cfg(feature = "dnssec")]
92-
use crate::onion_message::dns_resolution::{DNSResolverMessage, DNSResolverMessageHandler, DNSSECQuery, DNSSECProof, OMNameResolver};
90+
use crate::onion_message::dns_resolution::{DNSResolverMessage, OMNameResolver};
9391

9492
#[cfg(not(c_bindings))]
9593
use {
96-
crate::onion_message::messenger::DefaultMessageRouter,
9794
crate::routing::router::DefaultRouter,
9895
crate::routing::gossip::NetworkGraph,
9996
crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters},
@@ -2397,14 +2394,6 @@ where
23972394
#[cfg(feature = "dnssec")]
23982395
pending_dns_onion_messages: Mutex<Vec<(DNSResolverMessage, MessageSendInstructions)>>,
23992396

2400-
#[cfg(feature = "_test_utils")]
2401-
/// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
2402-
/// offer generated in the test.
2403-
///
2404-
/// This allows for doing so, validating proofs as normal, but, if they pass, replacing the
2405-
/// offer they resolve to to the given one.
2406-
pub testing_dnssec_proof_offer_resolution_override: Mutex<HashMap<HumanReadableName, Offer>>,
2407-
24082397
#[cfg(test)]
24092398
pub(super) entropy_source: ES,
24102399
#[cfg(not(test))]
@@ -3278,9 +3267,6 @@ where
32783267
hrn_resolver: OMNameResolver::new(current_timestamp, params.best_block.height),
32793268
#[cfg(feature = "dnssec")]
32803269
pending_dns_onion_messages: Mutex::new(Vec::new()),
3281-
3282-
#[cfg(feature = "_test_utils")]
3283-
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
32843270
}
32853271
}
32863272

@@ -9514,6 +9500,7 @@ pub trait OffersMessageCommons {
95149500
/// Get pending offers messages
95159501
fn get_pending_offers_messages(&self) -> MutexGuard<'_, Vec<(OffersMessage, MessageSendInstructions)>>;
95169502

9503+
#[cfg(feature = "dnssec")]
95179504
/// Get pending DNS onion messages
95189505
fn get_pending_dns_onion_messages(&self) -> MutexGuard<'_, Vec<(DNSResolverMessage, MessageSendInstructions)>>;
95199506

@@ -9646,6 +9633,16 @@ pub trait OffersMessageCommons {
96469633
payer_note: Option<String>, payment_id: PaymentId,
96479634
human_readable_name: Option<HumanReadableName>, create_pending_payment: CPP,
96489635
) -> Result<(), Bolt12SemanticError>;
9636+
9637+
#[cfg(feature = "dnssec")]
9638+
/// Amount for payment awaiting offer
9639+
fn amt_msats_for_payment_awaiting_offer(&self, payment_id: PaymentId) -> Result<u64, ()>;
9640+
9641+
#[cfg(feature = "dnssec")]
9642+
/// Received Offer
9643+
fn received_offer(
9644+
&self, payment_id: PaymentId, retryable_invoice_request: Option<RetryableInvoiceRequest>,
9645+
) -> Result<(), ()>;
96499646
}
96509647

96519648
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>
@@ -9664,6 +9661,7 @@ where
96649661
self.pending_offers_messages.lock().expect("Mutex is locked by other thread.")
96659662
}
96669663

9664+
#[cfg(feature = "dnssec")]
96679665
fn get_pending_dns_onion_messages(&self) -> MutexGuard<'_, Vec<(DNSResolverMessage, MessageSendInstructions)>> {
96689666
self.pending_dns_onion_messages.lock().expect("Mutex is locked by other thread.")
96699667
}
@@ -9897,6 +9895,18 @@ where
98979895

98989896
self.enqueue_invoice_request(invoice_request, reply_paths)
98999897
}
9898+
9899+
#[cfg(feature = "dnssec")]
9900+
fn amt_msats_for_payment_awaiting_offer(&self, payment_id: PaymentId) -> Result<u64, ()> {
9901+
self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id)
9902+
}
9903+
9904+
#[cfg(feature = "dnssec")]
9905+
fn received_offer(
9906+
&self, payment_id: PaymentId, retryable_invoice_request: Option<RetryableInvoiceRequest>,
9907+
) -> Result<(), ()> {
9908+
self.pending_outbound_payments.received_offer(payment_id, retryable_invoice_request)
9909+
}
99009910
}
99019911

99029912
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -11448,69 +11458,6 @@ where
1144811458
}
1144911459
}
1145011460

11451-
#[cfg(feature = "dnssec")]
11452-
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref>
11453-
DNSResolverMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
11454-
where
11455-
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
11456-
T::Target: BroadcasterInterface,
11457-
ES::Target: EntropySource,
11458-
NS::Target: NodeSigner,
11459-
SP::Target: SignerProvider,
11460-
F::Target: FeeEstimator,
11461-
R::Target: Router,
11462-
MR::Target: MessageRouter,
11463-
L::Target: Logger,
11464-
{
11465-
fn handle_dnssec_query(
11466-
&self, _message: DNSSECQuery, _responder: Option<Responder>,
11467-
) -> Option<(DNSResolverMessage, ResponseInstruction)> {
11468-
None
11469-
}
11470-
11471-
fn handle_dnssec_proof(&self, message: DNSSECProof, context: DNSResolverContext) {
11472-
let offer_opt = self.hrn_resolver.handle_dnssec_proof_for_offer(message, context);
11473-
#[cfg_attr(not(feature = "_test_utils"), allow(unused_mut))]
11474-
if let Some((completed_requests, mut offer)) = offer_opt {
11475-
for (name, payment_id) in completed_requests {
11476-
#[cfg(feature = "_test_utils")]
11477-
if let Some(replacement_offer) = self.testing_dnssec_proof_offer_resolution_override.lock().unwrap().remove(&name) {
11478-
// If we have multiple pending requests we may end up over-using the override
11479-
// offer, but tests can deal with that.
11480-
offer = replacement_offer;
11481-
}
11482-
if let Ok(amt_msats) = self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id) {
11483-
let offer_pay_res =
11484-
self.pay_for_offer_intern(&offer, None, Some(amt_msats), None, payment_id, Some(name),
11485-
|invoice_request, nonce| {
11486-
let retryable_invoice_request = RetryableInvoiceRequest {
11487-
invoice_request: invoice_request.clone(),
11488-
nonce,
11489-
};
11490-
self.pending_outbound_payments
11491-
.received_offer(payment_id, Some(retryable_invoice_request))
11492-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
11493-
});
11494-
if offer_pay_res.is_err() {
11495-
// The offer we tried to pay is the canonical current offer for the name we
11496-
// wanted to pay. If we can't pay it, there's no way to recover so fail the
11497-
// payment.
11498-
// Note that the PaymentFailureReason should be ignored for an
11499-
// AwaitingInvoice payment.
11500-
self.pending_outbound_payments.abandon_payment(
11501-
payment_id, PaymentFailureReason::RouteNotFound, &self.pending_events,
11502-
);
11503-
}
11504-
}
11505-
}
11506-
}
11507-
}
11508-
11509-
fn release_pending_messages(&self) -> Vec<(DNSResolverMessage, MessageSendInstructions)> {
11510-
core::mem::take(&mut self.pending_dns_onion_messages.lock().unwrap())
11511-
}
11512-
}
11513-
1151411461
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref>
1151511462
NodeIdLookUp for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
1151611463
where
@@ -13363,9 +13310,6 @@ where
1336313310
hrn_resolver: OMNameResolver::new(highest_seen_timestamp, best_block_height),
1336413311
#[cfg(feature = "dnssec")]
1336513312
pending_dns_onion_messages: Mutex::new(Vec::new()),
13366-
13367-
#[cfg(feature = "_test_utils")]
13368-
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
1336913313
};
1337013314

1337113315
for (_, monitor) in args.channel_monitors.iter() {

lightning/src/ln/functional_test_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger<
440440
&'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>,
441441
Arc<TestOffersMessageFlow<'chan_man, 'node_cfg, 'chan_mon_cfg>>,
442442
&'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
443-
&'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
443+
Arc<TestOffersMessageFlow<'chan_man, 'node_cfg, 'chan_mon_cfg>>,
444444
IgnoringMessageHandler,
445445
>;
446446

@@ -3362,7 +3362,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
33623362
#[cfg(feature = "dnssec")]
33633363
let onion_messenger = OnionMessenger::new(
33643364
dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &chan_mgrs[i],
3365-
&cfgs[i].message_router, offers_handler.clone(), &chan_mgrs[i], &chan_mgrs[i],
3365+
&cfgs[i].message_router, offers_handler.clone(), &chan_mgrs[i], offers_handler.clone(),
33663366
IgnoringMessageHandler {},
33673367
);
33683368
#[cfg(not(feature = "dnssec"))]

lightning/src/offers/flow.rs

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//! Provides data structures and functions for creating and managing Offers messages,
1111
//! facilitating communication, and handling Bolt12 invoice payments.
1212
13+
use crate::prelude::*;
1314
use alloc::vec::Vec;
1415
use core::ops::Deref;
1516
use core::time::Duration;
@@ -40,6 +41,7 @@ use crate::offers::parse::Bolt12SemanticError;
4041
use crate::offers::refund::{Refund, RefundBuilder};
4142

4243
use crate::sign::EntropySource;
44+
use crate::sync::Mutex;
4345
use crate::util::logger::{Logger, WithContext};
4446

4547
#[cfg(c_bindings)]
@@ -49,7 +51,12 @@ use {
4951
};
5052

5153
#[cfg(feature = "dnssec")]
52-
use crate::onion_message::dns_resolution::{DNSResolverMessage, HumanReadableName};
54+
use {
55+
crate::blinded_path::message::DNSResolverContext,
56+
crate::onion_message::dns_resolution::{
57+
DNSResolverMessage, DNSResolverMessageHandler, DNSSECProof, DNSSECQuery, HumanReadableName,
58+
},
59+
};
5360

5461
/// A trivial trait which describes any [`OffersMessageFlow`].
5562
///
@@ -394,6 +401,14 @@ where
394401
/// Contains functions shared between OffersMessageHandler and ChannelManager.
395402
commons: OMC,
396403

404+
#[cfg(feature = "_test_utils")]
405+
/// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
406+
/// offer generated in the test.
407+
///
408+
/// This allows for doing so, validating proofs as normal, but, if they pass, replacing the
409+
/// offer they resolve to to the given one.
410+
pub testing_dnssec_proof_offer_resolution_override: Mutex<HashMap<HumanReadableName, Offer>>,
411+
397412
/// The Logger for use in the OffersMessageFlow and which may be used to log
398413
/// information during deserialization.
399414
pub logger: L,
@@ -410,7 +425,14 @@ where
410425
let mut secp_ctx = Secp256k1::new();
411426
secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
412427

413-
Self { secp_ctx, commons, entropy_source, logger }
428+
Self {
429+
secp_ctx,
430+
commons,
431+
entropy_source,
432+
#[cfg(feature = "_test_utils")]
433+
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
434+
logger,
435+
}
414436
}
415437
}
416438

@@ -1150,3 +1172,73 @@ where
11501172
Ok(())
11511173
}
11521174
}
1175+
1176+
#[cfg(feature = "dnssec")]
1177+
impl<ES: Deref, OMC: Deref, L: Deref> DNSResolverMessageHandler for OffersMessageFlow<ES, OMC, L>
1178+
where
1179+
ES::Target: EntropySource,
1180+
OMC::Target: OffersMessageCommons,
1181+
L::Target: Logger,
1182+
{
1183+
fn handle_dnssec_query(
1184+
&self, _message: DNSSECQuery, _responder: Option<Responder>,
1185+
) -> Option<(DNSResolverMessage, ResponseInstruction)> {
1186+
None
1187+
}
1188+
1189+
fn handle_dnssec_proof(&self, message: DNSSECProof, context: DNSResolverContext) {
1190+
let offer_opt =
1191+
self.commons.get_hrn_resolver().handle_dnssec_proof_for_offer(message, context);
1192+
#[cfg_attr(not(feature = "_test_utils"), allow(unused_mut))]
1193+
if let Some((completed_requests, mut offer)) = offer_opt {
1194+
for (name, payment_id) in completed_requests {
1195+
#[cfg(feature = "_test_utils")]
1196+
if let Some(replacement_offer) = self
1197+
.testing_dnssec_proof_offer_resolution_override
1198+
.lock()
1199+
.unwrap()
1200+
.remove(&name)
1201+
{
1202+
// If we have multiple pending requests we may end up over-using the override
1203+
// offer, but tests can deal with that.
1204+
offer = replacement_offer;
1205+
}
1206+
if let Ok(amt_msats) = self.commons.amt_msats_for_payment_awaiting_offer(payment_id)
1207+
{
1208+
let offer_pay_res = self.commons.pay_for_offer_intern(
1209+
&offer,
1210+
None,
1211+
Some(amt_msats),
1212+
None,
1213+
payment_id,
1214+
Some(name),
1215+
|invoice_request, nonce| {
1216+
let retryable_invoice_request = RetryableInvoiceRequest {
1217+
invoice_request: invoice_request.clone(),
1218+
nonce,
1219+
};
1220+
self.commons
1221+
.received_offer(payment_id, Some(retryable_invoice_request))
1222+
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
1223+
},
1224+
);
1225+
if offer_pay_res.is_err() {
1226+
// The offer we tried to pay is the canonical current offer for the name we
1227+
// wanted to pay. If we can't pay it, there's no way to recover so fail the
1228+
// payment.
1229+
// Note that the PaymentFailureReason should be ignored for an
1230+
// AwaitingInvoice payment.
1231+
self.commons.abandon_payment_with_reason(
1232+
payment_id,
1233+
PaymentFailureReason::RouteNotFound,
1234+
);
1235+
}
1236+
}
1237+
}
1238+
}
1239+
}
1240+
1241+
fn release_pending_messages(&self) -> Vec<(DNSResolverMessage, MessageSendInstructions)> {
1242+
core::mem::take(&mut self.commons.get_pending_dns_onion_messages())
1243+
}
1244+
}

0 commit comments

Comments
 (0)