Skip to content

Commit cba7288

Browse files
committed
Move DNSResolverMessageHandler impl to OffersMessageFlow
1 parent d2161d9 commit cba7288

File tree

4 files changed

+114
-86
lines changed

4 files changed

+114
-86
lines changed

lightning-dns-resolver/src/lib.rs

+1-1
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

+14-82
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use crate::offers::signer;
7676
use crate::offers::static_invoice::StaticInvoice;
7777
use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
7878
use crate::onion_message::dns_resolution::HumanReadableName;
79-
use crate::onion_message::messenger::{Destination, MessageRouter, Responder, ResponseInstruction, MessageSendInstructions};
79+
use crate::onion_message::messenger::{DefaultMessageRouter, Destination, MessageRouter, MessageSendInstructions, Responder, ResponseInstruction};
8080
use crate::onion_message::offers::OffersMessage;
8181
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
8282
use crate::sign::ecdsa::EcdsaChannelSigner;
@@ -90,13 +90,10 @@ use crate::util::logger::{Level, Logger, WithContext};
9090
use crate::util::errors::APIError;
9191

9292
#[cfg(feature = "dnssec")]
93-
use crate::blinded_path::message::DNSResolverContext;
94-
#[cfg(feature = "dnssec")]
95-
use crate::onion_message::dns_resolution::{DNSResolverMessage, DNSResolverMessageHandler, DNSSECQuery, DNSSECProof, OMNameResolver};
93+
use crate::onion_message::dns_resolution::{DNSResolverMessage, OMNameResolver};
9694

9795
#[cfg(not(c_bindings))]
9896
use {
99-
crate::onion_message::messenger::DefaultMessageRouter,
10097
crate::routing::router::DefaultRouter,
10198
crate::routing::gossip::NetworkGraph,
10299
crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters},
@@ -2412,14 +2409,6 @@ where
24122409
#[cfg(feature = "dnssec")]
24132410
pending_dns_onion_messages: Mutex<Vec<(DNSResolverMessage, MessageSendInstructions)>>,
24142411

2415-
#[cfg(feature = "_test_utils")]
2416-
/// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
2417-
/// offer generated in the test.
2418-
///
2419-
/// This allows for doing so, validating proofs as normal, but, if they pass, replacing the
2420-
/// offer they resolve to to the given one.
2421-
pub testing_dnssec_proof_offer_resolution_override: Mutex<HashMap<HumanReadableName, Offer>>,
2422-
24232412
#[cfg(test)]
24242413
pub(super) entropy_source: ES,
24252414
#[cfg(not(test))]
@@ -3351,9 +3340,6 @@ where
33513340
hrn_resolver: OMNameResolver::new(current_timestamp, params.best_block.height),
33523341
#[cfg(feature = "dnssec")]
33533342
pending_dns_onion_messages: Mutex::new(Vec::new()),
3354-
3355-
#[cfg(feature = "_test_utils")]
3356-
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
33573343
}
33583344
}
33593345

@@ -9820,6 +9806,18 @@ where
98209806

98219807
self.enqueue_invoice_request(invoice_request, reply_paths)
98229808
}
9809+
9810+
#[cfg(feature = "dnssec")]
9811+
fn amt_msats_for_payment_awaiting_offer(&self, payment_id: PaymentId) -> Result<u64, ()> {
9812+
self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id)
9813+
}
9814+
9815+
#[cfg(feature = "dnssec")]
9816+
fn received_offer(
9817+
&self, payment_id: PaymentId, retryable_invoice_request: Option<RetryableInvoiceRequest>,
9818+
) -> Result<(), ()> {
9819+
self.pending_outbound_payments.received_offer(payment_id, retryable_invoice_request)
9820+
}
98239821
}
98249822

98259823
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -11375,69 +11373,6 @@ where
1137511373
}
1137611374
}
1137711375

