Skip to content

Commit 97af1df

Browse files
committed
Move DNSResolverMessageHandler impl to OffersMessageFlow
1 parent b718728 commit 97af1df

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},
@@ -2392,14 +2389,6 @@ where
23922389
#[cfg(feature = "dnssec")]
23932390
pending_dns_onion_messages: Mutex<Vec<(DNSResolverMessage, MessageSendInstructions)>>,
23942391

2395-
#[cfg(feature = "_test_utils")]
2396-
/// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
2397-
/// offer generated in the test.
2398-
///
2399-
/// This allows for doing so, validating proofs as normal, but, if they pass, replacing the
2400-
/// offer they resolve to to the given one.
2401-
pub testing_dnssec_proof_offer_resolution_override: Mutex<HashMap<HumanReadableName, Offer>>,
2402-
24032392
#[cfg(test)]
24042393
pub(super) entropy_source: ES,
24052394
#[cfg(not(test))]
@@ -3273,9 +3262,6 @@ where
32733262
hrn_resolver: OMNameResolver::new(current_timestamp, params.best_block.height),
32743263
#[cfg(feature = "dnssec")]
32753264
pending_dns_onion_messages: Mutex::new(Vec::new()),
3276-
3277-
#[cfg(feature = "_test_utils")]
3278-
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
32793265
}
32803266
}
32813267

@@ -9742,6 +9728,18 @@ where
97429728

97439729
self.enqueue_invoice_request(invoice_request, reply_paths)
97449730
}
9731+
9732+
#[cfg(feature = "dnssec")]
9733+
fn amt_msats_for_payment_awaiting_offer(&self, payment_id: PaymentId) -> Result<u64, ()> {
9734+
self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id)
9735+
}
9736+
9737+
#[cfg(feature = "dnssec")]
9738+
fn received_offer(
9739+
&self, payment_id: PaymentId, retryable_invoice_request: Option<RetryableInvoiceRequest>,
9740+
) -> Result<(), ()> {
9741+
self.pending_outbound_payments.received_offer(payment_id, retryable_invoice_request)
9742+
}
97459743
}
97469744

97479745
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -11293,69 +11291,6 @@ where
1129311291
}
1129411292
}
1129511293

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

1321613148
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::{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)