Skip to content

Commit 20dc922

Browse files
committed
Move DNSResolverMessageHandler impl to OffersMessageFlow
1 parent 92320d4 commit 20dc922

File tree

4 files changed

+114
-86
lines changed

4 files changed

+114
-86
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: 14 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ use crate::offers::signer;
7474
use crate::offers::static_invoice::StaticInvoice;
7575
use crate::onion_message::async_payments::{AsyncPaymentsMessage, HeldHtlcAvailable, ReleaseHeldHtlc, AsyncPaymentsMessageHandler};
7676
use crate::onion_message::dns_resolution::HumanReadableName;
77-
use crate::onion_message::messenger::{Destination, MessageRouter, Responder, ResponseInstruction, MessageSendInstructions};
77+
use crate::onion_message::messenger::{DefaultMessageRouter, Destination, MessageRouter, MessageSendInstructions, Responder, ResponseInstruction};
7878
use crate::onion_message::offers::OffersMessage;
7979
use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
8080
use crate::sign::ecdsa::EcdsaChannelSigner;
@@ -88,13 +88,10 @@ use crate::util::logger::{Level, Logger, WithContext};
8888
use crate::util::errors::APIError;
8989

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

9593
#[cfg(not(c_bindings))]
9694
use {
97-
crate::onion_message::messenger::DefaultMessageRouter,
9895
crate::routing::router::DefaultRouter,
9996
crate::routing::gossip::NetworkGraph,
10097
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

@@ -9747,6 +9733,18 @@ where
97479733

97489734
self.enqueue_invoice_request(invoice_request, reply_paths)
97499735
}
9736+
9737+
#[cfg(feature = "dnssec")]
9738+
fn amt_msats_for_payment_awaiting_offer(&self, payment_id: PaymentId) -> Result<u64, ()> {
9739+
self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id)
9740+
}
9741+
9742+
#[cfg(feature = "dnssec")]
9743+
fn received_offer(
9744+
&self, payment_id: PaymentId, retryable_invoice_request: Option<RetryableInvoiceRequest>,
9745+
) -> Result<(), ()> {
9746+
self.pending_outbound_payments.received_offer(payment_id, retryable_invoice_request)
9747+
}
97509748
}
97519749

97529750
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -11298,69 +11296,6 @@ where
1129811296
}
1129911297
}
1130011298

11301-
#[cfg(feature = "dnssec")]
11302-
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref>
11303-
DNSResolverMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
11304-
where
11305-
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
11306-
T::Target: BroadcasterInterface,
11307-
ES::Target: EntropySource,
11308-
NS::Target: NodeSigner,
11309-
SP::Target: SignerProvider,
11310-
F::Target: FeeEstimator,
11311-
R::Target: Router,
11312-
MR::Target: MessageRouter,
11313-
L::Target: Logger,
11314-
{
11315-
fn handle_dnssec_query(
11316-
&self, _message: DNSSECQuery, _responder: Option<Responder>,
11317-
) -> Option<(DNSResolverMessage, ResponseInstruction)> {
11318-
None
11319-
}
11320-
11321-
fn handle_dnssec_proof(&self, message: DNSSECProof, context: DNSResolverContext) {
11322-
let offer_opt = self.hrn_resolver.handle_dnssec_proof_for_offer(message, context);
11323-
#[cfg_attr(not(feature = "_test_utils"), allow(unused_mut))]
11324-
if let Some((completed_requests, mut offer)) = offer_opt {
11325-
for (name, payment_id) in completed_requests {
11326-
#[cfg(feature = "_test_utils")]
11327-
if let Some(replacement_offer) = self.testing_dnssec_proof_offer_resolution_override.lock().unwrap().remove(&name) {
11328-
// If we have multiple pending requests we may end up over-using the override
11329-
// offer, but tests can deal with that.
11330-
offer = replacement_offer;
11331-
}
11332-
if let Ok(amt_msats) = self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id) {
11333-
let offer_pay_res =
11334-
self.pay_for_offer_intern(&offer, None, Some(amt_msats), None, payment_id, Some(name),
11335-
|invoice_request, nonce| {
11336-
let retryable_invoice_request = RetryableInvoiceRequest {
11337-
invoice_request: invoice_request.clone(),
11338-
nonce,
11339-
};
11340-
self.pending_outbound_payments
11341-
.received_offer(payment_id, Some(retryable_invoice_request))
11342-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
11343-
});
11344-
if offer_pay_res.is_err() {
11345-
// The offer we tried to pay is the canonical current offer for the name we
11346-
// wanted to pay. If we can't pay it, there's no way to recover so fail the
11347-
// payment.
11348-
// Note that the PaymentFailureReason should be ignored for an
11349-
// AwaitingInvoice payment.
11350-
self.pending_outbound_payments.abandon_payment(
11351-
payment_id, PaymentFailureReason::RouteNotFound, &self.pending_events,
11352-
);
11353-
}
11354-
}
11355-
}
11356-
}
11357-
}
11358-
11359-
fn release_pending_messages(&self) -> Vec<(DNSResolverMessage, MessageSendInstructions)> {
11360-
core::mem::take(&mut self.pending_dns_onion_messages.lock().unwrap())
11361-
}
11362-
}
11363-
1136411299
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref>
1136511300
NodeIdLookUp for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
1136611301
where
@@ -13213,9 +13148,6 @@ where
1321313148
hrn_resolver: OMNameResolver::new(highest_seen_timestamp, best_block_height),
1321413149
#[cfg(feature = "dnssec")]
1321513150
pending_dns_onion_messages: Mutex::new(Vec::new()),
13216-
13217-
#[cfg(feature = "_test_utils")]
13218-
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
1321913151
};
1322013152

