impl OffersMessageHandler for TestOffersMessageHandler {
fn handle_message(
- &self, _message: OffersMessage, _context: OffersContext, _responder: Option<Responder>,
+ &self, _message: OffersMessage, _context: Option<OffersContext>,
+ _responder: Option<Responder>,
) -> ResponseInstruction<OffersMessage> {
ResponseInstruction::NoResponse
}
/// [`OffersMessage`]: crate::onion_message::offers::OffersMessage
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum OffersContext {
- /// Represents an unknown BOLT12 message context.
- ///
- /// This variant is used when a message is sent without using a [`BlindedPath`] or over one
- /// created prior to LDK version 0.0.124.
- Unknown {},
/// Context used by a [`BlindedPath`] within an [`Offer`].
///
/// This variant is intended to be received when handling an [`InvoiceRequest`].
);
impl_writeable_tlv_based_enum!(OffersContext,
- (0, Unknown) => {},
- (1, InvoiceRequest) => {
+ (0, InvoiceRequest) => {
(0, nonce, required),
},
- (2, OutboundPayment) => {
+ (1, OutboundPayment) => {
(0, payment_id, required),
(1, nonce, required),
},
- (3, InboundPayment) => {
+ (2, InboundPayment) => {
(0, payment_hash, required),
},
);
/// The context of the [`BlindedPath`] used to send the invoice.
///
/// [`BlindedPath`]: crate::blinded_path::BlindedPath
- context: OffersContext,
+ context: Option<OffersContext>,
/// A responder for replying with an [`InvoiceError`] if needed.
///
/// `None` if the invoice wasn't sent with a reply path.
write_tlv_fields!(writer, {
(0, payment_id, required),
(2, invoice, required),
- (4, context, required),
+ (4, context, option),
(6, responder, option),
});
},
_init_and_read_len_prefixed_tlv_fields!(reader, {
(0, payment_id, required),
(2, invoice, required),
- (4, context, required),
+ (4, context, option),
(6, responder, option),
});
Ok(Some(Event::InvoiceReceived {
payment_id: payment_id.0.unwrap(),
invoice: invoice.0.unwrap(),
- context: context.0.unwrap(),
+ context,
responder,
}))
};
///
/// [timer tick]: Self::timer_tick_occurred
pub fn send_payment_for_bolt12_invoice(
- &self, invoice: &Bolt12Invoice, context: &OffersContext,
+ &self, invoice: &Bolt12Invoice, context: Option<&OffersContext>,
) -> Result<(), Bolt12PaymentError> {
match self.verify_bolt12_invoice(invoice, context) {
Ok(payment_id) => self.send_payment_for_verified_bolt12_invoice(invoice, payment_id),
}
fn verify_bolt12_invoice(
- &self, invoice: &Bolt12Invoice, context: &OffersContext,
+ &self, invoice: &Bolt12Invoice, context: Option<&OffersContext>,
) -> Result<PaymentId, ()> {
let secp_ctx = &self.secp_ctx;
let expanded_key = &self.inbound_payment_key;
match context {
- OffersContext::Unknown {} if invoice.is_for_refund_without_paths() => {
+ None if invoice.is_for_refund_without_paths() => {
invoice.verify_using_metadata(expanded_key, secp_ctx)
},
- OffersContext::OutboundPayment { payment_id, nonce } => {
- invoice.verify_using_payer_data(*payment_id, *nonce, expanded_key, secp_ctx)
+ Some(&OffersContext::OutboundPayment { payment_id, nonce }) => {
+ invoice.verify_using_payer_data(payment_id, nonce, expanded_key, secp_ctx)
},
_ => Err(()),
}
R::Target: Router,
L::Target: Logger,
{
- fn handle_message(&self, message: OffersMessage, context: OffersContext, responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
+ fn handle_message(
+ &self, message: OffersMessage, context: Option<OffersContext>, responder: Option<Responder>,
+ ) -> ResponseInstruction<OffersMessage> {
let secp_ctx = &self.secp_ctx;
let expanded_key = &self.inbound_payment_key;
let abandon_if_payment = |context| {
match context {
- OffersContext::OutboundPayment { payment_id, .. } => self.abandon_payment(payment_id),
+ Some(OffersContext::OutboundPayment { payment_id, .. }) => {
+ self.abandon_payment(payment_id)
+ },
_ => {},
}
};
};
let nonce = match context {
- OffersContext::Unknown {} if invoice_request.metadata().is_some() => None,
- OffersContext::InvoiceRequest { nonce } => Some(nonce),
+ None if invoice_request.metadata().is_some() => None,
+ Some(OffersContext::InvoiceRequest { nonce }) => Some(nonce),
_ => return ResponseInstruction::NoResponse,
};
}
},
OffersMessage::Invoice(invoice) => {
- let payment_id = match self.verify_bolt12_invoice(&invoice, &context) {
+ let payment_id = match self.verify_bolt12_invoice(&invoice, context.as_ref()) {
Ok(payment_id) => payment_id,
Err(()) => return ResponseInstruction::NoResponse,
};
},
OffersMessage::InvoiceError(invoice_error) => {
let payment_hash = match context {
- OffersContext::InboundPayment { payment_hash } => Some(payment_hash),
+ Some(OffersContext::InboundPayment { payment_hash }) => Some(payment_hash),
_ => None,
};
let logger = WithContext::from(&self.logger, None, None, payment_hash);
assert_eq!(path.introduction_node, IntroductionNode::NodeId(alice_id));
}
- assert!(bob.node.send_payment_for_bolt12_invoice(&invoice, &context).is_ok());
+ assert!(bob.node.send_payment_for_bolt12_invoice(&invoice, context.as_ref()).is_ok());
assert_eq!(
- bob.node.send_payment_for_bolt12_invoice(&invoice, &context),
+ bob.node.send_payment_for_bolt12_invoice(&invoice, context.as_ref()),
Err(Bolt12PaymentError::DuplicateInvoice),
);
expect_recent_payment!(bob, RecentPaymentDetails::Fulfilled, payment_id);
assert_eq!(
- bob.node.send_payment_for_bolt12_invoice(&invoice, &context),
+ bob.node.send_payment_for_bolt12_invoice(&invoice, context.as_ref()),
Err(Bolt12PaymentError::DuplicateInvoice),
);
}
assert_eq!(
- bob.node.send_payment_for_bolt12_invoice(&invoice, &context),
+ bob.node.send_payment_for_bolt12_invoice(&invoice, context.as_ref()),
Err(Bolt12PaymentError::UnexpectedInvoice),
);
}
}
impl OffersMessageHandler for IgnoringMessageHandler {
- fn handle_message(&self, _message: OffersMessage, _context: OffersContext, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
+ fn handle_message(&self, _message: OffersMessage, _context: Option<OffersContext>, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
ResponseInstruction::NoResponse
}
}
struct TestOffersMessageHandler {}
impl OffersMessageHandler for TestOffersMessageHandler {
- fn handle_message(&self, _message: OffersMessage, _context: OffersContext, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
+ fn handle_message(&self, _message: OffersMessage, _context: Option<OffersContext>, _responder: Option<Responder>) -> ResponseInstruction<OffersMessage> {
ResponseInstruction::NoResponse
}
}
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1, SecretKey};
use crate::blinded_path::{BlindedPath, IntroductionNode, NextMessageHop, NodeIdLookUp};
-use crate::blinded_path::message::{advance_path_by_one, ForwardNode, ForwardTlvs, MessageContext, OffersContext, ReceiveTlvs};
+use crate::blinded_path::message::{advance_path_by_one, ForwardNode, ForwardTlvs, MessageContext, ReceiveTlvs};
use crate::blinded_path::utils;
use crate::events::{Event, EventHandler, EventsProvider, ReplayEvent};
use crate::sign::{EntropySource, NodeSigner, Recipient};
match message {
ParsedOnionMessageContents::Offers(msg) => {
let context = match context {
- None => OffersContext::Unknown {},
- Some(MessageContext::Offers(context)) => context,
+ None => None,
+ Some(MessageContext::Offers(context)) => Some(context),
Some(MessageContext::Custom(_)) => {
debug_assert!(false, "Shouldn't have triggered this case.");
return
/// The returned [`OffersMessage`], if any, is enqueued to be sent by [`OnionMessenger`].
///
/// [`OnionMessenger`]: crate::onion_message::messenger::OnionMessenger
- fn handle_message(&self, message: OffersMessage, context: OffersContext, responder: Option<Responder>) -> ResponseInstruction<OffersMessage>;
+ fn handle_message(
+ &self, message: OffersMessage, context: Option<OffersContext>, responder: Option<Responder>,
+ ) -> ResponseInstruction<OffersMessage>;
/// Releases any [`OffersMessage`]s that need to be sent.
///