Skip to content

Commit 7b44fe0

Browse files
committed
Move DNSResolverMessageHandler impl to OffersMessageFlow
1 parent 0d0732c commit 7b44fe0

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
@@ -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},
@@ -2426,14 +2423,6 @@ where
24262423
#[cfg(feature = "dnssec")]
24272424
pending_dns_onion_messages: Mutex<Vec<(DNSResolverMessage, MessageSendInstructions)>>,
24282425

2429-
#[cfg(feature = "_test_utils")]
2430-
/// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
2431-
/// offer generated in the test.
2432-
///
2433-
/// This allows for doing so, validating proofs as normal, but, if they pass, replacing the
2434-
/// offer they resolve to to the given one.
2435-
pub testing_dnssec_proof_offer_resolution_override: Mutex<HashMap<HumanReadableName, Offer>>,
2436-
24372426
#[cfg(test)]
24382427
pub(super) entropy_source: ES,
24392428
#[cfg(not(test))]
@@ -3364,9 +3353,6 @@ where
33643353
hrn_resolver: OMNameResolver::new(current_timestamp, params.best_block.height),
33653354
#[cfg(feature = "dnssec")]
33663355
pending_dns_onion_messages: Mutex::new(Vec::new()),
3367-
3368-
#[cfg(feature = "_test_utils")]
3369-
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
33703356
}
33713357
}
33723358

@@ -9871,6 +9857,18 @@ where
98719857

98729858
self.enqueue_invoice_request(invoice_request, reply_paths)
98739859
}
9860+
9861+
#[cfg(feature = "dnssec")]
9862+
fn amt_msats_for_payment_awaiting_offer(&self, payment_id: PaymentId) -> Result<u64, ()> {
9863+
self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id)
9864+
}
9865+
9866+
#[cfg(feature = "dnssec")]
9867+
fn received_offer(
9868+
&self, payment_id: PaymentId, retryable_invoice_request: Option<RetryableInvoiceRequest>,
9869+
) -> Result<(), ()> {
9870+
self.pending_outbound_payments.received_offer(payment_id, retryable_invoice_request)
9871+
}
98749872
}
98759873

98769874
/// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
@@ -11430,69 +11428,6 @@ where
1143011428
}
1143111429
}
1143211430

11433-
#[cfg(feature = "dnssec")]
11434-
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref>
11435-
DNSResolverMessageHandler for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
11436-
where
11437-
M::Target: chain::Watch<<SP::Target as SignerProvider>::EcdsaSigner>,
11438-
T::Target: BroadcasterInterface,
11439-
ES::Target: EntropySource,
11440-
NS::Target: NodeSigner,
11441-
SP::Target: SignerProvider,
11442-
F::Target: FeeEstimator,
11443-
R::Target: Router,
11444-
MR::Target: MessageRouter,
11445-
L::Target: Logger,
11446-
{
11447-
fn handle_dnssec_query(
11448-
&self, _message: DNSSECQuery, _responder: Option<Responder>,
11449-
) -> Option<(DNSResolverMessage, ResponseInstruction)> {
11450-
None
11451-
}
11452-
11453-
fn handle_dnssec_proof(&self, message: DNSSECProof, context: DNSResolverContext) {
11454-
let offer_opt = self.hrn_resolver.handle_dnssec_proof_for_offer(message, context);
11455-
#[cfg_attr(not(feature = "_test_utils"), allow(unused_mut))]
11456-
if let Some((completed_requests, mut offer)) = offer_opt {
11457-
for (name, payment_id) in completed_requests {
11458-
#[cfg(feature = "_test_utils")]
11459-
if let Some(replacement_offer) = self.testing_dnssec_proof_offer_resolution_override.lock().unwrap().remove(&name) {
11460-
// If we have multiple pending requests we may end up over-using the override
11461-
// offer, but tests can deal with that.
11462-
offer = replacement_offer;
11463-
}
11464-
if let Ok(amt_msats) = self.pending_outbound_payments.amt_msats_for_payment_awaiting_offer(payment_id) {
11465-
let offer_pay_res =
11466-
self.pay_for_offer_intern(&offer, None, Some(amt_msats), None, payment_id, Some(name),
11467-
|invoice_request, nonce| {
11468-
let retryable_invoice_request = RetryableInvoiceRequest {
11469-
invoice_request: invoice_request.clone(),
11470-
nonce,
11471-
};
11472-
self.pending_outbound_payments
11473-
.received_offer(payment_id, Some(retryable_invoice_request))
11474-
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
11475-
});
11476-
if offer_pay_res.is_err() {
11477-
// The offer we tried to pay is the canonical current offer for the name we
11478-
// wanted to pay. If we can't pay it, there's no way to recover so fail the
11479-
// payment.
11480-
// Note that the PaymentFailureReason should be ignored for an
11481-
// AwaitingInvoice payment.
11482-
self.pending_outbound_payments.abandon_payment(
11483-
payment_id, PaymentFailureReason::RouteNotFound, &self.pending_events,
11484-
);
11485-
}
11486-
}
11487-
}
11488-
}
11489-
}
11490-
11491-
fn release_pending_messages(&self) -> Vec<(DNSResolverMessage, MessageSendInstructions)> {
11492-
core::mem::take(&mut self.pending_dns_onion_messages.lock().unwrap())
11493-
}
11494-
}
11495-
1149611431
impl<M: Deref, T: Deref, ES: Deref, NS: Deref, SP: Deref, F: Deref, R: Deref, MR: Deref, L: Deref>
1149711432
NodeIdLookUp for ChannelManager<M, T, ES, NS, SP, F, R, MR, L>
1149811433
where
@@ -13372,9 +13307,6 @@ where
1337213307
hrn_resolver: OMNameResolver::new(highest_seen_timestamp, best_block_height),
1337313308
#[cfg(feature = "dnssec")]
1337413309
pending_dns_onion_messages: Mutex::new(Vec::new()),
13375-
13376-
#[cfg(feature = "_test_utils")]
13377-
testing_dnssec_proof_offer_resolution_override: Mutex::new(new_hash_map()),
1337813310
};
1337913311

1338013312
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

@@ -3350,7 +3350,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
33503350
#[cfg(feature = "dnssec")]
33513351
let onion_messenger = OnionMessenger::new(
33523352
dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &chan_mgrs[i],
3353-
&cfgs[i].message_router, offers_handler.clone(), &chan_mgrs[i], &chan_mgrs[i],
3353+
&cfgs[i].message_router, offers_handler.clone(), &chan_mgrs[i], offers_handler.clone(),
33543354
IgnoringMessageHandler {},
33553355
);
33563356
#[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)