11378-
#[cfg(feature = "dnssec")]
11379-
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref>
11380-
DNSResolverMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
11381-
where
11382-
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
11383-
T::Target: BroadcasterInterface,
11384-
ES::Target: EntropySource,
11385-
NS::Target: NodeSigner,
11386-
SP::Target: SignerProvider,
11387-
F::Target: FeeEstimator,
11388-
R::Target: Router,
11389-
MR::Target: MessageRouter,
11390-
L::Target: Logger,
11391-
{
11392-
fn handle_dnssec_query(
11393-
&self, _message: DNSSECQuery, _responder: Option<Responder>,
11394-
) -> Option<(DNSResolverMessage, ResponseInstruction)> {
11395-
None
11396-
}
11397-
11398-
fn handle_dnssec_proof(&self, message: DNSSECProof, context: DNSResolverContext) {
11399-
let offer_opt = self.hrn_resolver.handle_dnssec_proof_for_offer(message, context);
11400-
#[cfg_attr(not(feature = "_test_utils"), allow(unused_mut))]
11401-
if let Some((completed_requests, mut offer)) = offer_opt {
11402-
for (name, payment_id) in completed_requests {
11403-
#[cfg(feature = "_test_utils")]
11404-
if let Some(replacement_offer) = self.testing_dnssec_proof_offer_resolution_override.lock().unwrap().remove(&name) {
11405-
// If we have multiple pending requests we may end up over-using the override
11406-
// offer, but tests can deal with that.
11407-
offer = replacement_offer;
11408-
}
11409-
if let Ok(amt_msats) = self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id) {
11410-
let offer_pay_res =
11411-
self.pay_for_offer_intern(&offer, None, Some(amt_msats), None, payment_id, Some(name),
11412-
|invoice_request, nonce| {
11413-
let retryable_invoice_request = RetryableInvoiceRequest {
11414-
invoice_request: invoice_request.clone(),
11415-
nonce,
11416-
};
11417-
self.pending_outbound_payments
11418-
.received_offer(payment_id, Some(retryable_invoice_request))
11419-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
11420-
});
11421-
if offer_pay_res.is_err() {
11422-
// The offer we tried to pay is the canonical current offer for the name we
11423-
// wanted to pay. If we can't pay it, there's no way to recover so fail the
11424-
// payment.
11425-
// Note that the PaymentFailureReason should be ignored for an
11426-
// AwaitingInvoice payment.
11427-
self.pending_outbound_payments.abandon_payment(
11428-
payment_id, PaymentFailureReason::RouteNotFound, &self.pending_events,
11429-
);
11430-
}
11431-
}
11432-
}
11433-
}
11434-
}
11435-
11436-
fn release_pending_messages(&self) -> Vec<(DNSResolverMessage, MessageSendInstructions)> {
11437-
core::mem::take(&mut self.pending_dns_onion_messages.lock().unwrap())
11438-
}
11439-
}
11440-
1144111376
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref>
1144211377
NodeIdLookUp for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
1144311378
where
@@ -13318,9 +13253,6 @@ where
1331813253
hrn_resolver: OMNameResolver::new(highest_seen_timestamp, best_block_height),
1331913254
#[cfg(feature = "dnssec")]
1332013255
pending_dns_onion_messages: Mutex::new(Vec::new()),
13321-
13322-
#[cfg(feature = "_test_utils")]
13323-
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
1332413256
};
1332513257

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

lightning/src/ln/functional_test_utils.rs

+2-2
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

@@ -3345,7 +3345,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
33453345
#[cfg(feature = "dnssec")]
33463346
let onion_messenger = OnionMessenger::new(
33473347
dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &chan_mgrs[i],
3348-
&cfgs[i].message_router, offers_handler.clone(), &chan_mgrs[i], &chan_mgrs[i],
3348+
&cfgs[i].message_router, offers_handler.clone(), &chan_mgrs[i], offers_handler.clone(),
33493349
IgnoringMessageHandler {},
33503350
);
33513351
#[cfg(not(feature = "dnssec"))]

lightning/src/offers/flow.rs

+97-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use crate::offers::offer::{Offer, OfferBuilder};
4848
use crate::offers::refund::{Refund, RefundBuilder};
4949

5050
use crate::sign::EntropySource;
51+
use crate::sync::Mutex;
5152
use crate::util::logger::{Logger, WithContext};
5253

5354
#[cfg(async_payments)]
@@ -63,7 +64,12 @@ use {
6364
};
6465

6566
#[cfg(feature = "dnssec")]
66-
use crate::onion_message::dns_resolution::{DNSResolverMessage, HumanReadableName, OMNameResolver};
67+
use {
68+
crate::blinded_path::message::DNSResolverContext,
69+
crate::onion_message::dns_resolution::{
70+
DNSResolverMessage, DNSResolverMessageHandler, DNSSECProof, DNSSECQuery, OMNameResolver,
71+
},
72+
};
6773

