From cff6e344f558fe97570b50cbaa359fd6f504c586 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Thu, 13 Jun 2024 16:16:47 -0400 Subject: [PATCH] Support checking that a static invoice matches an outbound invreq. Useful for ensuring that an inbound static invoice matches one of our outbound invreqs, otherwise it is an unexpected invoice and should be ignored and not paid. --- lightning/src/offers/invoice_request.rs | 5 +++++ lightning/src/offers/merkle.rs | 1 + lightning/src/offers/static_invoice.rs | 15 +++++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index 32d05249c..dc2fd4bf1 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -840,6 +840,11 @@ impl InvoiceRequest { invoice_request_accessors!(self, self.contents); invoice_request_respond_with_explicit_signing_pubkey_methods!(self, self, InvoiceBuilder); invoice_request_verify_method!(self, Self); + + #[cfg(async_payments)] + pub(super) fn bytes(&self) -> &Vec { + &self.bytes + } } #[cfg(c_bindings)] diff --git a/lightning/src/offers/merkle.rs b/lightning/src/offers/merkle.rs index 90bfc859e..e2fed2e80 100644 --- a/lightning/src/offers/merkle.rs +++ b/lightning/src/offers/merkle.rs @@ -249,6 +249,7 @@ impl<'a> TlvStream<'a> { } /// A slice into a [`TlvStream`] for a record. +#[derive(Eq, PartialEq)] pub(super) struct TlvRecord<'a> { pub(super) r#type: u64, type_bytes: &'a [u8], diff --git a/lightning/src/offers/static_invoice.rs b/lightning/src/offers/static_invoice.rs index 33706f928..4910c57c5 100644 --- a/lightning/src/offers/static_invoice.rs +++ b/lightning/src/offers/static_invoice.rs @@ -20,12 +20,13 @@ use crate::offers::invoice::{ InvoiceTlvStream, InvoiceTlvStreamRef, }; use crate::offers::invoice_macros::{invoice_accessors_common, invoice_builder_methods_common}; +use crate::offers::invoice_request::InvoiceRequest; use crate::offers::merkle::{ - self, SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, + self, SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream, }; use crate::offers::nonce::Nonce; use crate::offers::offer::{ - Amount, Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef, Quantity, + Amount, Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef, Quantity, OFFER_TYPES, }; use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage}; use crate::util::ser::{CursorReadable, Iterable, WithoutLength, Writeable, Writer}; @@ -312,6 +313,16 @@ impl StaticInvoice { pub fn signature(&self) -> Signature { self.signature } + + pub(crate) fn from_same_offer(&self, invreq: &InvoiceRequest) -> bool { + let invoice_offer_tlv_stream = TlvStream::new(&self.bytes) + .range(OFFER_TYPES) + .map(|tlv_record| tlv_record.record_bytes); + let invreq_offer_tlv_stream = TlvStream::new(invreq.bytes()) + .range(OFFER_TYPES) + .map(|tlv_record| tlv_record.record_bytes); + invoice_offer_tlv_stream.eq(invreq_offer_tlv_stream) + } } impl InvoiceContents { -- 2.39.5