Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lightning/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::ln::types::ChannelId;
use crate::offers::invoice::Bolt12Invoice;
use crate::offers::invoice_request::InvoiceRequest;
use crate::offers::static_invoice::StaticInvoice;
use crate::onion_message::dns_resolution::DNSSECProof;
use crate::onion_message::messenger::Responder;
use crate::routing::gossip::NetworkUpdate;
use crate::routing::router::{BlindedTail, Path, RouteHop, RouteParameters};
Expand Down Expand Up @@ -1101,6 +1102,12 @@ pub enum Event {
///
/// [`StaticInvoice`]: crate::offers::static_invoice::StaticInvoice
bolt12_invoice: Option<PaidBolt12Invoice>,
/// The DNSSEC proof for BIP 353 proof of payment, if this payment originated from
/// a Human Readable Name resolution. This proof, combined with the [`Bolt12Invoice`],
/// provides a complete chain of proof from the DNS name to the payment.
///
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
dnssec_proof: Option<DNSSECProof>,
},
/// Indicates an outbound payment failed. Individual [`Event::PaymentPathFailed`] events
/// provide failure information for each path attempt in the payment, including retries.
Expand Down Expand Up @@ -1973,6 +1980,7 @@ impl Writeable for Event {
ref amount_msat,
ref fee_paid_msat,
ref bolt12_invoice,
ref dnssec_proof,
} => {
2u8.write(writer)?;
write_tlv_fields!(writer, {
Expand All @@ -1982,6 +1990,7 @@ impl Writeable for Event {
(5, fee_paid_msat, option),
(7, amount_msat, option),
(9, bolt12_invoice, option),
(11, dnssec_proof, option),
});
},
&Event::PaymentPathFailed {
Expand Down Expand Up @@ -2474,13 +2483,15 @@ impl MaybeReadable for Event {
let mut amount_msat = None;
let mut fee_paid_msat = None;
let mut bolt12_invoice = None;
let mut dnssec_proof: Option<DNSSECProof> = None;
read_tlv_fields!(reader, {
(0, payment_preimage, required),
(1, payment_hash, option),
(3, payment_id, option),
(5, fee_paid_msat, option),
(7, amount_msat, option),
(9, bolt12_invoice, option),
(11, dnssec_proof, option),
});
if payment_hash.is_none() {
payment_hash = Some(PaymentHash(
Expand All @@ -2494,6 +2505,7 @@ impl MaybeReadable for Event {
amount_msat,
fee_paid_msat,
bolt12_invoice,
dnssec_proof,
}))
};
f()
Expand Down
2 changes: 2 additions & 0 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16535,6 +16535,7 @@ mod tests {
first_hop_htlc_msat: 548,
payment_id: PaymentId([42; 32]),
bolt12_invoice: None,
dnssec_proof: None,
},
skimmed_fee_msat: None,
blinding_point: None,
Expand Down Expand Up @@ -16986,6 +16987,7 @@ mod tests {
first_hop_htlc_msat: 0,
payment_id: PaymentId([42; 32]),
bolt12_invoice: None,
dnssec_proof: None,
};
let dummy_outbound_output = OutboundHTLCOutput {
htlc_id: 0,
Expand Down
41 changes: 36 additions & 5 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ use crate::onion_message::async_payments::{
AsyncPaymentsMessage, AsyncPaymentsMessageHandler, HeldHtlcAvailable, OfferPaths,
OfferPathsRequest, ReleaseHeldHtlc, ServeStaticInvoice, StaticInvoicePersisted,
};
use crate::onion_message::dns_resolution::HumanReadableName;
use crate::onion_message::dns_resolution::{DNSSECProof, HumanReadableName};
use crate::onion_message::messenger::{
MessageRouter, MessageSendInstructions, Responder, ResponseInstruction,
};
Expand Down Expand Up @@ -836,6 +836,10 @@ mod fuzzy_channelmanager {
/// we can provide proof-of-payment details in payment claim events even after a restart
/// with a stale ChannelManager state.
bolt12_invoice: Option<PaidBolt12Invoice>,
/// The DNSSEC proof for BIP 353 proof of payment, if this payment originated from
/// a Human Readable Name resolution. Stored here to ensure we can provide it in
/// payment claim events even after a restart with a stale ChannelManager state.
dnssec_proof: Option<DNSSECProof>,
},
}

Expand Down Expand Up @@ -909,13 +913,15 @@ impl core::hash::Hash for HTLCSource {
payment_id,
first_hop_htlc_msat,
bolt12_invoice,
dnssec_proof,
} => {
1u8.hash(hasher);
path.hash(hasher);
session_priv[..].hash(hasher);
payment_id.hash(hasher);
first_hop_htlc_msat.hash(hasher);
bolt12_invoice.hash(hasher);
dnssec_proof.hash(hasher);
},
HTLCSource::TrampolineForward {
previous_hop_data,
Expand Down Expand Up @@ -943,6 +949,7 @@ impl HTLCSource {
first_hop_htlc_msat: 0,
payment_id: PaymentId([2; 32]),
bolt12_invoice: None,
dnssec_proof: None,
}
}

Expand Down Expand Up @@ -5394,6 +5401,7 @@ impl<
keysend_preimage,
invoice_request: None,
bolt12_invoice: None,
dnssec_proof: None,
session_priv_bytes,
hold_htlc_at_next_hop: false,
})
Expand All @@ -5409,6 +5417,7 @@ impl<
keysend_preimage,
invoice_request,
bolt12_invoice,
dnssec_proof,
session_priv_bytes,
hold_htlc_at_next_hop,
} = args;
Expand Down Expand Up @@ -5485,6 +5494,7 @@ impl<
first_hop_htlc_msat: htlc_msat,
payment_id,
bolt12_invoice: bolt12_invoice.cloned(),
dnssec_proof: dnssec_proof.cloned(),
};
let send_res = chan.send_htlc_and_commit(
htlc_msat,
Expand Down Expand Up @@ -9614,7 +9624,8 @@ impl<
ComplFunc: FnOnce(
Option<u64>,
bool,
) -> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
)
-> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
>(
&self, prev_hop: HTLCPreviousHopData, payment_preimage: PaymentPreimage,
payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
Expand Down Expand Up @@ -9652,7 +9663,8 @@ impl<
ComplFunc: FnOnce(
Option<u64>,
bool,
) -> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
)
-> (Option<MonitorUpdateCompletionAction>, Option<RAAMonitorUpdateBlockingAction>),
>(
&self, prev_hop: HTLCClaimSource, payment_preimage: PaymentPreimage,
payment_info: Option<PaymentClaimDetails>, attribution_data: Option<AttributionData>,
Expand Down Expand Up @@ -9952,7 +9964,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
let htlc_id = SentHTLCId::from_source(&source);
match source {
HTLCSource::OutboundRoute {
session_priv, payment_id, path, bolt12_invoice, ..
session_priv,
payment_id,
path,
bolt12_invoice,
dnssec_proof,
..
} => {
debug_assert!(!startup_replay,
"We don't support claim_htlc claims during startup - monitors may not be available yet");
Expand Down Expand Up @@ -9984,6 +10001,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
payment_id,
payment_preimage,
bolt12_invoice,
dnssec_proof,
session_priv,
path,
from_onchain,
Expand Down Expand Up @@ -17386,6 +17404,7 @@ impl<

#[rustfmt::skip]
fn handle_dnssec_proof(&self, message: DNSSECProof, context: DNSResolverContext) {
let proof = message.clone();
let offer_opt = self.flow.hrn_resolver.handle_dnssec_proof_for_offer(message, context);
#[cfg_attr(not(feature = "_test_utils"), allow(unused_mut))]
if let Some((completed_requests, mut offer)) = offer_opt {
Expand All @@ -17404,7 +17423,12 @@ impl<
.received_offer(payment_id, Some(retryable_invoice_request))
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)
});
if offer_pay_res.is_err() {
if offer_pay_res.is_ok() {
// Store the DNSSEC proof for BIP 353 proof of payment. The proof is
// now attached to the AwaitingInvoice state and will be carried through
// to the PaymentSent event.
self.pending_outbound_payments.set_dnssec_proof(payment_id, proof.clone());
} else {
// The offer we tried to pay is the canonical current offer for the name we
// wanted to pay. If we can't pay it, there's no way to recover so fail the
// payment.
Expand Down Expand Up @@ -17767,6 +17791,7 @@ impl Readable for HTLCSource {
let mut payment_params: Option<PaymentParameters> = None;
let mut blinded_tail: Option<BlindedTail> = None;
let mut bolt12_invoice: Option<PaidBolt12Invoice> = None;
let mut dnssec_proof: Option<DNSSECProof> = None;
read_tlv_fields!(reader, {
(0, session_priv, required),
(1, payment_id, option),
Expand All @@ -17775,6 +17800,7 @@ impl Readable for HTLCSource {
(5, payment_params, (option: ReadableArgs, 0)),
(6, blinded_tail, option),
(7, bolt12_invoice, option),
(9, dnssec_proof, option),
});
if payment_id.is_none() {
// For backwards compat, if there was no payment_id written, use the session_priv bytes
Expand All @@ -17798,6 +17824,7 @@ impl Readable for HTLCSource {
path,
payment_id: payment_id.unwrap(),
bolt12_invoice,
dnssec_proof,
})
}
1 => Ok(HTLCSource::PreviousHopData(Readable::read(reader)?)),
Expand All @@ -17817,6 +17844,7 @@ impl Writeable for HTLCSource {
ref path,
payment_id,
bolt12_invoice,
dnssec_proof,
} => {
0u8.write(writer)?;
let payment_id_opt = Some(payment_id);
Expand All @@ -17829,6 +17857,7 @@ impl Writeable for HTLCSource {
(5, None::<PaymentParameters>, option), // payment_params in LDK versions prior to 0.0.115
(6, path.blinded_tail, option),
(7, bolt12_invoice, option),
(9, dnssec_proof, option),
});
},
HTLCSource::PreviousHopData(ref field) => {
Expand Down Expand Up @@ -19687,6 +19716,7 @@ impl<
session_priv,
path,
bolt12_invoice,
dnssec_proof,
..
} => {
if let Some(preimage) = preimage_opt {
Expand All @@ -19704,6 +19734,7 @@ impl<
payment_id,
preimage,
bolt12_invoice,
dnssec_proof,
session_priv,
path,
true,
Expand Down
1 change: 1 addition & 0 deletions lightning/src/ln/functional_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3025,6 +3025,7 @@ pub fn expect_payment_sent<CM: AChannelManager, H: NodeHolder<CM = CM>>(
ref amount_msat,
ref fee_paid_msat,
ref bolt12_invoice,
..
} => {
assert_eq!(expected_payment_preimage, *payment_preimage);
assert_eq!(expected_payment_hash, *payment_hash);
Expand Down
4 changes: 4 additions & 0 deletions lightning/src/ln/onion_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3547,6 +3547,7 @@ mod tests {
first_hop_htlc_msat: 0,
payment_id: PaymentId([1; 32]),
bolt12_invoice: None,
dnssec_proof: None,
};

process_onion_failure(&ctx_full, &logger, &htlc_source, onion_error)
Expand Down Expand Up @@ -3733,6 +3734,7 @@ mod tests {
first_hop_htlc_msat: dummy_amt_msat,
payment_id: PaymentId([1; 32]),
bolt12_invoice: None,
dnssec_proof: None,
};

{
Expand Down Expand Up @@ -3921,6 +3923,7 @@ mod tests {
first_hop_htlc_msat: 0,
payment_id: PaymentId([1; 32]),
bolt12_invoice: None,
dnssec_proof: None,
};

// Iterate over all possible failure positions and check that the cases that can be attributed are.
Expand Down Expand Up @@ -4030,6 +4033,7 @@ mod tests {
first_hop_htlc_msat: 0,
payment_id: PaymentId([1; 32]),
bolt12_invoice: None,
dnssec_proof: None,
};

let decrypted_failure = process_onion_failure(&ctx_full, &logger, &htlc_source, packet);
Expand Down
Loading
Loading