6874
/// Functions commonly shared in usage between [`ChannelManager`] & `OffersMessageFlow`
6975
///
@@ -221,6 +227,16 @@ pub trait OffersMessageCommons {
221227
payer_note: Option<String>, payment_id: PaymentId,
222228
human_readable_name: Option<HumanReadableName>, create_pending_payment: CPP,
223229
) -> Result<(), Bolt12SemanticError>;
230+
231+
#[cfg(feature = "dnssec")]
232+
/// Amount for payment awaiting offer
233+
fn amt_msats_for_payment_awaiting_offer(&self, payment_id: PaymentId) -> Result<u64, ()>;
234+
235+
#[cfg(feature = "dnssec")]
236+
/// Received Offer
237+
fn received_offer(
238+
&self, payment_id: PaymentId, retryable_invoice_request: Option<RetryableInvoiceRequest>,
239+
) -> Result<(), ()>;
224240
}
225241

226242
/// A trivial trait which describes any [`OffersMessageFlow`].
@@ -569,6 +585,14 @@ where
569585
/// Contains functions shared between OffersMessageHandler and ChannelManager.
570586
commons: OMC,
571587

588+
#[cfg(feature = "_test_utils")]
589+
/// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
590+
/// offer generated in the test.
591+
///
592+
/// This allows for doing so, validating proofs as normal, but, if they pass, replacing the
593+
/// offer they resolve to to the given one.
594+
pub testing_dnssec_proof_offer_resolution_override: Mutex<HashMap<HumanReadableName, Offer>>,
595+
572596
/// The Logger for use in the OffersMessageFlow and which may be used to log
573597
/// information during deserialization.
574598
pub logger: L,
@@ -594,6 +618,8 @@ where
594618
secp_ctx,
595619
commons,
596620
entropy_source,
621+
#[cfg(feature = "_test_utils")]
622+
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
597623
logger,
598624
}
599625
}
@@ -1332,3 +1358,73 @@ where
13321358
Ok(())
13331359
}
13341360
}
1361+
1362+
#[cfg(feature = "dnssec")]
1363+
impl<ES: Deref, OMC: Deref, L: Deref> DNSResolverMessageHandler for OffersMessageFlow<ES, OMC, L>
1364+
where
1365+
ES::Target: EntropySource,
1366+
OMC::Target: OffersMessageCommons,
1367+
L::Target: Logger,
1368+
{
1369+
fn handle_dnssec_query(
1370+
&self, _message: DNSSECQuery, _responder: Option<Responder>,
1371+
) -> Option<(DNSResolverMessage, ResponseInstruction)> {
1372+
None
1373+
}
1374+
1375+
fn handle_dnssec_proof(&self, message: DNSSECProof, context: DNSResolverContext) {
1376+
let offer_opt =
1377+
self.commons.get_hrn_resolver().handle_dnssec_proof_for_offer(message, context);
1378+
#[cfg_attr(not(feature = "_test_utils"), allow(unused_mut))]
1379+
if let Some((completed_requests, mut offer)) = offer_opt {
1380+
for (name, payment_id) in completed_requests {
1381+
#[cfg(feature = "_test_utils")]
1382+
if let Some(replacement_offer) = self
1383+
.testing_dnssec_proof_offer_resolution_override
1384+
.lock()
1385+
.unwrap()
1386+
.remove(&name)
1387+
{
1388+
// If we have multiple pending requests we may end up over-using the override
1389+
// offer, but tests can deal with that.
1390+
offer = replacement_offer;
1391+
}
1392+
if let Ok(amt_msats) = self.commons.amt_msats_for_payment_awaiting_offer(payment_id)
1393+
{
1394+
let offer_pay_res = self.commons.pay_for_offer_intern(
1395+
&offer,
1396+
None,
1397+
Some(amt_msats),
1398+
None,
1399+
payment_id,
1400+
Some(name),
1401+
|invoice_request, nonce| {
1402+
let retryable_invoice_request = RetryableInvoiceRequest {
1403+
invoice_request: invoice_request.clone(),
1404+
nonce,
1405+
};
1406+
self.commons
1407+
.received_offer(payment_id, Some(retryable_invoice_request))
1408+
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
1409+
},
1410+
);
1411+
if offer_pay_res.is_err() {
1412+
// The offer we tried to pay is the canonical current offer for the name we
1413+
// wanted to pay. If we can't pay it, there's no way to recover so fail the
1414+
// payment.
1415+
// Note that the PaymentFailureReason should be ignored for an
1416+
// AwaitingInvoice payment.
1417+
self.commons.abandon_payment_with_reason(
1418+
payment_id,
1419+
PaymentFailureReason::RouteNotFound,
1420+
);
1421+
}
1422+
}
1423+
}
1424+
}
1425+
}
1426+
1427+
fn release_pending_messages(&self) -> Vec<(DNSResolverMessage, MessageSendInstructions)> {
1428+
core::mem::take(&mut self.commons.get_pending_dns_onion_messages())
1429+
}
1430+
}

0 commit comments

Comments
 (0)