PaymentPurpose::SpontaneousPayment(..) => true,
}
}
+
+ pub(crate) fn from_parts(
+ payment_preimage: Option<PaymentPreimage>, payment_secret: PaymentSecret,
+ payment_context: Option<PaymentContext>,
+ ) -> Self {
+ match payment_context {
+ Some(PaymentContext::Unknown(_)) | None => {
+ PaymentPurpose::Bolt11InvoicePayment {
+ payment_preimage,
+ payment_secret,
+ }
+ },
+ Some(PaymentContext::Bolt12Offer(context)) => {
+ PaymentPurpose::Bolt12OfferPayment {
+ payment_preimage,
+ payment_secret,
+ payment_context: context,
+ }
+ },
+ Some(PaymentContext::Bolt12Refund(context)) => {
+ PaymentPurpose::Bolt12RefundPayment {
+ payment_preimage,
+ payment_secret,
+ payment_context: context,
+ }
+ },
+ }
+ }
}
impl_writeable_tlv_based_enum!(PaymentPurpose,
(11, payment_context, option),
});
let purpose = match payment_secret {
- Some(secret) => match payment_context {
- Some(PaymentContext::Unknown(_)) | None => {
- PaymentPurpose::Bolt11InvoicePayment {
- payment_preimage,
- payment_secret: secret,
- }
- },
- Some(PaymentContext::Bolt12Offer(context)) => {
- PaymentPurpose::Bolt12OfferPayment {
- payment_preimage,
- payment_secret: secret,
- payment_context: context,
- }
- },
- Some(PaymentContext::Bolt12Refund(context)) => {
- PaymentPurpose::Bolt12RefundPayment {
- payment_preimage,
- payment_secret: secret,
- payment_context: context,
- }
- },
- },
+ Some(secret) => PaymentPurpose::from_parts(payment_preimage, secret, payment_context),
None if payment_preimage.is_some() => PaymentPurpose::SpontaneousPayment(payment_preimage.unwrap()),
None => return Err(msgs::DecodeError::InvalidValue),
};
/// // On the event processing thread
/// channel_manager.process_pending_events(&|event| match event {
/// Event::PaymentClaimable { payment_hash, purpose, .. } => match purpose {
-/// PaymentPurpose::Bolt11InvoicePayment { payment_preimage: Some(payment_preimage), .. } => {
+/// PaymentPurpose::Bolt12OfferPayment { payment_preimage: Some(payment_preimage), .. } => {
/// println!("Claiming payment {}", payment_hash);
/// channel_manager.claim_funds(payment_preimage);
/// },
-/// PaymentPurpose::Bolt11InvoicePayment { payment_preimage: None, .. } => {
+/// PaymentPurpose::Bolt12OfferPayment { payment_preimage: None, .. } => {
/// println!("Unknown payment hash: {}", payment_hash);
/// },
/// // ...
/// // On the event processing thread
/// channel_manager.process_pending_events(&|event| match event {
/// Event::PaymentClaimable { payment_hash, purpose, .. } => match purpose {
-/// PaymentPurpose::Bolt11InvoicePayment { payment_preimage: Some(payment_preimage), .. } => {
+/// PaymentPurpose::Bolt12RefundPayment { payment_preimage: Some(payment_preimage), .. } => {
/// assert_eq!(payment_hash, known_payment_hash);
/// println!("Claiming payment {}", payment_hash);
/// channel_manager.claim_funds(payment_preimage);
/// },
-/// PaymentPurpose::Bolt11InvoicePayment { payment_preimage: None, .. } => {
+/// PaymentPurpose::Bolt12RefundPayment { payment_preimage: None, .. } => {
/// println!("Unknown payment hash: {}", payment_hash);
/// },
/// // ...
match payment_secrets.entry(payment_hash) {
hash_map::Entry::Vacant(_) => {
match claimable_htlc.onion_payload {
- OnionPayload::Invoice { .. } => {
+ OnionPayload::Invoice { ref payment_context, .. } => {
let payment_data = payment_data.unwrap();
let (payment_preimage, min_final_cltv_expiry_delta) = match inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) {
Ok(result) => result,
fail_htlc!(claimable_htlc, payment_hash);
}
}
- let purpose = events::PaymentPurpose::Bolt11InvoicePayment {
- payment_preimage: payment_preimage.clone(),
- payment_secret: payment_data.payment_secret,
- };
+ let purpose = events::PaymentPurpose::from_parts(
+ payment_preimage.clone(),
+ payment_data.payment_secret,
+ payment_context.clone(),
+ );
check_total_value!(purpose);
},
OnionPayload::Spontaneous(preimage) => {
}
},
hash_map::Entry::Occupied(inbound_payment) => {
- if let OnionPayload::Spontaneous(_) = claimable_htlc.onion_payload {
- log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", &payment_hash);
- fail_htlc!(claimable_htlc, payment_hash);
- }
+ let payment_context = match claimable_htlc.onion_payload {
+ OnionPayload::Spontaneous(_) => {
+ log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", &payment_hash);
+ fail_htlc!(claimable_htlc, payment_hash);
+ },
+ OnionPayload::Invoice { ref payment_context, .. } => payment_context,
+ };
let payment_data = payment_data.unwrap();
if inbound_payment.get().payment_secret != payment_data.payment_secret {
log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", &payment_hash);
&payment_hash, payment_data.total_msat, inbound_payment.get().min_value_msat.unwrap());
fail_htlc!(claimable_htlc, payment_hash);
} else {
- let purpose = events::PaymentPurpose::Bolt11InvoicePayment {
- payment_preimage: inbound_payment.get().payment_preimage,
- payment_secret: payment_data.payment_secret,
- };
+ let purpose = events::PaymentPurpose::from_parts(
+ inbound_payment.get().payment_preimage,
+ payment_data.payment_secret,
+ payment_context.clone(),
+ );
let payment_claimable_generated = check_total_value!(purpose);
if payment_claimable_generated {
inbound_payment.remove_entry();
use bitcoin::network::constants::Network;
use core::time::Duration;
use crate::blinded_path::{BlindedPath, IntroductionNode};
-use crate::events::{Event, MessageSendEventsProvider, PaymentPurpose};
+use crate::events::{Event, MessageSendEventsProvider};
use crate::ln::channelmanager::{PaymentId, RecentPaymentDetails, Retry, self};
use crate::ln::functional_test_utils::*;
use crate::ln::msgs::{ChannelMessageHandler, Init, NodeAnnouncement, OnionMessage, OnionMessageHandler, RoutingMessageHandler, SocketAddress, UnsignedGossipMessage, UnsignedNodeAnnouncement};
fn claim_bolt12_payment<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, path: &[&Node<'a, 'b, 'c>]) {
let recipient = &path[path.len() - 1];
match get_event!(recipient, Event::PaymentClaimable) {
- Event::PaymentClaimable {
- purpose: PaymentPurpose::Bolt11InvoicePayment {
- payment_preimage: Some(payment_preimage), ..
- }, ..
- } => claim_payment(node, path, payment_preimage),
- _ => panic!(),
+ Event::PaymentClaimable { purpose, .. } => match purpose.preimage() {
+ Some(payment_preimage) => claim_payment(node, path, payment_preimage),
+ None => panic!("No preimage in Event::PaymentClaimable"),
+ },
+ _ => panic!("No Event::PaymentClaimable"),
};
}