1322113153
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: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use crate::offers::offer::{DerivedMetadata, 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(c_bindings)]
@@ -57,7 +58,12 @@ use {
5758
};
5859

5960
#[cfg(feature = "dnssec")]
60-
use crate::onion_message::dns_resolution::{DNSResolverMessage, HumanReadableName, OMNameResolver};
61+
use {
62+
crate::blinded_path::message::DNSResolverContext,
63+
crate::onion_message::dns_resolution::{
64+
DNSResolverMessage, DNSResolverMessageHandler, DNSSECProof, DNSSECQuery, OMNameResolver,
65+
},
66+
};
6167

6268
/// Functions commonly shared in usage between [`ChannelManager`] & `OffersMessageFlow`
6369
///
@@ -209,6 +215,16 @@ pub trait OffersMessageCommons {
209215
payer_note: Option<String>, payment_id: PaymentId,
210216
human_readable_name: Option<HumanReadableName>, create_pending_payment: CPP,
211217
) -> Result<(), Bolt12SemanticError>;
218+
219+
#[cfg(feature = "dnssec")]
220+
/// Amount for payment awaiting offer
221+
fn amt_msats_for_payment_awaiting_offer(&self, payment_id: PaymentId) -> Result<u64, ()>;
222+
223+
#[cfg(feature = "dnssec")]
224+
/// Received Offer
225+
fn received_offer(
226+
&self, payment_id: PaymentId, retryable_invoice_request: Option<RetryableInvoiceRequest>,
227+
) -> Result<(), ()>;
212228
}
213229

214230
/// A trivial trait which describes any [`OffersMessageFlow`].
@@ -557,6 +573,14 @@ where
557573
/// Contains functions shared between OffersMessageHandler and ChannelManager.
558574
commons: OMC,
559575

576+
#[cfg(feature = "_test_utils")]
577+
/// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
578+
/// offer generated in the test.
579+
///
580+
/// This allows for doing so, validating proofs as normal, but, if they pass, replacing the
581+
/// offer they resolve to to the given one.
582+
pub testing_dnssec_proof_offer_resolution_override: Mutex<HashMap<HumanReadableName, Offer>>,
583+
560584
/// The Logger for use in the OffersMessageFlow and which may be used to log
561585
/// information during deserialization.
562586
pub logger: L,
@@ -582,6 +606,8 @@ where
582606
secp_ctx,
583607
commons,
584608
entropy_source,
609+
#[cfg(feature = "_test_utils")]
610+
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
585611
logger,
586612
}
587613
}
@@ -1323,3 +1349,73 @@ where
13231349
Ok(())
13241350
}
13251351
}
1352+
1353+
#[cfg(feature = "dnssec")]
1354+
impl<ES: Deref, OMC: Deref, L: Deref> DNSResolverMessageHandler for OffersMessageFlow<ES, OMC, L>
1355+
where
1356+
ES::Target: EntropySource,
1357+
OMC::Target: OffersMessageCommons,
1358+
L::Target: Logger,
1359+
{
1360+
fn handle_dnssec_query(
1361+
&self, _message: DNSSECQuery, _responder: Option<Responder>,
1362+
) -> Option<(DNSResolverMessage, ResponseInstruction)> {
1363+
None
1364+
}
1365+
1366+
fn handle_dnssec_proof(&self, message: DNSSECProof, context: DNSResolverContext) {
1367+
let offer_opt =
1368+
self.commons.get_hrn_resolver().handle_dnssec_proof_for_offer(message, context);
1369+
#[cfg_attr(not(feature = "_test_utils"), allow(unused_mut))]
1370+
if let Some((completed_requests, mut offer)) = offer_opt {
1371+
for (name, payment_id) in completed_requests {
1372+
#[cfg(feature = "_test_utils")]
1373+
if let Some(replacement_offer) = self
1374+
.testing_dnssec_proof_offer_resolution_override
1375+
.lock()
1376+
.unwrap()
1377+
.remove(&name)
1378+
{
1379+
// If we have multiple pending requests we may end up over-using the override
1380+
// offer, but tests can deal with that.
1381+
offer = replacement_offer;
1382+
}
1383+
if let Ok(amt_msats) = self.commons.amt_msats_for_payment_awaiting_offer(payment_id)
1384+
{
1385+
let offer_pay_res = self.commons.pay_for_offer_intern(
1386+
&offer,
1387+
None,
1388+
Some(amt_msats),
1389+
None,
1390+
payment_id,
1391+
Some(name),
1392+
|invoice_request, nonce| {
1393+
let retryable_invoice_request = RetryableInvoiceRequest {
1394+
invoice_request: invoice_request.clone(),
1395+
nonce,
1396+
};
1397+
self.commons
1398+
.received_offer(payment_id, Some(retryable_invoice_request))
1399+
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
1400+
},
1401+
);
1402+
if offer_pay_res.is_err() {
1403+
// The offer we tried to pay is the canonical current offer for the name we
1404+
// wanted to pay. If we can't pay it, there's no way to recover so fail the
1405+
// payment.
1406+
// Note that the PaymentFailureReason should be ignored for an
1407+
// AwaitingInvoice payment.
1408+
self.commons.abandon_payment_with_reason(
1409+
payment_id,
1410+
PaymentFailureReason::RouteNotFound,
1411+
);
1412+
}
1413+
}
1414+
}
1415+
}
1416+
}
1417+
1418+
fn release_pending_messages(&self) -> Vec<(DNSResolverMessage, MessageSendInstructions)> {
1419+
core::mem::take(&mut self.commons.get_pending_dns_onion_messages())
1420+
}
1421+
}

0 commit comments

Comments
 (0)