From 1227dfc1ee971ad648fde4e9230659a34da7fc9c Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Fri, 14 Jul 2023 15:02:29 -0500 Subject: [PATCH 01/13] Use rustc stable for check_commits Otherwise, the compiler will panic when using 1.57 for upcoming commits. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9ebfd125721..525dcbe5f06 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -147,7 +147,7 @@ jobs: check_commits: runs-on: ubuntu-latest env: - TOOLCHAIN: 1.57.0 + TOOLCHAIN: stable steps: - name: Checkout source code uses: actions/checkout@v3 From 3e50011e22976bba477350405c1ee81aaa3c4a7e Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Fri, 14 Jul 2023 15:04:30 -0500 Subject: [PATCH 02/13] Fix grammar in docs --- lightning-invoice/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 8ccd9d979ab..454a67f6352 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -1148,7 +1148,7 @@ impl Invoice { self.signed_invoice.hash } - /// Transform the `Invoice` into it's unchecked version + /// Transform the `Invoice` into its unchecked version. pub fn into_signed_raw(self) -> SignedRawInvoice { self.signed_invoice } From f8c9b092fdeab598431a0d05e4ccb914c2ca0a4f Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 13 Jul 2023 13:32:40 -0500 Subject: [PATCH 03/13] Qualify the BOLT 12 invoice type To avoid a naming conflict in bindings with BOLT 11 invoices, qualify the BOLT 12 invoice type. --- fuzz/src/invoice_deser.rs | 4 +- lightning/src/offers/invoice.rs | 117 ++++++++++++------------ lightning/src/offers/invoice_error.rs | 12 +-- lightning/src/offers/invoice_request.rs | 46 +++++----- lightning/src/offers/offer.rs | 19 ++-- lightning/src/offers/refund.rs | 32 +++---- lightning/src/onion_message/offers.rs | 14 +-- lightning/src/routing/router.rs | 6 +- 8 files changed, 125 insertions(+), 125 deletions(-) diff --git a/fuzz/src/invoice_deser.rs b/fuzz/src/invoice_deser.rs index 7b93fd38db1..34bb955e2a7 100644 --- a/fuzz/src/invoice_deser.rs +++ b/fuzz/src/invoice_deser.rs @@ -8,13 +8,13 @@ // licenses. use crate::utils::test_logger; -use lightning::offers::invoice::Invoice; +use lightning::offers::invoice::Bolt12Invoice; use lightning::util::ser::Writeable; use std::convert::TryFrom; #[inline] pub fn do_test(data: &[u8], _out: Out) { - if let Ok(invoice) = Invoice::try_from(data.to_vec()) { + if let Ok(invoice) = Bolt12Invoice::try_from(data.to_vec()) { let mut bytes = Vec::with_capacity(data.len()); invoice.write(&mut bytes).unwrap(); assert_eq!(data, bytes); diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index fb1f78fd644..9a09e58aca1 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -9,9 +9,9 @@ //! Data structures and encoding for `invoice` messages. //! -//! An [`Invoice`] can be built from a parsed [`InvoiceRequest`] for the "offer to be paid" flow or -//! from a [`Refund`] as an "offer for money" flow. The expected recipient of the payment then sends -//! the invoice to the intended payer, who will then pay it. +//! A [`Bolt12Invoice`] can be built from a parsed [`InvoiceRequest`] for the "offer to be paid" +//! flow or from a [`Refund`] as an "offer for money" flow. The expected recipient of the payment +//! then sends the invoice to the intended payer, who will then pay it. //! //! The payment recipient must include a [`PaymentHash`], so as to reveal the preimage upon payment //! receipt, and one or more [`BlindedPath`]s for the payer to use when sending the payment. @@ -128,7 +128,7 @@ const DEFAULT_RELATIVE_EXPIRY: Duration = Duration::from_secs(7200); pub(super) const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "signature"); -/// Builds an [`Invoice`] from either: +/// Builds a [`Bolt12Invoice`] from either: /// - an [`InvoiceRequest`] for the "offer to be paid" flow or /// - a [`Refund`] for the "offer for money" flow. /// @@ -146,17 +146,17 @@ pub struct InvoiceBuilder<'a, S: SigningPubkeyStrategy> { signing_pubkey_strategy: core::marker::PhantomData, } -/// Indicates how [`Invoice::signing_pubkey`] was set. +/// Indicates how [`Bolt12Invoice::signing_pubkey`] was set. /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. pub trait SigningPubkeyStrategy {} -/// [`Invoice::signing_pubkey`] was explicitly set. +/// [`Bolt12Invoice::signing_pubkey`] was explicitly set. /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. pub struct ExplicitSigningPubkey {} -/// [`Invoice::signing_pubkey`] was derived. +/// [`Bolt12Invoice::signing_pubkey`] was derived. /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. pub struct DerivedSigningPubkey {} @@ -271,8 +271,9 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { }) } - /// Sets the [`Invoice::relative_expiry`] as seconds since [`Invoice::created_at`]. Any expiry - /// that has already passed is valid and can be checked for using [`Invoice::is_expired`]. + /// Sets the [`Bolt12Invoice::relative_expiry`] as seconds since [`Bolt12Invoice::created_at`]. + /// Any expiry that has already passed is valid and can be checked for using + /// [`Bolt12Invoice::is_expired`]. /// /// Successive calls to this method will override the previous setting. pub fn relative_expiry(mut self, relative_expiry_secs: u32) -> Self { @@ -281,7 +282,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { self } - /// Adds a P2WSH address to [`Invoice::fallbacks`]. + /// Adds a P2WSH address to [`Bolt12Invoice::fallbacks`]. /// /// Successive calls to this method will add another address. Caller is responsible for not /// adding duplicate addresses and only calling if capable of receiving to P2WSH addresses. @@ -294,7 +295,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { self } - /// Adds a P2WPKH address to [`Invoice::fallbacks`]. + /// Adds a P2WPKH address to [`Bolt12Invoice::fallbacks`]. /// /// Successive calls to this method will add another address. Caller is responsible for not /// adding duplicate addresses and only calling if capable of receiving to P2WPKH addresses. @@ -307,7 +308,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { self } - /// Adds a P2TR address to [`Invoice::fallbacks`]. + /// Adds a P2TR address to [`Bolt12Invoice::fallbacks`]. /// /// Successive calls to this method will add another address. Caller is responsible for not /// adding duplicate addresses and only calling if capable of receiving to P2TR addresses. @@ -320,7 +321,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { self } - /// Sets [`Invoice::features`] to indicate MPP may be used. Otherwise, MPP is disallowed. + /// Sets [`Bolt12Invoice::features`] to indicate MPP may be used. Otherwise, MPP is disallowed. pub fn allow_mpp(mut self) -> Self { self.invoice.fields_mut().features.set_basic_mpp_optional(); self @@ -328,7 +329,7 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { } impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> { - /// Builds an unsigned [`Invoice`] after checking for valid semantics. It can be signed by + /// Builds an unsigned [`Bolt12Invoice`] after checking for valid semantics. It can be signed by /// [`UnsignedInvoice::sign`]. pub fn build(self) -> Result, SemanticError> { #[cfg(feature = "std")] { @@ -343,10 +344,10 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> { } impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> { - /// Builds a signed [`Invoice`] after checking for valid semantics. + /// Builds a signed [`Bolt12Invoice`] after checking for valid semantics. pub fn build_and_sign( self, secp_ctx: &Secp256k1 - ) -> Result { + ) -> Result { #[cfg(feature = "std")] { if self.invoice.is_offer_or_refund_expired() { return Err(SemanticError::AlreadyExpired); @@ -364,7 +365,7 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> { } } -/// A semantically valid [`Invoice`] that hasn't been signed. +/// A semantically valid [`Bolt12Invoice`] that hasn't been signed. pub struct UnsignedInvoice<'a> { invreq_bytes: &'a Vec, invoice: InvoiceContents, @@ -379,7 +380,7 @@ impl<'a> UnsignedInvoice<'a> { /// Signs the invoice using the given function. /// /// This is not exported to bindings users as functions aren't currently mapped. - pub fn sign(self, sign: F) -> Result> + pub fn sign(self, sign: F) -> Result> where F: FnOnce(&Message) -> Result { @@ -402,7 +403,7 @@ impl<'a> UnsignedInvoice<'a> { }; signature_tlv_stream.write(&mut bytes).unwrap(); - Ok(Invoice { + Ok(Bolt12Invoice { bytes, contents: self.invoice, signature, @@ -410,39 +411,37 @@ impl<'a> UnsignedInvoice<'a> { } } -/// An `Invoice` is a payment request, typically corresponding to an [`Offer`] or a [`Refund`]. +/// A `Bolt12Invoice` is a payment request, typically corresponding to an [`Offer`] or a [`Refund`]. /// /// An invoice may be sent in response to an [`InvoiceRequest`] in the case of an offer or sent /// directly after scanning a refund. It includes all the information needed to pay a recipient. /// -/// This is not exported to bindings users as its name conflicts with the BOLT 11 Invoice type. -/// /// [`Offer`]: crate::offers::offer::Offer /// [`Refund`]: crate::offers::refund::Refund /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] -pub struct Invoice { +pub struct Bolt12Invoice { bytes: Vec, contents: InvoiceContents, signature: Signature, } -/// The contents of an [`Invoice`] for responding to either an [`Offer`] or a [`Refund`]. +/// The contents of an [`Bolt12Invoice`] for responding to either an [`Offer`] or a [`Refund`]. /// /// [`Offer`]: crate::offers::offer::Offer /// [`Refund`]: crate::offers::refund::Refund #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] enum InvoiceContents { - /// Contents for an [`Invoice`] corresponding to an [`Offer`]. + /// Contents for an [`Bolt12Invoice`] corresponding to an [`Offer`]. /// /// [`Offer`]: crate::offers::offer::Offer ForOffer { invoice_request: InvoiceRequestContents, fields: InvoiceFields, }, - /// Contents for an [`Invoice`] corresponding to a [`Refund`]. + /// Contents for an [`Bolt12Invoice`] corresponding to a [`Refund`]. /// /// [`Refund`]: crate::offers::refund::Refund ForRefund { @@ -464,7 +463,7 @@ struct InvoiceFields { signing_pubkey: PublicKey, } -impl Invoice { +impl Bolt12Invoice { /// A complete description of the purpose of the originating offer or refund. Intended to be /// displayed to the user but with the caveat that it has not been verified in any way. pub fn description(&self) -> PrintableString { @@ -475,7 +474,7 @@ impl Invoice { /// needed for routing payments across them. /// /// Blinded paths provide recipient privacy by obfuscating its node id. Note, however, that this - /// privacy is lost if a public node id is used for [`Invoice::signing_pubkey`]. + /// privacy is lost if a public node id is used for [`Bolt12Invoice::signing_pubkey`]. pub fn payment_paths(&self) -> &[(BlindedPayInfo, BlindedPath)] { &self.contents.fields().payment_paths[..] } @@ -485,8 +484,8 @@ impl Invoice { self.contents.fields().created_at } - /// Duration since [`Invoice::created_at`] when the invoice has expired and therefore should no - /// longer be paid. + /// Duration since [`Bolt12Invoice::created_at`] when the invoice has expired and therefore + /// should no longer be paid. pub fn relative_expiry(&self) -> Duration { self.contents.fields().relative_expiry.unwrap_or(DEFAULT_RELATIVE_EXPIRY) } @@ -579,7 +578,7 @@ impl Invoice { self.contents.fields().signing_pubkey } - /// Signature of the invoice verified using [`Invoice::signing_pubkey`]. + /// Signature of the invoice verified using [`Bolt12Invoice::signing_pubkey`]. pub fn signature(&self) -> Signature { self.signature } @@ -716,7 +715,7 @@ impl InvoiceFields { } } -impl Writeable for Invoice { +impl Writeable for Bolt12Invoice { fn write(&self, writer: &mut W) -> Result<(), io::Error> { WithoutLength(&self.bytes).write(writer) } @@ -728,12 +727,12 @@ impl Writeable for InvoiceContents { } } -impl TryFrom> for Invoice { +impl TryFrom> for Bolt12Invoice { type Error = ParseError; fn try_from(bytes: Vec) -> Result { let parsed_invoice = ParsedMessage::::try_from(bytes)?; - Invoice::try_from(parsed_invoice) + Bolt12Invoice::try_from(parsed_invoice) } } @@ -840,7 +839,7 @@ type PartialInvoiceTlvStreamRef<'a> = ( InvoiceTlvStreamRef<'a>, ); -impl TryFrom> for Invoice { +impl TryFrom> for Bolt12Invoice { type Error = ParseError; fn try_from(invoice: ParsedMessage) -> Result { @@ -860,7 +859,7 @@ impl TryFrom> for Invoice { let pubkey = contents.fields().signing_pubkey; merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, pubkey)?; - Ok(Invoice { bytes, contents, signature }) + Ok(Bolt12Invoice { bytes, contents, signature }) } } @@ -944,7 +943,7 @@ impl TryFrom for InvoiceContents { #[cfg(test)] mod tests { - use super::{DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, Invoice, InvoiceTlvStreamRef, SIGNATURE_TAG}; + use super::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, InvoiceTlvStreamRef, SIGNATURE_TAG}; use bitcoin::blockdata::script::Script; use bitcoin::hashes::Hash; @@ -1066,7 +1065,7 @@ mod tests { ), ); - if let Err(e) = Invoice::try_from(buffer) { + if let Err(e) = Bolt12Invoice::try_from(buffer) { panic!("error parsing invoice: {:?}", e); } } @@ -1144,7 +1143,7 @@ mod tests { ), ); - if let Err(e) = Invoice::try_from(buffer) { + if let Err(e) = Bolt12Invoice::try_from(buffer) { panic!("error parsing invoice: {:?}", e); } } @@ -1494,14 +1493,14 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - if let Err(e) = Invoice::try_from(buffer) { + if let Err(e) = Bolt12Invoice::try_from(buffer) { panic!("error parsing invoice: {:?}", e); } let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.paths = None; - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)), } @@ -1509,7 +1508,7 @@ mod tests { let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.blindedpay = None; - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)), } @@ -1518,7 +1517,7 @@ mod tests { let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.paths = Some(Iterable(empty_payment_paths.iter().map(|(_, path)| path))); - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)), } @@ -1528,7 +1527,7 @@ mod tests { let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.blindedpay = Some(Iterable(payment_paths.iter().map(|(payinfo, _)| payinfo))); - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)), } @@ -1549,14 +1548,14 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - if let Err(e) = Invoice::try_from(buffer) { + if let Err(e) = Bolt12Invoice::try_from(buffer) { panic!("error parsing invoice: {:?}", e); } let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.created_at = None; - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingCreationTime)); @@ -1580,7 +1579,7 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - match Invoice::try_from(buffer) { + match Bolt12Invoice::try_from(buffer) { Ok(invoice) => assert_eq!(invoice.relative_expiry(), Duration::from_secs(3600)), Err(e) => panic!("error parsing invoice: {:?}", e), } @@ -1601,14 +1600,14 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - if let Err(e) = Invoice::try_from(buffer) { + if let Err(e) = Bolt12Invoice::try_from(buffer) { panic!("error parsing invoice: {:?}", e); } let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.payment_hash = None; - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaymentHash)); @@ -1631,14 +1630,14 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - if let Err(e) = Invoice::try_from(buffer) { + if let Err(e) = Bolt12Invoice::try_from(buffer) { panic!("error parsing invoice: {:?}", e); } let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.amount = None; - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)), } @@ -1660,7 +1659,7 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - match Invoice::try_from(buffer) { + match Bolt12Invoice::try_from(buffer) { Ok(invoice) => { let mut features = Bolt12InvoiceFeatures::empty(); features.set_basic_mpp_optional(); @@ -1705,7 +1704,7 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - match Invoice::try_from(buffer) { + match Bolt12Invoice::try_from(buffer) { Ok(invoice) => { assert_eq!( invoice.fallbacks(), @@ -1749,14 +1748,14 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - if let Err(e) = Invoice::try_from(buffer) { + if let Err(e) = Bolt12Invoice::try_from(buffer) { panic!("error parsing invoice: {:?}", e); } let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.node_id = None; - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); @@ -1767,7 +1766,7 @@ mod tests { let mut tlv_stream = invoice.as_tlv_stream(); tlv_stream.3.node_id = Some(&invalid_pubkey); - match Invoice::try_from(tlv_stream.to_bytes()) { + match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidSigningPubkey)); @@ -1789,7 +1788,7 @@ mod tests { .invoice .write(&mut buffer).unwrap(); - match Invoice::try_from(buffer) { + match Bolt12Invoice::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSignature)), } @@ -1812,7 +1811,7 @@ mod tests { let mut buffer = Vec::new(); invoice.write(&mut buffer).unwrap(); - match Invoice::try_from(buffer) { + match Bolt12Invoice::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { assert_eq!(e, ParseError::InvalidSignature(secp256k1::Error::InvalidSignature)); @@ -1838,7 +1837,7 @@ mod tests { BigSize(32).write(&mut encoded_invoice).unwrap(); [42u8; 32].write(&mut encoded_invoice).unwrap(); - match Invoice::try_from(encoded_invoice) { + match Bolt12Invoice::try_from(encoded_invoice) { Ok(_) => panic!("expected error"), Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)), } diff --git a/lightning/src/offers/invoice_error.rs b/lightning/src/offers/invoice_error.rs index e843264b4e3..7345bc14d69 100644 --- a/lightning/src/offers/invoice_error.rs +++ b/lightning/src/offers/invoice_error.rs @@ -17,27 +17,27 @@ use crate::util::string::UntrustedString; use crate::prelude::*; -/// An error in response to an [`InvoiceRequest`] or an [`Invoice`]. +/// An error in response to an [`InvoiceRequest`] or an [`Bolt12Invoice`]. /// /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] pub struct InvoiceError { - /// The field in the [`InvoiceRequest`] or the [`Invoice`] that contained an error. + /// The field in the [`InvoiceRequest`] or the [`Bolt12Invoice`] that contained an error. /// /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest - /// [`Invoice`]: crate::offers::invoice::Invoice + /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice pub erroneous_field: Option, /// An explanation of the error. pub message: UntrustedString, } -/// The field in the [`InvoiceRequest`] or the [`Invoice`] that contained an error. +/// The field in the [`InvoiceRequest`] or the [`Bolt12Invoice`] that contained an error. /// /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] pub struct ErroneousField { diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index f51d2526781..f5cb439b58a 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -11,12 +11,12 @@ //! //! An [`InvoiceRequest`] can be built from a parsed [`Offer`] as an "offer to be paid". It is //! typically constructed by a customer and sent to the merchant who had published the corresponding -//! offer. The recipient of the request responds with an [`Invoice`]. +//! offer. The recipient of the request responds with a [`Bolt12Invoice`]. //! //! For an "offer for money" (e.g., refund, ATM withdrawal), where an offer doesn't exist as a //! precursor, see [`Refund`]. //! -//! [`Invoice`]: crate::offers::invoice::Invoice +//! [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice //! [`Refund`]: crate::offers::refund::Refund //! //! ``` @@ -247,7 +247,7 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a fn build_without_checks(mut self) -> (UnsignedInvoiceRequest<'a>, Option, Option<&'b Secp256k1>) { - // Create the metadata for stateless verification of an Invoice. + // Create the metadata for stateless verification of a Bolt12Invoice. let mut keys = None; let secp_ctx = self.secp_ctx.clone(); if self.invoice_request.payer.0.has_derivation_material() { @@ -381,12 +381,12 @@ impl<'a> UnsignedInvoiceRequest<'a> { } } -/// An `InvoiceRequest` is a request for an [`Invoice`] formulated from an [`Offer`]. +/// An `InvoiceRequest` is a request for a [`Bolt12Invoice`] formulated from an [`Offer`]. /// /// An offer may provide choices such as quantity, amount, chain, features, etc. An invoice request /// specifies these such that its recipient can send an invoice for payment. /// -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice /// [`Offer`]: crate::offers::offer::Offer #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] @@ -396,9 +396,9 @@ pub struct InvoiceRequest { signature: Signature, } -/// The contents of an [`InvoiceRequest`], which may be shared with an [`Invoice`]. +/// The contents of an [`InvoiceRequest`], which may be shared with an [`Bolt12Invoice`]. /// -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] pub(super) struct InvoiceRequestContents { @@ -492,8 +492,8 @@ impl InvoiceRequest { /// Creates an [`InvoiceBuilder`] for the request with the given required fields. /// /// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after - /// `created_at`, which is used to set [`Invoice::created_at`]. Useful for `no-std` builds where - /// [`std::time::SystemTime`] is not available. + /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. Useful for `no-std` builds + /// where [`std::time::SystemTime`] is not available. /// /// The caller is expected to remember the preimage of `payment_hash` in order to claim a payment /// for the invoice. @@ -507,7 +507,7 @@ impl InvoiceRequest { /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. /// - /// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at + /// [`Bolt12Invoice::created_at`]: crate::offers::invoice::Bolt12Invoice::created_at pub fn respond_with_no_std( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, created_at: core::time::Duration @@ -520,14 +520,14 @@ impl InvoiceRequest { } /// Creates an [`InvoiceBuilder`] for the request using the given required fields and that uses - /// derived signing keys from the originating [`Offer`] to sign the [`Invoice`]. Must use the - /// same [`ExpandedKey`] as the one used to create the offer. + /// derived signing keys from the originating [`Offer`] to sign the [`Bolt12Invoice`]. Must use + /// the same [`ExpandedKey`] as the one used to create the offer. /// /// See [`InvoiceRequest::respond_with`] for further details. /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. /// - /// [`Invoice`]: crate::offers::invoice::Invoice + /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[cfg(feature = "std")] pub fn verify_and_respond_using_derived_keys( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, @@ -543,14 +543,14 @@ impl InvoiceRequest { } /// Creates an [`InvoiceBuilder`] for the request using the given required fields and that uses - /// derived signing keys from the originating [`Offer`] to sign the [`Invoice`]. Must use the - /// same [`ExpandedKey`] as the one used to create the offer. + /// derived signing keys from the originating [`Offer`] to sign the [`Bolt12Invoice`]. Must use + /// the same [`ExpandedKey`] as the one used to create the offer. /// /// See [`InvoiceRequest::respond_with_no_std`] for further details. /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. /// - /// [`Invoice`]: crate::offers::invoice::Invoice + /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice pub fn verify_and_respond_using_derived_keys_no_std( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, created_at: core::time::Duration, expanded_key: &ExpandedKey, secp_ctx: &Secp256k1 @@ -569,10 +569,10 @@ impl InvoiceRequest { } /// Verifies that the request was for an offer created using the given key. Returns the derived - /// keys need to sign an [`Invoice`] for the request if they could be extracted from the + /// keys need to sign an [`Bolt12Invoice`] for the request if they could be extracted from the /// metadata. /// - /// [`Invoice`]: crate::offers::invoice::Invoice + /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice pub fn verify( &self, key: &ExpandedKey, secp_ctx: &Secp256k1 ) -> Result, ()> { @@ -789,7 +789,7 @@ mod tests { use crate::ln::features::InvoiceRequestFeatures; use crate::ln::inbound_payment::ExpandedKey; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; - use crate::offers::invoice::{Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG}; + use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG}; use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self}; use crate::offers::offer::{Amount, OfferBuilder, OfferTlvStreamRef, Quantity}; use crate::offers::parse::{ParseError, SemanticError}; @@ -930,7 +930,7 @@ mod tests { let mut encoded_invoice = bytes; signature_tlv_stream.write(&mut encoded_invoice).unwrap(); - let invoice = Invoice::try_from(encoded_invoice).unwrap(); + let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap(); assert!(!invoice.verify(&expanded_key, &secp_ctx)); // Fails verification with altered metadata @@ -954,7 +954,7 @@ mod tests { let mut encoded_invoice = bytes; signature_tlv_stream.write(&mut encoded_invoice).unwrap(); - let invoice = Invoice::try_from(encoded_invoice).unwrap(); + let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap(); assert!(!invoice.verify(&expanded_key, &secp_ctx)); } @@ -1000,7 +1000,7 @@ mod tests { let mut encoded_invoice = bytes; signature_tlv_stream.write(&mut encoded_invoice).unwrap(); - let invoice = Invoice::try_from(encoded_invoice).unwrap(); + let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap(); assert!(!invoice.verify(&expanded_key, &secp_ctx)); // Fails verification with altered payer id @@ -1024,7 +1024,7 @@ mod tests { let mut encoded_invoice = bytes; signature_tlv_stream.write(&mut encoded_invoice).unwrap(); - let invoice = Invoice::try_from(encoded_invoice).unwrap(); + let invoice = Bolt12Invoice::try_from(encoded_invoice).unwrap(); assert!(!invoice.verify(&expanded_key, &secp_ctx)); } diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 9c8489778b0..fd705a901c7 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -319,8 +319,8 @@ impl<'a, M: MetadataStrategy, T: secp256k1::Signing> OfferBuilder<'a, M, T> { /// An `Offer` is a potentially long-lived proposal for payment of a good or service. /// /// An offer is a precursor to an [`InvoiceRequest`]. A merchant publishes an offer from which a -/// customer may request an [`Invoice`] for a specific quantity and using an amount sufficient to -/// cover that quantity (i.e., at least `quantity * amount`). See [`Offer::amount`]. +/// customer may request an [`Bolt12Invoice`] for a specific quantity and using an amount sufficient +/// to cover that quantity (i.e., at least `quantity * amount`). See [`Offer::amount`]. /// /// Offers may be denominated in currency other than bitcoin but are ultimately paid using the /// latter. @@ -328,7 +328,7 @@ impl<'a, M: MetadataStrategy, T: secp256k1::Signing> OfferBuilder<'a, M, T> { /// Through the use of [`BlindedPath`]s, offers provide recipient privacy. /// /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] pub struct Offer { @@ -338,10 +338,11 @@ pub struct Offer { pub(super) contents: OfferContents, } -/// The contents of an [`Offer`], which may be shared with an [`InvoiceRequest`] or an [`Invoice`]. +/// The contents of an [`Offer`], which may be shared with an [`InvoiceRequest`] or a +/// [`Bolt12Invoice`]. /// /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] pub(super) struct OfferContents { @@ -451,8 +452,8 @@ impl Offer { /// - derives the [`InvoiceRequest::payer_id`] such that a different key can be used for each /// request, and /// - sets the [`InvoiceRequest::metadata`] when [`InvoiceRequestBuilder::build`] is called such - /// that it can be used by [`Invoice::verify`] to determine if the invoice was requested using - /// a base [`ExpandedKey`] from which the payer id was derived. + /// that it can be used by [`Bolt12Invoice::verify`] to determine if the invoice was requested + /// using a base [`ExpandedKey`] from which the payer id was derived. /// /// Useful to protect the sender's privacy. /// @@ -460,7 +461,7 @@ impl Offer { /// /// [`InvoiceRequest::payer_id`]: crate::offers::invoice_request::InvoiceRequest::payer_id /// [`InvoiceRequest::metadata`]: crate::offers::invoice_request::InvoiceRequest::metadata - /// [`Invoice::verify`]: crate::offers::invoice::Invoice::verify + /// [`Bolt12Invoice::verify`]: crate::offers::invoice::Bolt12Invoice::verify /// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey pub fn request_invoice_deriving_payer_id<'a, 'b, ES: Deref, T: secp256k1::Signing>( &'a self, expanded_key: &ExpandedKey, entropy_source: ES, secp_ctx: &'b Secp256k1 @@ -497,7 +498,7 @@ impl Offer { } /// Creates an [`InvoiceRequestBuilder`] for the offer with the given `metadata` and `payer_id`, - /// which will be reflected in the `Invoice` response. + /// which will be reflected in the `Bolt12Invoice` response. /// /// The `metadata` is useful for including information about the derivation of `payer_id` such /// that invoice response handling can be stateless. Also serves as payer-provided entropy while diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index 07e759917ac..35c1726c977 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -10,11 +10,11 @@ //! Data structures and encoding for refunds. //! //! A [`Refund`] is an "offer for money" and is typically constructed by a merchant and presented -//! directly to the customer. The recipient responds with an [`Invoice`] to be paid. +//! directly to the customer. The recipient responds with a [`Bolt12Invoice`] to be paid. //! //! This is an [`InvoiceRequest`] produced *not* in response to an [`Offer`]. //! -//! [`Invoice`]: crate::offers::invoice::Invoice +//! [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice //! [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest //! [`Offer`]: crate::offers::offer::Offer //! @@ -207,12 +207,12 @@ impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> { } /// Sets [`Refund::quantity`] of items. This is purely for informational purposes. It is useful - /// when the refund pertains to an [`Invoice`] that paid for more than one item from an + /// when the refund pertains to a [`Bolt12Invoice`] that paid for more than one item from an /// [`Offer`] as specified by [`InvoiceRequest::quantity`]. /// /// Successive calls to this method will override the previous setting. /// - /// [`Invoice`]: crate::offers::invoice::Invoice + /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice /// [`InvoiceRequest::quantity`]: crate::offers::invoice_request::InvoiceRequest::quantity /// [`Offer`]: crate::offers::offer::Offer pub fn quantity(mut self, quantity: u64) -> Self { @@ -234,7 +234,7 @@ impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> { self.refund.chain = None; } - // Create the metadata for stateless verification of an Invoice. + // Create the metadata for stateless verification of a Bolt12Invoice. if self.refund.payer.0.has_derivation_material() { let mut metadata = core::mem::take(&mut self.refund.payer.0); @@ -272,13 +272,13 @@ impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> { } } -/// A `Refund` is a request to send an [`Invoice`] without a preceding [`Offer`]. +/// A `Refund` is a request to send an [`Bolt12Invoice`] without a preceding [`Offer`]. /// /// Typically, after an invoice is paid, the recipient may publish a refund allowing the sender to /// recoup their funds. A refund may be used more generally as an "offer for money", such as with a /// bitcoin ATM. /// -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice /// [`Offer`]: crate::offers::offer::Offer #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] @@ -287,9 +287,9 @@ pub struct Refund { pub(super) contents: RefundContents, } -/// The contents of a [`Refund`], which may be shared with an [`Invoice`]. +/// The contents of a [`Refund`], which may be shared with an [`Bolt12Invoice`]. /// -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq))] pub(super) struct RefundContents { @@ -407,8 +407,8 @@ impl Refund { /// Creates an [`InvoiceBuilder`] for the refund with the given required fields. /// /// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after - /// `created_at`, which is used to set [`Invoice::created_at`]. Useful for `no-std` builds where - /// [`std::time::SystemTime`] is not available. + /// `created_at`, which is used to set [`Bolt12Invoice::created_at`]. Useful for `no-std` builds + /// where [`std::time::SystemTime`] is not available. /// /// The caller is expected to remember the preimage of `payment_hash` in order to /// claim a payment for the invoice. @@ -425,7 +425,7 @@ impl Refund { /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. /// - /// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at + /// [`Bolt12Invoice::created_at`]: crate::offers::invoice::Bolt12Invoice::created_at pub fn respond_with_no_std( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, signing_pubkey: PublicKey, created_at: Duration @@ -438,13 +438,13 @@ impl Refund { } /// Creates an [`InvoiceBuilder`] for the refund using the given required fields and that uses - /// derived signing keys to sign the [`Invoice`]. + /// derived signing keys to sign the [`Bolt12Invoice`]. /// /// See [`Refund::respond_with`] for further details. /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. /// - /// [`Invoice`]: crate::offers::invoice::Invoice + /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[cfg(feature = "std")] pub fn respond_using_derived_keys( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, @@ -463,13 +463,13 @@ impl Refund { } /// Creates an [`InvoiceBuilder`] for the refund using the given required fields and that uses - /// derived signing keys to sign the [`Invoice`]. + /// derived signing keys to sign the [`Bolt12Invoice`]. /// /// See [`Refund::respond_with_no_std`] for further details. /// /// This is not exported to bindings users as builder patterns don't map outside of move semantics. /// - /// [`Invoice`]: crate::offers::invoice::Invoice + /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice pub fn respond_using_derived_keys_no_std( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, created_at: core::time::Duration, expanded_key: &ExpandedKey, entropy_source: ES diff --git a/lightning/src/onion_message/offers.rs b/lightning/src/onion_message/offers.rs index f82afdd618a..e335e8aa88b 100644 --- a/lightning/src/onion_message/offers.rs +++ b/lightning/src/onion_message/offers.rs @@ -14,7 +14,7 @@ use crate::io::{self, Read}; use crate::ln::msgs::DecodeError; use crate::offers::invoice_error::InvoiceError; use crate::offers::invoice_request::InvoiceRequest; -use crate::offers::invoice::Invoice; +use crate::offers::invoice::Bolt12Invoice; use crate::offers::parse::ParseError; use crate::util::logger::Logger; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer}; @@ -30,8 +30,8 @@ const INVOICE_ERROR_TLV_TYPE: u64 = 68; /// /// [`OnionMessage`]: crate::ln::msgs::OnionMessage pub trait OffersMessageHandler { - /// Handles the given message by either responding with an [`Invoice`], sending a payment, or - /// replying with an error. + /// Handles the given message by either responding with an [`Bolt12Invoice`], sending a payment, + /// or replying with an error. fn handle_message(&self, message: OffersMessage) -> Option; } @@ -40,15 +40,15 @@ pub trait OffersMessageHandler { /// [`OnionMessage`]: crate::ln::msgs::OnionMessage #[derive(Debug)] pub enum OffersMessage { - /// A request for an [`Invoice`] for a particular [`Offer`]. + /// A request for a [`Bolt12Invoice`] for a particular [`Offer`]. /// /// [`Offer`]: crate::offers::offer::Offer InvoiceRequest(InvoiceRequest), - /// An [`Invoice`] sent in response to an [`InvoiceRequest`] or a [`Refund`]. + /// A [`Bolt12Invoice`] sent in response to an [`InvoiceRequest`] or a [`Refund`]. /// /// [`Refund`]: crate::offers::refund::Refund - Invoice(Invoice), + Invoice(Bolt12Invoice), /// An error from handling an [`OffersMessage`]. InvoiceError(InvoiceError), @@ -75,7 +75,7 @@ impl OffersMessage { fn parse(tlv_type: u64, bytes: Vec) -> Result { match tlv_type { INVOICE_REQUEST_TLV_TYPE => Ok(Self::InvoiceRequest(InvoiceRequest::try_from(bytes)?)), - INVOICE_TLV_TYPE => Ok(Self::Invoice(Invoice::try_from(bytes)?)), + INVOICE_TLV_TYPE => Ok(Self::Invoice(Bolt12Invoice::try_from(bytes)?)), _ => Err(ParseError::Decode(DecodeError::InvalidValue)), } } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index d3539579c50..141e7d26cc1 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -18,7 +18,7 @@ use crate::ln::PaymentHash; use crate::ln::channelmanager::{ChannelDetails, PaymentId}; use crate::ln::features::{Bolt12InvoiceFeatures, ChannelFeatures, InvoiceFeatures, NodeFeatures}; use crate::ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT}; -use crate::offers::invoice::{BlindedPayInfo, Invoice as Bolt12Invoice}; +use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice}; use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId, RoutingFees}; use crate::routing::scoring::{ChannelUsage, LockableScore, Score}; use crate::util::ser::{Writeable, Readable, ReadableArgs, Writer}; @@ -271,9 +271,9 @@ impl_writeable_tlv_based!(RouteHop, { }); /// The blinded portion of a [`Path`], if we're routing to a recipient who provided blinded paths in -/// their BOLT12 [`Invoice`]. +/// their [`Bolt12Invoice`]. /// -/// [`Invoice`]: crate::offers::invoice::Invoice +/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct BlindedTail { /// The hops of the [`BlindedPath`] provided by the recipient. From d94227cc13d2dee0ce1a4f24629d6e58a8a8416d Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 13 Jul 2023 13:47:09 -0500 Subject: [PATCH 04/13] Qualify the BOLT 12 unsigned invoice type A previous commit qualified the BOLT 12 invoice type, so any related types should be similarly qualified, if public. --- fuzz/src/invoice_request_deser.rs | 4 ++-- fuzz/src/refund_deser.rs | 4 ++-- lightning/src/offers/invoice.rs | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fuzz/src/invoice_request_deser.rs b/fuzz/src/invoice_request_deser.rs index f8fe34f2b8b..dbf62fac7df 100644 --- a/fuzz/src/invoice_request_deser.rs +++ b/fuzz/src/invoice_request_deser.rs @@ -14,7 +14,7 @@ use lightning::blinded_path::BlindedPath; use lightning::sign::EntropySource; use lightning::ln::PaymentHash; use lightning::ln::features::BlindedHopFeatures; -use lightning::offers::invoice::{BlindedPayInfo, UnsignedInvoice}; +use lightning::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice}; use lightning::offers::invoice_request::InvoiceRequest; use lightning::offers::parse::SemanticError; use lightning::util::ser::Writeable; @@ -71,7 +71,7 @@ fn privkey(byte: u8) -> SecretKey { fn build_response<'a, T: secp256k1::Signing + secp256k1::Verification>( invoice_request: &'a InvoiceRequest, secp_ctx: &Secp256k1 -) -> Result, SemanticError> { +) -> Result, SemanticError> { let entropy_source = Randomness {}; let paths = vec![ BlindedPath::new_for_message(&[pubkey(43), pubkey(44), pubkey(42)], &entropy_source, secp_ctx).unwrap(), diff --git a/fuzz/src/refund_deser.rs b/fuzz/src/refund_deser.rs index 618b129f9a1..b1c729d9e5c 100644 --- a/fuzz/src/refund_deser.rs +++ b/fuzz/src/refund_deser.rs @@ -14,7 +14,7 @@ use lightning::blinded_path::BlindedPath; use lightning::sign::EntropySource; use lightning::ln::PaymentHash; use lightning::ln::features::BlindedHopFeatures; -use lightning::offers::invoice::{BlindedPayInfo, UnsignedInvoice}; +use lightning::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice}; use lightning::offers::parse::SemanticError; use lightning::offers::refund::Refund; use lightning::util::ser::Writeable; @@ -60,7 +60,7 @@ fn privkey(byte: u8) -> SecretKey { fn build_response<'a, T: secp256k1::Signing + secp256k1::Verification>( refund: &'a Refund, signing_pubkey: PublicKey, secp_ctx: &Secp256k1 -) -> Result, SemanticError> { +) -> Result, SemanticError> { let entropy_source = Randomness {}; let paths = vec![ BlindedPath::new_for_message(&[pubkey(43), pubkey(44), pubkey(42)], &entropy_source, secp_ctx).unwrap(), diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index 9a09e58aca1..8e0c28b60ef 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -330,8 +330,8 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> { /// Builds an unsigned [`Bolt12Invoice`] after checking for valid semantics. It can be signed by - /// [`UnsignedInvoice::sign`]. - pub fn build(self) -> Result, SemanticError> { + /// [`UnsignedBolt12Invoice::sign`]. + pub fn build(self) -> Result, SemanticError> { #[cfg(feature = "std")] { if self.invoice.is_offer_or_refund_expired() { return Err(SemanticError::AlreadyExpired); @@ -339,7 +339,7 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> { } let InvoiceBuilder { invreq_bytes, invoice, .. } = self; - Ok(UnsignedInvoice { invreq_bytes, invoice }) + Ok(UnsignedBolt12Invoice { invreq_bytes, invoice }) } } @@ -355,7 +355,7 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> { } let InvoiceBuilder { invreq_bytes, invoice, keys, .. } = self; - let unsigned_invoice = UnsignedInvoice { invreq_bytes, invoice }; + let unsigned_invoice = UnsignedBolt12Invoice { invreq_bytes, invoice }; let keys = keys.unwrap(); let invoice = unsigned_invoice @@ -366,12 +366,12 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> { } /// A semantically valid [`Bolt12Invoice`] that hasn't been signed. -pub struct UnsignedInvoice<'a> { +pub struct UnsignedBolt12Invoice<'a> { invreq_bytes: &'a Vec, invoice: InvoiceContents, } -impl<'a> UnsignedInvoice<'a> { +impl<'a> UnsignedBolt12Invoice<'a> { /// The public key corresponding to the key needed to sign the invoice. pub fn signing_pubkey(&self) -> PublicKey { self.invoice.fields().signing_pubkey From 5627d7cc1f94815915422e669e2f29a1a7854fc4 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 13 Jul 2023 16:09:43 -0500 Subject: [PATCH 05/13] Qualify the BOLT 12 parse error To avoid a naming conflict in bindings with BOLT 11 parse error, qualify the BOLT 12 parse error type. --- fuzz/src/bech32_parse.rs | 6 ++-- lightning/src/offers/invoice.rs | 38 +++++++++++------------ lightning/src/offers/invoice_request.rs | 40 ++++++++++++------------- lightning/src/offers/offer.rs | 32 ++++++++++---------- lightning/src/offers/parse.rs | 22 +++++++------- lightning/src/offers/refund.rs | 36 +++++++++++----------- lightning/src/onion_message/offers.rs | 12 ++++---- 7 files changed, 92 insertions(+), 94 deletions(-) diff --git a/fuzz/src/bech32_parse.rs b/fuzz/src/bech32_parse.rs index f3dd5ac9d1e..ff465ceea39 100644 --- a/fuzz/src/bech32_parse.rs +++ b/fuzz/src/bech32_parse.rs @@ -9,7 +9,7 @@ use crate::utils::test_logger; use core::convert::TryFrom; -use lightning::offers::parse::{Bech32Encode, ParseError}; +use lightning::offers::parse::{Bech32Encode, Bolt12ParseError}; #[inline] pub fn do_test(data: &[u8], _out: Out) { @@ -35,8 +35,8 @@ impl AsRef<[u8]> for Bytes { } impl TryFrom> for Bytes { - type Error = ParseError; - fn try_from(data: Vec) -> Result { + type Error = Bolt12ParseError; + fn try_from(data: Vec) -> Result { Ok(Bytes(data)) } } diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index 8e0c28b60ef..03bb9553625 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -34,7 +34,7 @@ //! # fn create_payment_paths() -> Vec<(BlindedPayInfo, BlindedPath)> { unimplemented!() } //! # fn create_payment_hash() -> PaymentHash { unimplemented!() } //! # -//! # fn parse_invoice_request(bytes: Vec) -> Result<(), lightning::offers::parse::ParseError> { +//! # fn parse_invoice_request(bytes: Vec) -> Result<(), lightning::offers::parse::Bolt12ParseError> { //! let payment_paths = create_payment_paths(); //! let payment_hash = create_payment_hash(); //! let secp_ctx = Secp256k1::new(); @@ -62,7 +62,7 @@ //! # Ok(()) //! # } //! -//! # fn parse_refund(bytes: Vec) -> Result<(), lightning::offers::parse::ParseError> { +//! # fn parse_refund(bytes: Vec) -> Result<(), lightning::offers::parse::Bolt12ParseError> { //! # let payment_paths = create_payment_paths(); //! # let payment_hash = create_payment_hash(); //! # let secp_ctx = Secp256k1::new(); @@ -112,7 +112,7 @@ use crate::ln::msgs::DecodeError; use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef}; use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TlvStream, WithoutSignatures, self}; use crate::offers::offer::{Amount, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef}; -use crate::offers::parse::{ParseError, ParsedMessage, SemanticError}; +use crate::offers::parse::{Bolt12ParseError, ParsedMessage, SemanticError}; use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef}; use crate::offers::refund::{IV_BYTES as REFUND_IV_BYTES, Refund, RefundContents}; use crate::offers::signer; @@ -728,7 +728,7 @@ impl Writeable for InvoiceContents { } impl TryFrom> for Bolt12Invoice { - type Error = ParseError; + type Error = Bolt12ParseError; fn try_from(bytes: Vec) -> Result { let parsed_invoice = ParsedMessage::::try_from(bytes)?; @@ -840,7 +840,7 @@ type PartialInvoiceTlvStreamRef<'a> = ( ); impl TryFrom> for Bolt12Invoice { - type Error = ParseError; + type Error = Bolt12ParseError; fn try_from(invoice: ParsedMessage) -> Result { let ParsedMessage { bytes, tlv_stream } = invoice; @@ -853,7 +853,7 @@ impl TryFrom> for Bolt12Invoice { )?; let signature = match signature { - None => return Err(ParseError::InvalidSemantics(SemanticError::MissingSignature)), + None => return Err(Bolt12ParseError::InvalidSemantics(SemanticError::MissingSignature)), Some(signature) => signature, }; let pubkey = contents.fields().signing_pubkey; @@ -961,7 +961,7 @@ mod tests { use crate::offers::invoice_request::InvoiceRequestTlvStreamRef; use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self}; use crate::offers::offer::{OfferBuilder, OfferTlvStreamRef, Quantity}; - use crate::offers::parse::{ParseError, SemanticError}; + use crate::offers::parse::{Bolt12ParseError, SemanticError}; use crate::offers::payer::PayerTlvStreamRef; use crate::offers::refund::RefundBuilder; use crate::offers::test_utils::*; @@ -1502,7 +1502,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPaths)), } let mut tlv_stream = invoice.as_tlv_stream(); @@ -1510,7 +1510,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)), } let empty_payment_paths = vec![]; @@ -1519,7 +1519,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaths)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPaths)), } let mut payment_paths = payment_paths(); @@ -1529,7 +1529,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)), } } @@ -1558,7 +1558,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingCreationTime)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingCreationTime)); }, } } @@ -1610,7 +1610,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPaymentHash)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPaymentHash)); }, } } @@ -1639,7 +1639,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingAmount)), } } @@ -1758,7 +1758,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); }, } @@ -1769,7 +1769,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidSigningPubkey)); }, } } @@ -1790,7 +1790,7 @@ mod tests { match Bolt12Invoice::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSignature)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSignature)), } } @@ -1814,7 +1814,7 @@ mod tests { match Bolt12Invoice::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSignature(secp256k1::Error::InvalidSignature)); + assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature)); }, } } @@ -1839,7 +1839,7 @@ mod tests { match Bolt12Invoice::try_from(encoded_invoice) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)), + Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)), } } } diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index f5cb439b58a..6c70a5968eb 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -30,7 +30,7 @@ //! use lightning::offers::offer::Offer; //! use lightning::util::ser::Writeable; //! -//! # fn parse() -> Result<(), lightning::offers::parse::ParseError> { +//! # fn parse() -> Result<(), lightning::offers::parse::Bolt12ParseError> { //! let secp_ctx = Secp256k1::new(); //! let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32])?); //! let pubkey = PublicKey::from(keys); @@ -68,7 +68,7 @@ use crate::ln::msgs::DecodeError; use crate::offers::invoice::{BlindedPayInfo, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder}; use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, self}; use crate::offers::offer::{Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef}; -use crate::offers::parse::{ParseError, ParsedMessage, SemanticError}; +use crate::offers::parse::{Bolt12ParseError, ParsedMessage, SemanticError}; use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef}; use crate::offers::signer::{Metadata, MetadataMaterial}; use crate::util::ser::{HighZeroBytesDroppedBigSize, SeekReadable, WithoutLength, Writeable, Writer}; @@ -708,7 +708,7 @@ type PartialInvoiceRequestTlvStreamRef<'a> = ( ); impl TryFrom> for InvoiceRequest { - type Error = ParseError; + type Error = Bolt12ParseError; fn try_from(bytes: Vec) -> Result { let invoice_request = ParsedMessage::::try_from(bytes)?; @@ -722,7 +722,7 @@ impl TryFrom> for InvoiceRequest { )?; let signature = match signature { - None => return Err(ParseError::InvalidSemantics(SemanticError::MissingSignature)), + None => return Err(Bolt12ParseError::InvalidSemantics(SemanticError::MissingSignature)), Some(signature) => signature, }; merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, contents.payer_id)?; @@ -792,7 +792,7 @@ mod tests { use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG}; use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self}; use crate::offers::offer::{Amount, OfferBuilder, OfferTlvStreamRef, Quantity}; - use crate::offers::parse::{ParseError, SemanticError}; + use crate::offers::parse::{Bolt12ParseError, SemanticError}; use crate::offers::payer::PayerTlvStreamRef; use crate::offers::test_utils::*; use crate::util::ser::{BigSize, Writeable}; @@ -1438,7 +1438,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnsupportedChain)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnsupportedChain)), } } @@ -1483,7 +1483,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingAmount)), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1499,7 +1499,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InsufficientAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InsufficientAmount)), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1515,7 +1515,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnsupportedCurrency)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnsupportedCurrency)); }, } @@ -1533,7 +1533,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidAmount)), } } @@ -1573,7 +1573,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedQuantity)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedQuantity)); }, } @@ -1609,7 +1609,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidQuantity)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidQuantity)), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1642,7 +1642,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingQuantity)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingQuantity)), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1658,7 +1658,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingQuantity)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingQuantity)), } } @@ -1678,7 +1678,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPayerMetadata)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPayerMetadata)); }, } } @@ -1698,7 +1698,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPayerId)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPayerId)), } } @@ -1718,7 +1718,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); }, } } @@ -1736,7 +1736,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSignature)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSignature)), } } @@ -1757,7 +1757,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSignature(secp256k1::Error::InvalidSignature)); + assert_eq!(e, Bolt12ParseError::InvalidSignature(secp256k1::Error::InvalidSignature)); }, } } @@ -1782,7 +1782,7 @@ mod tests { match InvoiceRequest::try_from(encoded_invoice_request) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)), + Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)), } } } diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index fd705a901c7..1168aff9432 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -24,7 +24,7 @@ //! //! use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey}; //! use lightning::offers::offer::{Offer, OfferBuilder, Quantity}; -//! use lightning::offers::parse::ParseError; +//! use lightning::offers::parse::Bolt12ParseError; //! use lightning::util::ser::{Readable, Writeable}; //! //! # use lightning::blinded_path::BlindedPath; @@ -35,7 +35,7 @@ //! # fn create_another_blinded_path() -> BlindedPath { unimplemented!() } //! # //! # #[cfg(feature = "std")] -//! # fn build() -> Result<(), ParseError> { +//! # fn build() -> Result<(), Bolt12ParseError> { //! let secp_ctx = Secp256k1::new(); //! let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); //! let pubkey = PublicKey::from(keys); @@ -82,7 +82,7 @@ use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce}; use crate::ln::msgs::MAX_VALUE_MSAT; use crate::offers::invoice_request::{DerivedPayerId, ExplicitPayerId, InvoiceRequestBuilder}; use crate::offers::merkle::TlvStream; -use crate::offers::parse::{Bech32Encode, ParseError, ParsedMessage, SemanticError}; +use crate::offers::parse::{Bech32Encode, Bolt12ParseError, ParsedMessage, SemanticError}; use crate::offers::signer::{Metadata, MetadataMaterial, self}; use crate::util::ser::{HighZeroBytesDroppedBigSize, WithoutLength, Writeable, Writer}; use crate::util::string::PrintableString; @@ -768,7 +768,7 @@ impl Bech32Encode for Offer { } impl FromStr for Offer { - type Err = ParseError; + type Err = Bolt12ParseError; fn from_str(s: &str) -> Result::Err> { Self::from_bech32_str(s) @@ -776,7 +776,7 @@ impl FromStr for Offer { } impl TryFrom> for Offer { - type Error = ParseError; + type Error = Bolt12ParseError; fn try_from(bytes: Vec) -> Result { let offer = ParsedMessage::::try_from(bytes)?; @@ -856,7 +856,7 @@ mod tests { use crate::ln::features::OfferFeatures; use crate::ln::inbound_payment::ExpandedKey; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; - use crate::offers::parse::{ParseError, SemanticError}; + use crate::offers::parse::{Bolt12ParseError, SemanticError}; use crate::offers::test_utils::*; use crate::util::ser::{BigSize, Writeable}; use crate::util::string::PrintableString; @@ -1305,7 +1305,7 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingAmount)), } let mut tlv_stream = offer.as_tlv_stream(); @@ -1317,7 +1317,7 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidAmount)), } } @@ -1337,7 +1337,7 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingDescription)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingDescription)); }, } } @@ -1427,7 +1427,7 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); }, } } @@ -1444,14 +1444,14 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)), + Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)), } } } #[cfg(test)] mod bech32_tests { - use super::{Offer, ParseError}; + use super::{Bolt12ParseError, Offer}; use bitcoin::bech32; use crate::ln::msgs::DecodeError; @@ -1493,7 +1493,7 @@ mod bech32_tests { for encoded_offer in &offers { match encoded_offer.parse::() { Ok(_) => panic!("Valid offer: {}", encoded_offer), - Err(e) => assert_eq!(e, ParseError::InvalidContinuation), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidContinuation), } } @@ -1504,7 +1504,7 @@ mod bech32_tests { let encoded_offer = "lni1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxg"; match encoded_offer.parse::() { Ok(_) => panic!("Valid offer: {}", encoded_offer), - Err(e) => assert_eq!(e, ParseError::InvalidBech32Hrp), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidBech32Hrp), } } @@ -1513,7 +1513,7 @@ mod bech32_tests { let encoded_offer = "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxo"; match encoded_offer.parse::() { Ok(_) => panic!("Valid offer: {}", encoded_offer), - Err(e) => assert_eq!(e, ParseError::Bech32(bech32::Error::InvalidChar('o'))), + Err(e) => assert_eq!(e, Bolt12ParseError::Bech32(bech32::Error::InvalidChar('o'))), } } @@ -1522,7 +1522,7 @@ mod bech32_tests { let encoded_offer = "lno1pqps7sjqpgtyzm3qv4uxzmtsd3jjqer9wd3hy6tsw35k7msjzfpy7nz5yqcnygrfdej82um5wf5k2uckyypwa3eyt44h6txtxquqh7lz5djge4afgfjn7k4rgrkuag0jsd5xvxgqqqqq"; match encoded_offer.parse::() { Ok(_) => panic!("Valid offer: {}", encoded_offer), - Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)), + Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)), } } } diff --git a/lightning/src/offers/parse.rs b/lightning/src/offers/parse.rs index 42ed2e002d1..064604f3afb 100644 --- a/lightning/src/offers/parse.rs +++ b/lightning/src/offers/parse.rs @@ -29,24 +29,24 @@ mod sealed { use bitcoin::bech32::{FromBase32, ToBase32}; use core::convert::TryFrom; use core::fmt; - use super::ParseError; + use super::Bolt12ParseError; use crate::prelude::*; /// Indicates a message can be encoded using bech32. - pub trait Bech32Encode: AsRef<[u8]> + TryFrom, Error=ParseError> { + pub trait Bech32Encode: AsRef<[u8]> + TryFrom, Error=Bolt12ParseError> { /// Human readable part of the message's bech32 encoding. const BECH32_HRP: &'static str; /// Parses a bech32-encoded message into a TLV stream. - fn from_bech32_str(s: &str) -> Result { + fn from_bech32_str(s: &str) -> Result { // Offer encoding may be split by '+' followed by optional whitespace. let encoded = match s.split('+').skip(1).next() { Some(_) => { for chunk in s.split('+') { let chunk = chunk.trim_start(); if chunk.is_empty() || chunk.contains(char::is_whitespace) { - return Err(ParseError::InvalidContinuation); + return Err(Bolt12ParseError::InvalidContinuation); } } @@ -59,7 +59,7 @@ mod sealed { let (hrp, data) = bech32::decode_without_checksum(encoded.as_ref())?; if hrp != Self::BECH32_HRP { - return Err(ParseError::InvalidBech32Hrp); + return Err(Bolt12ParseError::InvalidBech32Hrp); } let data = Vec::::from_base32(&data)?; @@ -116,10 +116,8 @@ impl TryFrom> for ParsedMessage { } /// Error when parsing a bech32 encoded message using [`str::parse`]. -/// -/// This is not exported to bindings users as its name conflicts with the BOLT 11 ParseError type. #[derive(Debug, PartialEq)] -pub enum ParseError { +pub enum Bolt12ParseError { /// The bech32 encoding does not conform to the BOLT 12 requirements for continuing messages /// across multiple parts (i.e., '+' followed by whitespace). InvalidContinuation, @@ -195,25 +193,25 @@ pub enum SemanticError { MissingSignature, } -impl From for ParseError { +impl From for Bolt12ParseError { fn from(error: bech32::Error) -> Self { Self::Bech32(error) } } -impl From for ParseError { +impl From for Bolt12ParseError { fn from(error: DecodeError) -> Self { Self::Decode(error) } } -impl From for ParseError { +impl From for Bolt12ParseError { fn from(error: SemanticError) -> Self { Self::InvalidSemantics(error) } } -impl From for ParseError { +impl From for Bolt12ParseError { fn from(error: secp256k1::Error) -> Self { Self::InvalidSignature(error) } diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index 35c1726c977..aea5e49a3c8 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -28,7 +28,7 @@ //! //! use bitcoin::network::constants::Network; //! use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey}; -//! use lightning::offers::parse::ParseError; +//! use lightning::offers::parse::Bolt12ParseError; //! use lightning::offers::refund::{Refund, RefundBuilder}; //! use lightning::util::ser::{Readable, Writeable}; //! @@ -40,7 +40,7 @@ //! # fn create_another_blinded_path() -> BlindedPath { unimplemented!() } //! # //! # #[cfg(feature = "std")] -//! # fn build() -> Result<(), ParseError> { +//! # fn build() -> Result<(), Bolt12ParseError> { //! let secp_ctx = Secp256k1::new(); //! let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); //! let pubkey = PublicKey::from(keys); @@ -88,7 +88,7 @@ use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; use crate::offers::invoice::{BlindedPayInfo, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder}; use crate::offers::invoice_request::{InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef}; use crate::offers::offer::{OfferTlvStream, OfferTlvStreamRef}; -use crate::offers::parse::{Bech32Encode, ParseError, ParsedMessage, SemanticError}; +use crate::offers::parse::{Bech32Encode, Bolt12ParseError, ParsedMessage, SemanticError}; use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef}; use crate::offers::signer::{Metadata, MetadataMaterial, self}; use crate::util::ser::{SeekReadable, WithoutLength, Writeable, Writer}; @@ -606,7 +606,7 @@ impl Bech32Encode for Refund { } impl FromStr for Refund { - type Err = ParseError; + type Err = Bolt12ParseError; fn from_str(s: &str) -> Result::Err> { Refund::from_bech32_str(s) @@ -614,7 +614,7 @@ impl FromStr for Refund { } impl TryFrom> for Refund { - type Error = ParseError; + type Error = Bolt12ParseError; fn try_from(bytes: Vec) -> Result { let refund = ParsedMessage::::try_from(bytes)?; @@ -718,7 +718,7 @@ mod tests { use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; use crate::offers::invoice_request::InvoiceRequestTlvStreamRef; use crate::offers::offer::OfferTlvStreamRef; - use crate::offers::parse::{ParseError, SemanticError}; + use crate::offers::parse::{Bolt12ParseError, SemanticError}; use crate::offers::payer::PayerTlvStreamRef; use crate::offers::test_utils::*; use crate::util::ser::{BigSize, Writeable}; @@ -1082,7 +1082,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPayerMetadata)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPayerMetadata)); }, } } @@ -1101,7 +1101,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingDescription)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingDescription)); }, } } @@ -1120,7 +1120,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingAmount)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingAmount)); }, } @@ -1130,7 +1130,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::InvalidAmount)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidAmount)); }, } } @@ -1149,7 +1149,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::MissingPayerId)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPayerId)); }, } } @@ -1218,7 +1218,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedMetadata)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedMetadata)); }, } @@ -1229,7 +1229,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedChain)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedChain)); }, } @@ -1240,7 +1240,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedAmount)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedAmount)); }, } @@ -1251,7 +1251,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedFeatures)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedFeatures)); }, } @@ -1261,7 +1261,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedQuantity)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedQuantity)); }, } @@ -1272,7 +1272,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, ParseError::InvalidSemantics(SemanticError::UnexpectedSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedSigningPubkey)); }, } } @@ -1292,7 +1292,7 @@ mod tests { match Refund::try_from(encoded_refund) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, ParseError::Decode(DecodeError::InvalidValue)), + Err(e) => assert_eq!(e, Bolt12ParseError::Decode(DecodeError::InvalidValue)), } } } diff --git a/lightning/src/onion_message/offers.rs b/lightning/src/onion_message/offers.rs index e335e8aa88b..9a1f59b8459 100644 --- a/lightning/src/onion_message/offers.rs +++ b/lightning/src/onion_message/offers.rs @@ -15,7 +15,7 @@ use crate::ln::msgs::DecodeError; use crate::offers::invoice_error::InvoiceError; use crate::offers::invoice_request::InvoiceRequest; use crate::offers::invoice::Bolt12Invoice; -use crate::offers::parse::ParseError; +use crate::offers::parse::Bolt12ParseError; use crate::util::logger::Logger; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer}; @@ -72,11 +72,11 @@ impl OffersMessage { } } - fn parse(tlv_type: u64, bytes: Vec) -> Result { + fn parse(tlv_type: u64, bytes: Vec) -> Result { match tlv_type { INVOICE_REQUEST_TLV_TYPE => Ok(Self::InvoiceRequest(InvoiceRequest::try_from(bytes)?)), INVOICE_TLV_TYPE => Ok(Self::Invoice(Bolt12Invoice::try_from(bytes)?)), - _ => Err(ParseError::Decode(DecodeError::InvalidValue)), + _ => Err(Bolt12ParseError::Decode(DecodeError::InvalidValue)), } } } @@ -103,12 +103,12 @@ impl ReadableArgs<(u64, &L)> for OffersMessage { match Self::parse(tlv_type, bytes) { Ok(message) => Ok(message), - Err(ParseError::Decode(e)) => Err(e), - Err(ParseError::InvalidSemantics(e)) => { + Err(Bolt12ParseError::Decode(e)) => Err(e), + Err(Bolt12ParseError::InvalidSemantics(e)) => { log_trace!(logger, "Invalid semantics for TLV type {}: {:?}", tlv_type, e); Err(DecodeError::InvalidValue) }, - Err(ParseError::InvalidSignature(e)) => { + Err(Bolt12ParseError::InvalidSignature(e)) => { log_trace!(logger, "Invalid signature for TLV type {}: {:?}", tlv_type, e); Err(DecodeError::InvalidValue) }, From 3234136f57976d3adca795b611b251c557d3054a Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 13 Jul 2023 16:28:55 -0500 Subject: [PATCH 06/13] Qualify the BOLT 12 semantic error To avoid a naming conflict in bindings with BOLT 11 semantic error, qualify the BOLT 12 semantic error type. --- fuzz/src/invoice_request_deser.rs | 4 +- fuzz/src/offer_deser.rs | 6 +- fuzz/src/refund_deser.rs | 4 +- lightning/src/offers/invoice.rs | 84 +++++++++---------- lightning/src/offers/invoice_error.rs | 6 +- lightning/src/offers/invoice_request.rs | 106 ++++++++++++------------ lightning/src/offers/offer.rs | 66 +++++++-------- lightning/src/offers/parse.rs | 10 +-- lightning/src/offers/refund.rs | 76 ++++++++--------- 9 files changed, 180 insertions(+), 182 deletions(-) diff --git a/fuzz/src/invoice_request_deser.rs b/fuzz/src/invoice_request_deser.rs index dbf62fac7df..ca9d06ab1f8 100644 --- a/fuzz/src/invoice_request_deser.rs +++ b/fuzz/src/invoice_request_deser.rs @@ -16,7 +16,7 @@ use lightning::ln::PaymentHash; use lightning::ln::features::BlindedHopFeatures; use lightning::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice}; use lightning::offers::invoice_request::InvoiceRequest; -use lightning::offers::parse::SemanticError; +use lightning::offers::parse::Bolt12SemanticError; use lightning::util::ser::Writeable; #[inline] @@ -71,7 +71,7 @@ fn privkey(byte: u8) -> SecretKey { fn build_response<'a, T: secp256k1::Signing + secp256k1::Verification>( invoice_request: &'a InvoiceRequest, secp_ctx: &Secp256k1 -) -> Result, SemanticError> { +) -> Result, Bolt12SemanticError> { let entropy_source = Randomness {}; let paths = vec![ BlindedPath::new_for_message(&[pubkey(43), pubkey(44), pubkey(42)], &entropy_source, secp_ctx).unwrap(), diff --git a/fuzz/src/offer_deser.rs b/fuzz/src/offer_deser.rs index 213742d8c08..53f67a3380d 100644 --- a/fuzz/src/offer_deser.rs +++ b/fuzz/src/offer_deser.rs @@ -12,7 +12,7 @@ use crate::utils::test_logger; use core::convert::{Infallible, TryFrom}; use lightning::offers::invoice_request::UnsignedInvoiceRequest; use lightning::offers::offer::{Amount, Offer, Quantity}; -use lightning::offers::parse::SemanticError; +use lightning::offers::parse::Bolt12SemanticError; use lightning::util::ser::Writeable; #[inline] @@ -41,13 +41,13 @@ pub fn do_test(data: &[u8], _out: Out) { fn build_response<'a>( offer: &'a Offer, pubkey: PublicKey -) -> Result, SemanticError> { +) -> Result, Bolt12SemanticError> { let mut builder = offer.request_invoice(vec![42; 64], pubkey)?; builder = match offer.amount() { None => builder.amount_msats(1000).unwrap(), Some(Amount::Bitcoin { amount_msats }) => builder.amount_msats(amount_msats + 1)?, - Some(Amount::Currency { .. }) => return Err(SemanticError::UnsupportedCurrency), + Some(Amount::Currency { .. }) => return Err(Bolt12SemanticError::UnsupportedCurrency), }; builder = match offer.supported_quantity() { diff --git a/fuzz/src/refund_deser.rs b/fuzz/src/refund_deser.rs index b1c729d9e5c..81b614d602b 100644 --- a/fuzz/src/refund_deser.rs +++ b/fuzz/src/refund_deser.rs @@ -15,7 +15,7 @@ use lightning::sign::EntropySource; use lightning::ln::PaymentHash; use lightning::ln::features::BlindedHopFeatures; use lightning::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice}; -use lightning::offers::parse::SemanticError; +use lightning::offers::parse::Bolt12SemanticError; use lightning::offers::refund::Refund; use lightning::util::ser::Writeable; @@ -60,7 +60,7 @@ fn privkey(byte: u8) -> SecretKey { fn build_response<'a, T: secp256k1::Signing + secp256k1::Verification>( refund: &'a Refund, signing_pubkey: PublicKey, secp_ctx: &Secp256k1 -) -> Result, SemanticError> { +) -> Result, Bolt12SemanticError> { let entropy_source = Randomness {}; let paths = vec![ BlindedPath::new_for_message(&[pubkey(43), pubkey(44), pubkey(42)], &entropy_source, secp_ctx).unwrap(), diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index 03bb9553625..279e31dd66a 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -112,7 +112,7 @@ use crate::ln::msgs::DecodeError; use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef}; use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TlvStream, WithoutSignatures, self}; use crate::offers::offer::{Amount, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef}; -use crate::offers::parse::{Bolt12ParseError, ParsedMessage, SemanticError}; +use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage}; use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef}; use crate::offers::refund::{IV_BYTES as REFUND_IV_BYTES, Refund, RefundContents}; use crate::offers::signer; @@ -168,7 +168,7 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> { pub(super) fn for_offer( invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration, payment_hash: PaymentHash - ) -> Result { + ) -> Result { let amount_msats = Self::check_amount_msats(invoice_request)?; let signing_pubkey = invoice_request.contents.inner.offer.signing_pubkey(); let contents = InvoiceContents::ForOffer { @@ -184,7 +184,7 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> { pub(super) fn for_refund( refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration, payment_hash: PaymentHash, signing_pubkey: PublicKey - ) -> Result { + ) -> Result { let amount_msats = refund.amount_msats(); let contents = InvoiceContents::ForRefund { refund: refund.contents.clone(), @@ -201,7 +201,7 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> { pub(super) fn for_offer_using_keys( invoice_request: &'a InvoiceRequest, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration, payment_hash: PaymentHash, keys: KeyPair - ) -> Result { + ) -> Result { let amount_msats = Self::check_amount_msats(invoice_request)?; let signing_pubkey = invoice_request.contents.inner.offer.signing_pubkey(); let contents = InvoiceContents::ForOffer { @@ -217,7 +217,7 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> { pub(super) fn for_refund_using_keys( refund: &'a Refund, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, created_at: Duration, payment_hash: PaymentHash, keys: KeyPair, - ) -> Result { + ) -> Result { let amount_msats = refund.amount_msats(); let signing_pubkey = keys.public_key(); let contents = InvoiceContents::ForRefund { @@ -232,16 +232,16 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> { } impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { - fn check_amount_msats(invoice_request: &InvoiceRequest) -> Result { + fn check_amount_msats(invoice_request: &InvoiceRequest) -> Result { match invoice_request.amount_msats() { Some(amount_msats) => Ok(amount_msats), None => match invoice_request.contents.inner.offer.amount() { Some(Amount::Bitcoin { amount_msats }) => { amount_msats.checked_mul(invoice_request.quantity().unwrap_or(1)) - .ok_or(SemanticError::InvalidAmount) + .ok_or(Bolt12SemanticError::InvalidAmount) }, - Some(Amount::Currency { .. }) => Err(SemanticError::UnsupportedCurrency), - None => Err(SemanticError::MissingAmount), + Some(Amount::Currency { .. }) => Err(Bolt12SemanticError::UnsupportedCurrency), + None => Err(Bolt12SemanticError::MissingAmount), }, } } @@ -258,9 +258,9 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { fn new( invreq_bytes: &'a Vec, contents: InvoiceContents, keys: Option - ) -> Result { + ) -> Result { if contents.fields().payment_paths.is_empty() { - return Err(SemanticError::MissingPaths); + return Err(Bolt12SemanticError::MissingPaths); } Ok(Self { @@ -331,10 +331,10 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> { impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> { /// Builds an unsigned [`Bolt12Invoice`] after checking for valid semantics. It can be signed by /// [`UnsignedBolt12Invoice::sign`]. - pub fn build(self) -> Result, SemanticError> { + pub fn build(self) -> Result, Bolt12SemanticError> { #[cfg(feature = "std")] { if self.invoice.is_offer_or_refund_expired() { - return Err(SemanticError::AlreadyExpired); + return Err(Bolt12SemanticError::AlreadyExpired); } } @@ -347,10 +347,10 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> { /// Builds a signed [`Bolt12Invoice`] after checking for valid semantics. pub fn build_and_sign( self, secp_ctx: &Secp256k1 - ) -> Result { + ) -> Result { #[cfg(feature = "std")] { if self.invoice.is_offer_or_refund_expired() { - return Err(SemanticError::AlreadyExpired); + return Err(Bolt12SemanticError::AlreadyExpired); } } @@ -853,7 +853,7 @@ impl TryFrom> for Bolt12Invoice { )?; let signature = match signature { - None => return Err(Bolt12ParseError::InvalidSemantics(SemanticError::MissingSignature)), + None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)), Some(signature) => signature, }; let pubkey = contents.fields().signing_pubkey; @@ -864,7 +864,7 @@ impl TryFrom> for Bolt12Invoice { } impl TryFrom for InvoiceContents { - type Error = SemanticError; + type Error = Bolt12SemanticError; fn try_from(tlv_stream: PartialInvoiceTlvStream) -> Result { let ( @@ -878,11 +878,11 @@ impl TryFrom for InvoiceContents { ) = tlv_stream; let payment_paths = match (blindedpay, paths) { - (_, None) => return Err(SemanticError::MissingPaths), - (None, _) => return Err(SemanticError::InvalidPayInfo), - (_, Some(paths)) if paths.is_empty() => return Err(SemanticError::MissingPaths), + (_, None) => return Err(Bolt12SemanticError::MissingPaths), + (None, _) => return Err(Bolt12SemanticError::InvalidPayInfo), + (_, Some(paths)) if paths.is_empty() => return Err(Bolt12SemanticError::MissingPaths), (Some(blindedpay), Some(paths)) if paths.len() != blindedpay.len() => { - return Err(SemanticError::InvalidPayInfo); + return Err(Bolt12SemanticError::InvalidPayInfo); }, (Some(blindedpay), Some(paths)) => { blindedpay.into_iter().zip(paths.into_iter()).collect::>() @@ -890,7 +890,7 @@ impl TryFrom for InvoiceContents { }; let created_at = match created_at { - None => return Err(SemanticError::MissingCreationTime), + None => return Err(Bolt12SemanticError::MissingCreationTime), Some(timestamp) => Duration::from_secs(timestamp), }; @@ -899,19 +899,19 @@ impl TryFrom for InvoiceContents { .map(Duration::from_secs); let payment_hash = match payment_hash { - None => return Err(SemanticError::MissingPaymentHash), + None => return Err(Bolt12SemanticError::MissingPaymentHash), Some(payment_hash) => payment_hash, }; let amount_msats = match amount { - None => return Err(SemanticError::MissingAmount), + None => return Err(Bolt12SemanticError::MissingAmount), Some(amount) => amount, }; let features = features.unwrap_or_else(Bolt12InvoiceFeatures::empty); let signing_pubkey = match node_id { - None => return Err(SemanticError::MissingSigningPubkey), + None => return Err(Bolt12SemanticError::MissingSigningPubkey), Some(node_id) => node_id, }; @@ -923,7 +923,7 @@ impl TryFrom for InvoiceContents { match offer_tlv_stream.node_id { Some(expected_signing_pubkey) => { if fields.signing_pubkey != expected_signing_pubkey { - return Err(SemanticError::InvalidSigningPubkey); + return Err(Bolt12SemanticError::InvalidSigningPubkey); } let invoice_request = InvoiceRequestContents::try_from( @@ -961,7 +961,7 @@ mod tests { use crate::offers::invoice_request::InvoiceRequestTlvStreamRef; use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self}; use crate::offers::offer::{OfferBuilder, OfferTlvStreamRef, Quantity}; - use crate::offers::parse::{Bolt12ParseError, SemanticError}; + use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError}; use crate::offers::payer::PayerTlvStreamRef; use crate::offers::refund::RefundBuilder; use crate::offers::test_utils::*; @@ -1180,7 +1180,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::AlreadyExpired), + Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired), } } @@ -1208,7 +1208,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::AlreadyExpired), + Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired), } } @@ -1253,7 +1253,7 @@ mod tests { payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx ) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InvalidMetadata), + Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata), } let desc = "foo".to_string(); @@ -1269,7 +1269,7 @@ mod tests { payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx ) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InvalidMetadata), + Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata), } } @@ -1376,7 +1376,7 @@ mod tests { .respond_with_no_std(payment_paths(), payment_hash(), now()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InvalidAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount), } } @@ -1502,7 +1502,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPaths)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)), } let mut tlv_stream = invoice.as_tlv_stream(); @@ -1510,7 +1510,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)), } let empty_payment_paths = vec![]; @@ -1519,7 +1519,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPaths)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaths)), } let mut payment_paths = payment_paths(); @@ -1529,7 +1529,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidPayInfo)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidPayInfo)), } } @@ -1558,7 +1558,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingCreationTime)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingCreationTime)); }, } } @@ -1610,7 +1610,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPaymentHash)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPaymentHash)); }, } } @@ -1639,7 +1639,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)), } } @@ -1758,7 +1758,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey)); }, } @@ -1769,7 +1769,7 @@ mod tests { match Bolt12Invoice::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidSigningPubkey)); }, } } @@ -1790,7 +1790,7 @@ mod tests { match Bolt12Invoice::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSignature)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)), } } diff --git a/lightning/src/offers/invoice_error.rs b/lightning/src/offers/invoice_error.rs index 7345bc14d69..122049b9295 100644 --- a/lightning/src/offers/invoice_error.rs +++ b/lightning/src/offers/invoice_error.rs @@ -11,7 +11,7 @@ use crate::io; use crate::ln::msgs::DecodeError; -use crate::offers::parse::SemanticError; +use crate::offers::parse::Bolt12SemanticError; use crate::util::ser::{HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer}; use crate::util::string::UntrustedString; @@ -93,8 +93,8 @@ impl Readable for InvoiceError { } } -impl From for InvoiceError { - fn from(error: SemanticError) -> Self { +impl From for InvoiceError { + fn from(error: Bolt12SemanticError) -> Self { InvoiceError { erroneous_field: None, message: UntrustedString(format!("{:?}", error)), diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index 6c70a5968eb..f014bf12002 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -68,7 +68,7 @@ use crate::ln::msgs::DecodeError; use crate::offers::invoice::{BlindedPayInfo, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder}; use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, self}; use crate::offers::offer::{Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef}; -use crate::offers::parse::{Bolt12ParseError, ParsedMessage, SemanticError}; +use crate::offers::parse::{Bolt12ParseError, ParsedMessage, Bolt12SemanticError}; use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef}; use crate::offers::signer::{Metadata, MetadataMaterial}; use crate::util::ser::{HighZeroBytesDroppedBigSize, SeekReadable, WithoutLength, Writeable, Writer}; @@ -171,10 +171,10 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a /// by the offer. /// /// Successive calls to this method will override the previous setting. - pub fn chain(mut self, network: Network) -> Result { + pub fn chain(mut self, network: Network) -> Result { let chain = ChainHash::using_genesis_block(network); if !self.offer.supports_chain(chain) { - return Err(SemanticError::UnsupportedChain); + return Err(Bolt12SemanticError::UnsupportedChain); } self.invoice_request.chain = Some(chain); @@ -187,7 +187,7 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a /// Successive calls to this method will override the previous setting. /// /// [`quantity`]: Self::quantity - pub fn amount_msats(mut self, amount_msats: u64) -> Result { + pub fn amount_msats(mut self, amount_msats: u64) -> Result { self.invoice_request.offer.check_amount_msats_for_quantity( Some(amount_msats), self.invoice_request.quantity )?; @@ -199,7 +199,7 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a /// does not conform to [`Offer::is_valid_quantity`]. /// /// Successive calls to this method will override the previous setting. - pub fn quantity(mut self, quantity: u64) -> Result { + pub fn quantity(mut self, quantity: u64) -> Result { self.invoice_request.offer.check_quantity(Some(quantity))?; self.invoice_request.quantity = Some(quantity); Ok(self) @@ -215,17 +215,17 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a fn build_with_checks(mut self) -> Result< (UnsignedInvoiceRequest<'a>, Option, Option<&'b Secp256k1>), - SemanticError + Bolt12SemanticError > { #[cfg(feature = "std")] { if self.offer.is_expired() { - return Err(SemanticError::AlreadyExpired); + return Err(Bolt12SemanticError::AlreadyExpired); } } let chain = self.invoice_request.chain(); if !self.offer.supports_chain(chain) { - return Err(SemanticError::UnsupportedChain); + return Err(Bolt12SemanticError::UnsupportedChain); } if chain == self.offer.implied_chain() { @@ -233,7 +233,7 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a } if self.offer.amount().is_none() && self.invoice_request.amount_msats.is_none() { - return Err(SemanticError::MissingAmount); + return Err(Bolt12SemanticError::MissingAmount); } self.invoice_request.offer.check_quantity(self.invoice_request.quantity)?; @@ -290,7 +290,7 @@ impl<'a, 'b, P: PayerIdStrategy, T: secp256k1::Signing> InvoiceRequestBuilder<'a impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, ExplicitPayerId, T> { /// Builds an unsigned [`InvoiceRequest`] after checking for valid semantics. It can be signed /// by [`UnsignedInvoiceRequest::sign`]. - pub fn build(self) -> Result, SemanticError> { + pub fn build(self) -> Result, Bolt12SemanticError> { let (unsigned_invoice_request, keys, _) = self.build_with_checks()?; debug_assert!(keys.is_none()); Ok(unsigned_invoice_request) @@ -299,7 +299,7 @@ impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, ExplicitPayerI impl<'a, 'b, T: secp256k1::Signing> InvoiceRequestBuilder<'a, 'b, DerivedPayerId, T> { /// Builds a signed [`InvoiceRequest`] after checking for valid semantics. - pub fn build_and_sign(self) -> Result { + pub fn build_and_sign(self) -> Result { let (unsigned_invoice_request, keys, secp_ctx) = self.build_with_checks()?; debug_assert!(keys.is_some()); @@ -481,7 +481,7 @@ impl InvoiceRequest { #[cfg(feature = "std")] pub fn respond_with( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash - ) -> Result, SemanticError> { + ) -> Result, Bolt12SemanticError> { let created_at = std::time::SystemTime::now() .duration_since(std::time::SystemTime::UNIX_EPOCH) .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"); @@ -511,9 +511,9 @@ impl InvoiceRequest { pub fn respond_with_no_std( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, created_at: core::time::Duration - ) -> Result, SemanticError> { + ) -> Result, Bolt12SemanticError> { if self.features().requires_unknown_bits() { - return Err(SemanticError::UnknownRequiredFeatures); + return Err(Bolt12SemanticError::UnknownRequiredFeatures); } InvoiceBuilder::for_offer(self, payment_paths, created_at, payment_hash) @@ -532,7 +532,7 @@ impl InvoiceRequest { pub fn verify_and_respond_using_derived_keys( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, expanded_key: &ExpandedKey, secp_ctx: &Secp256k1 - ) -> Result, SemanticError> { + ) -> Result, Bolt12SemanticError> { let created_at = std::time::SystemTime::now() .duration_since(std::time::SystemTime::UNIX_EPOCH) .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"); @@ -554,14 +554,14 @@ impl InvoiceRequest { pub fn verify_and_respond_using_derived_keys_no_std( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, created_at: core::time::Duration, expanded_key: &ExpandedKey, secp_ctx: &Secp256k1 - ) -> Result, SemanticError> { + ) -> Result, Bolt12SemanticError> { if self.features().requires_unknown_bits() { - return Err(SemanticError::UnknownRequiredFeatures); + return Err(Bolt12SemanticError::UnknownRequiredFeatures); } let keys = match self.verify(expanded_key, secp_ctx) { - Err(()) => return Err(SemanticError::InvalidMetadata), - Ok(None) => return Err(SemanticError::InvalidMetadata), + Err(()) => return Err(Bolt12SemanticError::InvalidMetadata), + Ok(None) => return Err(Bolt12SemanticError::InvalidMetadata), Ok(Some(keys)) => keys, }; @@ -722,7 +722,7 @@ impl TryFrom> for InvoiceRequest { )?; let signature = match signature { - None => return Err(Bolt12ParseError::InvalidSemantics(SemanticError::MissingSignature)), + None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)), Some(signature) => signature, }; merkle::verify_signature(&signature, SIGNATURE_TAG, &bytes, contents.payer_id)?; @@ -732,7 +732,7 @@ impl TryFrom> for InvoiceRequest { } impl TryFrom for InvoiceRequestContents { - type Error = SemanticError; + type Error = Bolt12SemanticError; fn try_from(tlv_stream: PartialInvoiceRequestTlvStream) -> Result { let ( @@ -742,17 +742,17 @@ impl TryFrom for InvoiceRequestContents { ) = tlv_stream; let payer = match metadata { - None => return Err(SemanticError::MissingPayerMetadata), + None => return Err(Bolt12SemanticError::MissingPayerMetadata), Some(metadata) => PayerContents(Metadata::Bytes(metadata)), }; let offer = OfferContents::try_from(offer_tlv_stream)?; if !offer.supports_chain(chain.unwrap_or_else(|| offer.implied_chain())) { - return Err(SemanticError::UnsupportedChain); + return Err(Bolt12SemanticError::UnsupportedChain); } if offer.amount().is_none() && amount.is_none() { - return Err(SemanticError::MissingAmount); + return Err(Bolt12SemanticError::MissingAmount); } offer.check_quantity(quantity)?; @@ -761,7 +761,7 @@ impl TryFrom for InvoiceRequestContents { let features = features.unwrap_or_else(InvoiceRequestFeatures::empty); let payer_id = match payer_id { - None => return Err(SemanticError::MissingPayerId), + None => return Err(Bolt12SemanticError::MissingPayerId), Some(payer_id) => payer_id, }; @@ -792,7 +792,7 @@ mod tests { use crate::offers::invoice::{Bolt12Invoice, SIGNATURE_TAG as INVOICE_SIGNATURE_TAG}; use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self}; use crate::offers::offer::{Amount, OfferBuilder, OfferTlvStreamRef, Quantity}; - use crate::offers::parse::{Bolt12ParseError, SemanticError}; + use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError}; use crate::offers::payer::PayerTlvStreamRef; use crate::offers::test_utils::*; use crate::util::ser::{BigSize, Writeable}; @@ -882,7 +882,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::AlreadyExpired), + Err(e) => assert_eq!(e, Bolt12SemanticError::AlreadyExpired), } } @@ -1091,7 +1091,7 @@ mod tests { .chain(Network::Bitcoin) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::UnsupportedChain), + Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain), } match OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1102,7 +1102,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::UnsupportedChain), + Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedChain), } } @@ -1149,7 +1149,7 @@ mod tests { .amount_msats(999) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InsufficientAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount), } match OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1161,7 +1161,7 @@ mod tests { .amount_msats(1000) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InsufficientAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount), } match OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1171,7 +1171,7 @@ mod tests { .amount_msats(MAX_VALUE_MSAT + 1) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InvalidAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount), } match OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1184,7 +1184,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InsufficientAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::InsufficientAmount), } match OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1193,7 +1193,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::MissingAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::MissingAmount), } match OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1205,7 +1205,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InvalidAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount), } } @@ -1260,7 +1260,7 @@ mod tests { .quantity(2) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::UnexpectedQuantity), + Err(e) => assert_eq!(e, Bolt12SemanticError::UnexpectedQuantity), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1285,7 +1285,7 @@ mod tests { .quantity(11) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InvalidQuantity), + Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidQuantity), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1309,7 +1309,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::MissingQuantity), + Err(e) => assert_eq!(e, Bolt12SemanticError::MissingQuantity), } match OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1320,7 +1320,7 @@ mod tests { .build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::MissingQuantity), + Err(e) => assert_eq!(e, Bolt12SemanticError::MissingQuantity), } } @@ -1387,7 +1387,7 @@ mod tests { .respond_with_no_std(payment_paths(), payment_hash(), now()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::UnknownRequiredFeatures), + Err(e) => assert_eq!(e, Bolt12SemanticError::UnknownRequiredFeatures), } } @@ -1438,7 +1438,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnsupportedChain)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnsupportedChain)), } } @@ -1483,7 +1483,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1499,7 +1499,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InsufficientAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InsufficientAmount)), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1515,7 +1515,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnsupportedCurrency)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnsupportedCurrency)); }, } @@ -1533,7 +1533,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)), } } @@ -1573,7 +1573,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedQuantity)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedQuantity)); }, } @@ -1609,7 +1609,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidQuantity)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidQuantity)), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1642,7 +1642,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingQuantity)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingQuantity)), } let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) @@ -1658,7 +1658,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingQuantity)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingQuantity)), } } @@ -1678,7 +1678,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPayerMetadata)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPayerMetadata)); }, } } @@ -1698,7 +1698,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPayerId)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPayerId)), } } @@ -1718,7 +1718,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey)); }, } } @@ -1736,7 +1736,7 @@ mod tests { match InvoiceRequest::try_from(buffer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSignature)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)), } } diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 1168aff9432..d801be9d26f 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -82,7 +82,7 @@ use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce}; use crate::ln::msgs::MAX_VALUE_MSAT; use crate::offers::invoice_request::{DerivedPayerId, ExplicitPayerId, InvoiceRequestBuilder}; use crate::offers::merkle::TlvStream; -use crate::offers::parse::{Bech32Encode, Bolt12ParseError, ParsedMessage, SemanticError}; +use crate::offers::parse::{Bech32Encode, Bolt12ParseError, Bolt12SemanticError, ParsedMessage}; use crate::offers::signer::{Metadata, MetadataMaterial, self}; use crate::util::ser::{HighZeroBytesDroppedBigSize, WithoutLength, Writeable, Writer}; use crate::util::string::PrintableString; @@ -146,7 +146,7 @@ impl<'a> OfferBuilder<'a, ExplicitMetadata, secp256k1::SignOnly> { /// Sets the [`Offer::metadata`] to the given bytes. /// /// Successive calls to this method will override the previous setting. - pub fn metadata(mut self, metadata: Vec) -> Result { + pub fn metadata(mut self, metadata: Vec) -> Result { self.offer.metadata = Some(Metadata::Bytes(metadata)); Ok(self) } @@ -252,14 +252,14 @@ impl<'a, M: MetadataStrategy, T: secp256k1::Signing> OfferBuilder<'a, M, T> { } /// Builds an [`Offer`] from the builder's settings. - pub fn build(mut self) -> Result { + pub fn build(mut self) -> Result { match self.offer.amount { Some(Amount::Bitcoin { amount_msats }) => { if amount_msats > MAX_VALUE_MSAT { - return Err(SemanticError::InvalidAmount); + return Err(Bolt12SemanticError::InvalidAmount); } }, - Some(Amount::Currency { .. }) => return Err(SemanticError::UnsupportedCurrency), + Some(Amount::Currency { .. }) => return Err(Bolt12SemanticError::UnsupportedCurrency), None => {}, } @@ -465,12 +465,12 @@ impl Offer { /// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey pub fn request_invoice_deriving_payer_id<'a, 'b, ES: Deref, T: secp256k1::Signing>( &'a self, expanded_key: &ExpandedKey, entropy_source: ES, secp_ctx: &'b Secp256k1 - ) -> Result, SemanticError> + ) -> Result, Bolt12SemanticError> where ES::Target: EntropySource, { if self.features().requires_unknown_bits() { - return Err(SemanticError::UnknownRequiredFeatures); + return Err(Bolt12SemanticError::UnknownRequiredFeatures); } Ok(InvoiceRequestBuilder::deriving_payer_id(self, expanded_key, entropy_source, secp_ctx)) @@ -486,12 +486,12 @@ impl Offer { /// [`InvoiceRequest::payer_id`]: crate::offers::invoice_request::InvoiceRequest::payer_id pub fn request_invoice_deriving_metadata( &self, payer_id: PublicKey, expanded_key: &ExpandedKey, entropy_source: ES - ) -> Result, SemanticError> + ) -> Result, Bolt12SemanticError> where ES::Target: EntropySource, { if self.features().requires_unknown_bits() { - return Err(SemanticError::UnknownRequiredFeatures); + return Err(Bolt12SemanticError::UnknownRequiredFeatures); } Ok(InvoiceRequestBuilder::deriving_metadata(self, payer_id, expanded_key, entropy_source)) @@ -514,9 +514,9 @@ impl Offer { /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest pub fn request_invoice( &self, metadata: Vec, payer_id: PublicKey - ) -> Result, SemanticError> { + ) -> Result, Bolt12SemanticError> { if self.features().requires_unknown_bits() { - return Err(SemanticError::UnknownRequiredFeatures); + return Err(Bolt12SemanticError::UnknownRequiredFeatures); } Ok(InvoiceRequestBuilder::new(self, metadata, payer_id)) @@ -572,24 +572,24 @@ impl OfferContents { pub(super) fn check_amount_msats_for_quantity( &self, amount_msats: Option, quantity: Option - ) -> Result<(), SemanticError> { + ) -> Result<(), Bolt12SemanticError> { let offer_amount_msats = match self.amount { None => 0, Some(Amount::Bitcoin { amount_msats }) => amount_msats, - Some(Amount::Currency { .. }) => return Err(SemanticError::UnsupportedCurrency), + Some(Amount::Currency { .. }) => return Err(Bolt12SemanticError::UnsupportedCurrency), }; if !self.expects_quantity() || quantity.is_some() { let expected_amount_msats = offer_amount_msats.checked_mul(quantity.unwrap_or(1)) - .ok_or(SemanticError::InvalidAmount)?; + .ok_or(Bolt12SemanticError::InvalidAmount)?; let amount_msats = amount_msats.unwrap_or(expected_amount_msats); if amount_msats < expected_amount_msats { - return Err(SemanticError::InsufficientAmount); + return Err(Bolt12SemanticError::InsufficientAmount); } if amount_msats > MAX_VALUE_MSAT { - return Err(SemanticError::InvalidAmount); + return Err(Bolt12SemanticError::InvalidAmount); } } @@ -600,13 +600,13 @@ impl OfferContents { self.supported_quantity } - pub(super) fn check_quantity(&self, quantity: Option) -> Result<(), SemanticError> { + pub(super) fn check_quantity(&self, quantity: Option) -> Result<(), Bolt12SemanticError> { let expects_quantity = self.expects_quantity(); match quantity { - None if expects_quantity => Err(SemanticError::MissingQuantity), - Some(_) if !expects_quantity => Err(SemanticError::UnexpectedQuantity), + None if expects_quantity => Err(Bolt12SemanticError::MissingQuantity), + Some(_) if !expects_quantity => Err(Bolt12SemanticError::UnexpectedQuantity), Some(quantity) if !self.is_valid_quantity(quantity) => { - Err(SemanticError::InvalidQuantity) + Err(Bolt12SemanticError::InvalidQuantity) }, _ => Ok(()), } @@ -787,7 +787,7 @@ impl TryFrom> for Offer { } impl TryFrom for OfferContents { - type Error = SemanticError; + type Error = Bolt12SemanticError; fn try_from(tlv_stream: OfferTlvStream) -> Result { let OfferTlvStream { @@ -800,15 +800,15 @@ impl TryFrom for OfferContents { let amount = match (currency, amount) { (None, None) => None, (None, Some(amount_msats)) if amount_msats > MAX_VALUE_MSAT => { - return Err(SemanticError::InvalidAmount); + return Err(Bolt12SemanticError::InvalidAmount); }, (None, Some(amount_msats)) => Some(Amount::Bitcoin { amount_msats }), - (Some(_), None) => return Err(SemanticError::MissingAmount), + (Some(_), None) => return Err(Bolt12SemanticError::MissingAmount), (Some(iso4217_code), Some(amount)) => Some(Amount::Currency { iso4217_code, amount }), }; let description = match description { - None => return Err(SemanticError::MissingDescription), + None => return Err(Bolt12SemanticError::MissingDescription), Some(description) => description, }; @@ -824,7 +824,7 @@ impl TryFrom for OfferContents { }; let signing_pubkey = match node_id { - None => return Err(SemanticError::MissingSigningPubkey), + None => return Err(Bolt12SemanticError::MissingSigningPubkey), Some(node_id) => node_id, }; @@ -856,7 +856,7 @@ mod tests { use crate::ln::features::OfferFeatures; use crate::ln::inbound_payment::ExpandedKey; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; - use crate::offers::parse::{Bolt12ParseError, SemanticError}; + use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError}; use crate::offers::test_utils::*; use crate::util::ser::{BigSize, Writeable}; use crate::util::string::PrintableString; @@ -1090,7 +1090,7 @@ mod tests { assert_eq!(tlv_stream.currency, Some(b"USD")); match builder.build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::UnsupportedCurrency), + Err(e) => assert_eq!(e, Bolt12SemanticError::UnsupportedCurrency), } let offer = OfferBuilder::new("foo".into(), pubkey(42)) @@ -1105,7 +1105,7 @@ mod tests { let invalid_amount = Amount::Bitcoin { amount_msats: MAX_VALUE_MSAT + 1 }; match OfferBuilder::new("foo".into(), pubkey(42)).amount(invalid_amount).build() { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InvalidAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount), } } @@ -1259,7 +1259,7 @@ mod tests { .request_invoice(vec![1; 32], pubkey(43)) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::UnknownRequiredFeatures), + Err(e) => assert_eq!(e, Bolt12SemanticError::UnknownRequiredFeatures), } } @@ -1305,7 +1305,7 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)), } let mut tlv_stream = offer.as_tlv_stream(); @@ -1317,7 +1317,7 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidAmount)), + Err(e) => assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)), } } @@ -1337,7 +1337,7 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingDescription)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingDescription)); }, } } @@ -1427,7 +1427,7 @@ mod tests { match Offer::try_from(encoded_offer) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSigningPubkey)); }, } } diff --git a/lightning/src/offers/parse.rs b/lightning/src/offers/parse.rs index 064604f3afb..b722499f251 100644 --- a/lightning/src/offers/parse.rs +++ b/lightning/src/offers/parse.rs @@ -129,16 +129,14 @@ pub enum Bolt12ParseError { /// The bech32 decoded string could not be decoded as the expected message type. Decode(DecodeError), /// The parsed message has invalid semantics. - InvalidSemantics(SemanticError), + InvalidSemantics(Bolt12SemanticError), /// The parsed message has an invalid signature. InvalidSignature(secp256k1::Error), } /// Error when interpreting a TLV stream as a specific type. -/// -/// This is not exported to bindings users as its name conflicts with the BOLT 11 SemanticError type. #[derive(Debug, PartialEq)] -pub enum SemanticError { +pub enum Bolt12SemanticError { /// The current [`std::time::SystemTime`] is past the offer or invoice's expiration. AlreadyExpired, /// The provided chain hash does not correspond to a supported chain. @@ -205,8 +203,8 @@ impl From for Bolt12ParseError { } } -impl From for Bolt12ParseError { - fn from(error: SemanticError) -> Self { +impl From for Bolt12ParseError { + fn from(error: Bolt12SemanticError) -> Self { Self::InvalidSemantics(error) } } diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index aea5e49a3c8..2c8dffeb151 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -88,7 +88,7 @@ use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; use crate::offers::invoice::{BlindedPayInfo, DerivedSigningPubkey, ExplicitSigningPubkey, InvoiceBuilder}; use crate::offers::invoice_request::{InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef}; use crate::offers::offer::{OfferTlvStream, OfferTlvStreamRef}; -use crate::offers::parse::{Bech32Encode, Bolt12ParseError, ParsedMessage, SemanticError}; +use crate::offers::parse::{Bech32Encode, Bolt12ParseError, Bolt12SemanticError, ParsedMessage}; use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef}; use crate::offers::signer::{Metadata, MetadataMaterial, self}; use crate::util::ser::{SeekReadable, WithoutLength, Writeable, Writer}; @@ -121,9 +121,9 @@ impl<'a> RefundBuilder<'a, secp256k1::SignOnly> { /// [`Refund::amount_msats`]. pub fn new( description: String, metadata: Vec, payer_id: PublicKey, amount_msats: u64 - ) -> Result { + ) -> Result { if amount_msats > MAX_VALUE_MSAT { - return Err(SemanticError::InvalidAmount); + return Err(Bolt12SemanticError::InvalidAmount); } let metadata = Metadata::Bytes(metadata); @@ -152,9 +152,9 @@ impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> { pub fn deriving_payer_id( description: String, node_id: PublicKey, expanded_key: &ExpandedKey, entropy_source: ES, secp_ctx: &'a Secp256k1, amount_msats: u64 - ) -> Result where ES::Target: EntropySource { + ) -> Result where ES::Target: EntropySource { if amount_msats > MAX_VALUE_MSAT { - return Err(SemanticError::InvalidAmount); + return Err(Bolt12SemanticError::InvalidAmount); } let nonce = Nonce::from_entropy_source(entropy_source); @@ -229,7 +229,7 @@ impl<'a, T: secp256k1::Signing> RefundBuilder<'a, T> { } /// Builds a [`Refund`] after checking for valid semantics. - pub fn build(mut self) -> Result { + pub fn build(mut self) -> Result { if self.refund.chain() == self.refund.implied_chain() { self.refund.chain = None; } @@ -396,7 +396,7 @@ impl Refund { pub fn respond_with( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, signing_pubkey: PublicKey, - ) -> Result, SemanticError> { + ) -> Result, Bolt12SemanticError> { let created_at = std::time::SystemTime::now() .duration_since(std::time::SystemTime::UNIX_EPOCH) .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH"); @@ -429,9 +429,9 @@ impl Refund { pub fn respond_with_no_std( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, signing_pubkey: PublicKey, created_at: Duration - ) -> Result, SemanticError> { + ) -> Result, Bolt12SemanticError> { if self.features().requires_unknown_bits() { - return Err(SemanticError::UnknownRequiredFeatures); + return Err(Bolt12SemanticError::UnknownRequiredFeatures); } InvoiceBuilder::for_refund(self, payment_paths, created_at, payment_hash, signing_pubkey) @@ -449,7 +449,7 @@ impl Refund { pub fn respond_using_derived_keys( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, expanded_key: &ExpandedKey, entropy_source: ES - ) -> Result, SemanticError> + ) -> Result, Bolt12SemanticError> where ES::Target: EntropySource, { @@ -473,12 +473,12 @@ impl Refund { pub fn respond_using_derived_keys_no_std( &self, payment_paths: Vec<(BlindedPayInfo, BlindedPath)>, payment_hash: PaymentHash, created_at: core::time::Duration, expanded_key: &ExpandedKey, entropy_source: ES - ) -> Result, SemanticError> + ) -> Result, Bolt12SemanticError> where ES::Target: EntropySource, { if self.features().requires_unknown_bits() { - return Err(SemanticError::UnknownRequiredFeatures); + return Err(Bolt12SemanticError::UnknownRequiredFeatures); } let nonce = Nonce::from_entropy_source(entropy_source); @@ -626,7 +626,7 @@ impl TryFrom> for Refund { } impl TryFrom for RefundContents { - type Error = SemanticError; + type Error = Bolt12SemanticError; fn try_from(tlv_stream: RefundTlvStream) -> Result { let ( @@ -639,45 +639,45 @@ impl TryFrom for RefundContents { ) = tlv_stream; let payer = match payer_metadata { - None => return Err(SemanticError::MissingPayerMetadata), + None => return Err(Bolt12SemanticError::MissingPayerMetadata), Some(metadata) => PayerContents(Metadata::Bytes(metadata)), }; if metadata.is_some() { - return Err(SemanticError::UnexpectedMetadata); + return Err(Bolt12SemanticError::UnexpectedMetadata); } if chains.is_some() { - return Err(SemanticError::UnexpectedChain); + return Err(Bolt12SemanticError::UnexpectedChain); } if currency.is_some() || offer_amount.is_some() { - return Err(SemanticError::UnexpectedAmount); + return Err(Bolt12SemanticError::UnexpectedAmount); } let description = match description { - None => return Err(SemanticError::MissingDescription), + None => return Err(Bolt12SemanticError::MissingDescription), Some(description) => description, }; if offer_features.is_some() { - return Err(SemanticError::UnexpectedFeatures); + return Err(Bolt12SemanticError::UnexpectedFeatures); } let absolute_expiry = absolute_expiry.map(Duration::from_secs); if quantity_max.is_some() { - return Err(SemanticError::UnexpectedQuantity); + return Err(Bolt12SemanticError::UnexpectedQuantity); } if node_id.is_some() { - return Err(SemanticError::UnexpectedSigningPubkey); + return Err(Bolt12SemanticError::UnexpectedSigningPubkey); } let amount_msats = match amount { - None => return Err(SemanticError::MissingAmount), + None => return Err(Bolt12SemanticError::MissingAmount), Some(amount_msats) if amount_msats > MAX_VALUE_MSAT => { - return Err(SemanticError::InvalidAmount); + return Err(Bolt12SemanticError::InvalidAmount); }, Some(amount_msats) => amount_msats, }; @@ -685,7 +685,7 @@ impl TryFrom for RefundContents { let features = features.unwrap_or_else(InvoiceRequestFeatures::empty); let payer_id = match payer_id { - None => return Err(SemanticError::MissingPayerId), + None => return Err(Bolt12SemanticError::MissingPayerId), Some(payer_id) => payer_id, }; @@ -718,7 +718,7 @@ mod tests { use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; use crate::offers::invoice_request::InvoiceRequestTlvStreamRef; use crate::offers::offer::OfferTlvStreamRef; - use crate::offers::parse::{Bolt12ParseError, SemanticError}; + use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError}; use crate::offers::payer::PayerTlvStreamRef; use crate::offers::test_utils::*; use crate::util::ser::{BigSize, Writeable}; @@ -795,7 +795,7 @@ mod tests { fn fails_building_refund_with_invalid_amount() { match RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), MAX_VALUE_MSAT + 1) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::InvalidAmount), + Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidAmount), } } @@ -1064,7 +1064,7 @@ mod tests { .respond_with_no_std(payment_paths(), payment_hash(), recipient_pubkey(), now()) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SemanticError::UnknownRequiredFeatures), + Err(e) => assert_eq!(e, Bolt12SemanticError::UnknownRequiredFeatures), } } @@ -1082,7 +1082,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPayerMetadata)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPayerMetadata)); }, } } @@ -1101,7 +1101,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingDescription)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingDescription)); }, } } @@ -1120,7 +1120,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingAmount)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingAmount)); }, } @@ -1130,7 +1130,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::InvalidAmount)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::InvalidAmount)); }, } } @@ -1149,7 +1149,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::MissingPayerId)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingPayerId)); }, } } @@ -1218,7 +1218,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedMetadata)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedMetadata)); }, } @@ -1229,7 +1229,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedChain)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedChain)); }, } @@ -1240,7 +1240,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedAmount)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedAmount)); }, } @@ -1251,7 +1251,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedFeatures)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedFeatures)); }, } @@ -1261,7 +1261,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedQuantity)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedQuantity)); }, } @@ -1272,7 +1272,7 @@ mod tests { match Refund::try_from(tlv_stream.to_bytes()) { Ok(_) => panic!("expected error"), Err(e) => { - assert_eq!(e, Bolt12ParseError::InvalidSemantics(SemanticError::UnexpectedSigningPubkey)); + assert_eq!(e, Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::UnexpectedSigningPubkey)); }, } } From 93ead4aec5695216525234acceb442ecedf9912d Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 13 Jul 2023 17:22:26 -0500 Subject: [PATCH 07/13] Qualify the BOLT 11 invoice type A previous commit qualified the BOLT 12 invoice type. Qualify the BOLT 11 invoice type for consistency. --- lightning-invoice/src/de.rs | 14 +++--- lightning-invoice/src/lib.rs | 82 +++++++++++++++---------------- lightning-invoice/src/payment.rs | 43 ++++++++-------- lightning-invoice/src/ser.rs | 4 +- lightning-invoice/src/utils.rs | 26 +++++----- lightning-invoice/tests/ser_de.rs | 18 +++---- 6 files changed, 94 insertions(+), 93 deletions(-) diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs index 01adf67d1af..2e638ff14cb 100644 --- a/lightning-invoice/src/de.rs +++ b/lightning-invoice/src/de.rs @@ -23,7 +23,7 @@ use num_traits::{CheckedAdd, CheckedMul}; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use secp256k1::PublicKey; -use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, +use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, SemanticError, PrivateRoute, ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice, constants, SignedRawInvoice, RawDataPart, InvoiceFeatures}; @@ -210,7 +210,7 @@ impl FromStr for SiPrefix { } /// ``` -/// use lightning_invoice::Invoice; +/// use lightning_invoice::Bolt11Invoice; /// /// /// let invoice = "lnbc100p1psj9jhxdqud3jxktt5w46x7unfv9kz6mn0v3jsnp4q0d3p2sfluzdx45tqcs\ @@ -225,14 +225,14 @@ impl FromStr for SiPrefix { /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\ /// j5r6drg6k6zcqj0fcwg"; /// -/// assert!(invoice.parse::().is_ok()); +/// assert!(invoice.parse::().is_ok()); /// ``` -impl FromStr for Invoice { +impl FromStr for Bolt11Invoice { type Err = ParseOrSemanticError; fn from_str(s: &str) -> Result::Err> { let signed = s.parse::()?; - Ok(Invoice::from_signed(signed)?) + Ok(Bolt11Invoice::from_signed(signed)?) } } @@ -251,10 +251,10 @@ impl FromStr for Invoice { /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\ /// j5r6drg6k6zcqj0fcwg"; /// -/// let parsed_1 = invoice.parse::(); +/// let parsed_1 = invoice.parse::(); /// /// let parsed_2 = match invoice.parse::() { -/// Ok(signed) => match Invoice::from_signed(signed) { +/// Ok(signed) => match Bolt11Invoice::from_signed(signed) { /// Ok(invoice) => Ok(invoice), /// Err(e) => Err(ParseOrSemanticError::SemanticError(e)), /// }, diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 454a67f6352..94566ba7378 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -18,11 +18,11 @@ //! invoices and functions to create, encode and decode these. If you just want to use the standard //! en-/decoding functionality this should get you started: //! -//! * For parsing use `str::parse::(&self)` (see [`Invoice::from_str`]) +//! * For parsing use `str::parse::(&self)` (see [`Bolt11Invoice::from_str`]) //! * For constructing invoices use the [`InvoiceBuilder`] //! * For serializing invoices use the [`Display`]/[`ToString`] traits //! -//! [`Invoice::from_str`]: crate::Invoice#impl-FromStr +//! [`Bolt11Invoice::from_str`]: crate::Bolt11Invoice#impl-FromStr #[cfg(not(any(feature = "std", feature = "no-std")))] compile_error!("at least one of the `std` or `no-std` features must be enabled"); @@ -164,8 +164,8 @@ pub const DEFAULT_EXPIRY_TIME: u64 = 3600; /// [`MIN_FINAL_CLTV_EXPIRY_DELTA`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18; -/// Builder for [`Invoice`]s. It's the most convenient and advised way to use this library. It ensures -/// that only a semantically and syntactically correct Invoice can be built using it. +/// Builder for [`Bolt11Invoice`]s. It's the most convenient and advised way to use this library. It +/// ensures that only a semantically and syntactically correct invoice can be built using it. /// /// ``` /// extern crate secp256k1; @@ -243,14 +243,14 @@ pub struct InvoiceBuilder(&str)` (see [`Invoice::from_str`]) +/// 2. using [`Bolt11Invoice::from_signed`] +/// 3. using `str::parse::(&str)` (see [`Bolt11Invoice::from_str`]) /// -/// [`Invoice::from_str`]: crate::Invoice#impl-FromStr +/// [`Bolt11Invoice::from_str`]: crate::Bolt11Invoice#impl-FromStr #[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)] -pub struct Invoice { +pub struct Bolt11Invoice { signed_invoice: SignedRawInvoice, } @@ -291,11 +291,11 @@ pub struct SignedRawInvoice { signature: InvoiceSignature, } -/// Represents an syntactically correct [`Invoice`] for a payment on the lightning network, +/// Represents an syntactically correct [`Bolt11Invoice`] for a payment on the lightning network, /// but without the signature information. /// Decoding and encoding should not lead to information loss but may lead to different hashes. /// -/// For methods without docs see the corresponding methods in [`Invoice`]. +/// For methods without docs see the corresponding methods in [`Bolt11Invoice`]. #[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)] pub struct RawInvoice { /// human readable part @@ -807,7 +807,7 @@ impl InvoiceBuilder(self, sign_function: F) -> Result + pub fn build_signed(self, sign_function: F) -> Result where F: FnOnce(&Message) -> RecoverableSignature { let invoice = self.try_build_signed::<_, ()>(|hash| { @@ -824,7 +824,7 @@ impl InvoiceBuilder(self, sign_function: F) -> Result> + pub fn try_build_signed(self, sign_function: F) -> Result> where F: FnOnce(&Message) -> Result { let raw = match self.build_raw() { @@ -837,7 +837,7 @@ impl InvoiceBuilder return Err(SignOrCreationError::SignError(e)), }; - let invoice = Invoice { + let invoice = Bolt11Invoice { signed_invoice: signed, }; @@ -1142,13 +1142,13 @@ impl From for SystemTime { } } -impl Invoice { +impl Bolt11Invoice { /// The hash of the [`RawInvoice`] that was signed. pub fn signable_hash(&self) -> [u8; 32] { self.signed_invoice.hash } - /// Transform the `Invoice` into its unchecked version. + /// Transform the `Bolt11Invoice` into its unchecked version. pub fn into_signed_raw(self) -> SignedRawInvoice { self.signed_invoice } @@ -1252,7 +1252,7 @@ impl Invoice { Ok(()) } - /// Constructs an `Invoice` from a [`SignedRawInvoice`] by checking all its invariants. + /// Constructs a `Bolt11Invoice` from a [`SignedRawInvoice`] by checking all its invariants. /// ``` /// use lightning_invoice::*; /// @@ -1270,10 +1270,10 @@ impl Invoice { /// /// let signed = invoice.parse::().unwrap(); /// - /// assert!(Invoice::from_signed(signed).is_ok()); + /// assert!(Bolt11Invoice::from_signed(signed).is_ok()); /// ``` pub fn from_signed(signed_invoice: SignedRawInvoice) -> Result { - let invoice = Invoice { + let invoice = Bolt11Invoice { signed_invoice, }; invoice.check_field_counts()?; @@ -1284,18 +1284,18 @@ impl Invoice { Ok(invoice) } - /// Returns the `Invoice`'s timestamp (should equal its creation time) + /// Returns the `Bolt11Invoice`'s timestamp (should equal its creation time) #[cfg(feature = "std")] pub fn timestamp(&self) -> SystemTime { self.signed_invoice.raw_invoice().data.timestamp.as_time() } - /// Returns the `Invoice`'s timestamp as a duration since the Unix epoch + /// Returns the `Bolt11Invoice`'s timestamp as a duration since the Unix epoch pub fn duration_since_epoch(&self) -> Duration { self.signed_invoice.raw_invoice().data.timestamp.0 } - /// Returns an iterator over all tagged fields of this Invoice. + /// Returns an iterator over all tagged fields of this `Bolt11Invoice`. /// /// This is not exported to bindings users as there is not yet a manual mapping for a FilterMap pub fn tagged_fields(&self) @@ -1607,7 +1607,7 @@ impl Deref for SignedRawInvoice { } } -/// Errors that may occur when constructing a new [`RawInvoice`] or [`Invoice`] +/// Errors that may occur when constructing a new [`RawInvoice`] or [`Bolt11Invoice`] #[derive(Eq, PartialEq, Debug, Clone)] pub enum CreationError { /// The supplied description string was longer than 639 __bytes__ (see [`Description::new`]) @@ -1651,8 +1651,8 @@ impl Display for CreationError { #[cfg(feature = "std")] impl std::error::Error for CreationError { } -/// Errors that may occur when converting a [`RawInvoice`] to an [`Invoice`]. They relate to the -/// requirements sections in BOLT #11 +/// Errors that may occur when converting a [`RawInvoice`] to a [`Bolt11Invoice`]. They relate to +/// the requirements sections in BOLT #11 #[derive(Eq, PartialEq, Debug, Clone)] pub enum SemanticError { /// The invoice is missing the mandatory payment hash @@ -1728,16 +1728,16 @@ impl Display for SignOrCreationError { } #[cfg(feature = "serde")] -impl Serialize for Invoice { +impl Serialize for Bolt11Invoice { fn serialize(&self, serializer: S) -> Result where S: Serializer { serializer.serialize_str(self.to_string().as_str()) } } #[cfg(feature = "serde")] -impl<'de> Deserialize<'de> for Invoice { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { +impl<'de> Deserialize<'de> for Bolt11Invoice { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { let bolt11 = String::deserialize(deserializer)? - .parse::() + .parse::() .map_err(|e| D::Error::custom(format_args!("{:?}", e)))?; Ok(bolt11) @@ -1866,7 +1866,7 @@ mod test { use lightning::ln::features::InvoiceFeatures; use secp256k1::Secp256k1; use secp256k1::SecretKey; - use crate::{RawInvoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, Invoice, + use crate::{Bolt11Invoice, RawInvoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, SemanticError}; let private_key = SecretKey::from_slice(&[42; 32]).unwrap(); @@ -1898,7 +1898,7 @@ mod test { invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures)); // Missing feature bits let invoice = { @@ -1907,7 +1907,7 @@ mod test { invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures)); let mut payment_secret_features = InvoiceFeatures::empty(); payment_secret_features.set_payment_secret_required(); @@ -1919,14 +1919,14 @@ mod test { invoice.data.tagged_fields.push(Features(payment_secret_features.clone()).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert!(Invoice::from_signed(invoice).is_ok()); + assert!(Bolt11Invoice::from_signed(invoice).is_ok()); // No payment secret or features let invoice = { let invoice = invoice_template.clone(); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); // No payment secret or feature bits let invoice = { @@ -1934,7 +1934,7 @@ mod test { invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); // Missing payment secret let invoice = { @@ -1942,7 +1942,7 @@ mod test { invoice.data.tagged_fields.push(Features(payment_secret_features).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); // Multiple payment secrets let invoice = { @@ -1951,7 +1951,7 @@ mod test { invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Invoice::from_signed(invoice), Err(SemanticError::MultiplePaymentSecrets)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::MultiplePaymentSecrets)); } #[test] @@ -2176,7 +2176,7 @@ mod test { Ok(secp_ctx.sign_ecdsa_recoverable(hash, &privkey)) }) .unwrap(); - let invoice = Invoice::from_signed(signed_invoice).unwrap(); + let invoice = Bolt11Invoice::from_signed(signed_invoice).unwrap(); assert_eq!(invoice.min_final_cltv_expiry_delta(), DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA); assert_eq!(invoice.expiry_time(), Duration::from_secs(DEFAULT_EXPIRY_TIME)); @@ -2202,7 +2202,7 @@ mod test { Ok(secp_ctx.sign_ecdsa_recoverable(hash, &privkey)) }) .unwrap(); - let invoice = Invoice::from_signed(signed_invoice).unwrap(); + let invoice = Bolt11Invoice::from_signed(signed_invoice).unwrap(); assert!(invoice.would_expire(Duration::from_secs(1234567 + DEFAULT_EXPIRY_TIME + 1))); } @@ -2221,9 +2221,9 @@ mod test { p62g49p7569ev48cmulecsxe59lvaw3wlxm7r982zxa9zzj7z5l0cqqxusqqyqqqqlgqqqqqzsqygarl9fh3\ 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\ j5r6drg6k6zcqj0fcwg"; - let invoice = invoice_str.parse::().unwrap(); + let invoice = invoice_str.parse::().unwrap(); let serialized_invoice = serde_json::to_string(&invoice).unwrap(); - let deserialized_invoice: super::Invoice = serde_json::from_str(serialized_invoice.as_str()).unwrap(); + let deserialized_invoice: super::Bolt11Invoice = serde_json::from_str(serialized_invoice.as_str()).unwrap(); assert_eq!(invoice, deserialized_invoice); assert_eq!(invoice_str, deserialized_invoice.to_string().as_str()); assert_eq!(invoice_str, serialized_invoice.as_str().trim_matches('\"')); diff --git a/lightning-invoice/src/payment.rs b/lightning-invoice/src/payment.rs index bf161dbbf0e..42408540ee4 100644 --- a/lightning-invoice/src/payment.rs +++ b/lightning-invoice/src/payment.rs @@ -9,7 +9,7 @@ //! Convenient utilities for paying Lightning invoices and sending spontaneous payments. -use crate::Invoice; +use crate::Bolt11Invoice; use bitcoin_hashes::Hash; @@ -25,15 +25,15 @@ use core::fmt::Debug; use core::ops::Deref; use core::time::Duration; -/// Pays the given [`Invoice`], retrying if needed based on [`Retry`]. +/// Pays the given [`Bolt11Invoice`], retrying if needed based on [`Retry`]. /// -/// [`Invoice::payment_hash`] is used as the [`PaymentId`], which ensures idempotency as long +/// [`Bolt11Invoice::payment_hash`] is used as the [`PaymentId`], which ensures idempotency as long /// as the payment is still pending. If the payment succeeds, you must ensure that a second payment /// with the same [`PaymentHash`] is never sent. /// /// If you wish to use a different payment idempotency token, see [`pay_invoice_with_id`]. pub fn pay_invoice( - invoice: &Invoice, retry_strategy: Retry, + invoice: &Bolt11Invoice, retry_strategy: Retry, channelmanager: &ChannelManager ) -> Result where @@ -51,17 +51,18 @@ where .map(|()| payment_id) } -/// Pays the given [`Invoice`] with a custom idempotency key, retrying if needed based on [`Retry`]. +/// Pays the given [`Bolt11Invoice`] with a custom idempotency key, retrying if needed based on +/// [`Retry`]. /// /// Note that idempotency is only guaranteed as long as the payment is still pending. Once the /// payment completes or fails, no idempotency guarantees are made. /// -/// You should ensure that the [`Invoice::payment_hash`] is unique and the same [`PaymentHash`] -/// has never been paid before. +/// You should ensure that the [`Bolt11Invoice::payment_hash`] is unique and the same +/// [`PaymentHash`] has never been paid before. /// /// See [`pay_invoice`] for a variant which uses the [`PaymentHash`] for the idempotency token. pub fn pay_invoice_with_id( - invoice: &Invoice, payment_id: PaymentId, retry_strategy: Retry, + invoice: &Bolt11Invoice, payment_id: PaymentId, retry_strategy: Retry, channelmanager: &ChannelManager ) -> Result<(), PaymentError> where @@ -78,17 +79,17 @@ where pay_invoice_using_amount(invoice, amt_msat, payment_id, retry_strategy, channelmanager) } -/// Pays the given zero-value [`Invoice`] using the given amount, retrying if needed based on +/// Pays the given zero-value [`Bolt11Invoice`] using the given amount, retrying if needed based on /// [`Retry`]. /// -/// [`Invoice::payment_hash`] is used as the [`PaymentId`], which ensures idempotency as long +/// [`Bolt11Invoice::payment_hash`] is used as the [`PaymentId`], which ensures idempotency as long /// as the payment is still pending. If the payment succeeds, you must ensure that a second payment /// with the same [`PaymentHash`] is never sent. /// /// If you wish to use a different payment idempotency token, see /// [`pay_zero_value_invoice_with_id`]. pub fn pay_zero_value_invoice( - invoice: &Invoice, amount_msats: u64, retry_strategy: Retry, + invoice: &Bolt11Invoice, amount_msats: u64, retry_strategy: Retry, channelmanager: &ChannelManager ) -> Result where @@ -107,19 +108,19 @@ where .map(|()| payment_id) } -/// Pays the given zero-value [`Invoice`] using the given amount and custom idempotency key, +/// Pays the given zero-value [`Bolt11Invoice`] using the given amount and custom idempotency key, /// retrying if needed based on [`Retry`]. /// /// Note that idempotency is only guaranteed as long as the payment is still pending. Once the /// payment completes or fails, no idempotency guarantees are made. /// -/// You should ensure that the [`Invoice::payment_hash`] is unique and the same [`PaymentHash`] -/// has never been paid before. +/// You should ensure that the [`Bolt11Invoice::payment_hash`] is unique and the same +/// [`PaymentHash`] has never been paid before. /// /// See [`pay_zero_value_invoice`] for a variant which uses the [`PaymentHash`] for the /// idempotency token. pub fn pay_zero_value_invoice_with_id( - invoice: &Invoice, amount_msats: u64, payment_id: PaymentId, retry_strategy: Retry, + invoice: &Bolt11Invoice, amount_msats: u64, payment_id: PaymentId, retry_strategy: Retry, channelmanager: &ChannelManager ) -> Result<(), PaymentError> where @@ -141,7 +142,7 @@ where } fn pay_invoice_using_amount( - invoice: &Invoice, amount_msats: u64, payment_id: PaymentId, retry_strategy: Retry, + invoice: &Bolt11Invoice, amount_msats: u64, payment_id: PaymentId, retry_strategy: Retry, payer: P ) -> Result<(), PaymentError> where P::Target: Payer { let payment_hash = PaymentHash((*invoice.payment_hash()).into_inner()); @@ -164,20 +165,20 @@ fn pay_invoice_using_amount( payer.send_payment(payment_hash, recipient_onion, payment_id, route_params, retry_strategy) } -fn expiry_time_from_unix_epoch(invoice: &Invoice) -> Duration { +fn expiry_time_from_unix_epoch(invoice: &Bolt11Invoice) -> Duration { invoice.signed_invoice.raw_invoice.data.timestamp.0 + invoice.expiry_time() } /// An error that may occur when making a payment. #[derive(Clone, Debug, PartialEq, Eq)] pub enum PaymentError { - /// An error resulting from the provided [`Invoice`] or payment hash. + /// An error resulting from the provided [`Bolt11Invoice`] or payment hash. Invoice(&'static str), /// An error occurring when sending a payment. Sending(RetryableSendFailure), } -/// A trait defining behavior of an [`Invoice`] payer. +/// A trait defining behavior of a [`Bolt11Invoice`] payer. /// /// Useful for unit testing internal methods. trait Payer { @@ -283,7 +284,7 @@ mod tests { duration_since_epoch } - fn invoice(payment_preimage: PaymentPreimage) -> Invoice { + fn invoice(payment_preimage: PaymentPreimage) -> Bolt11Invoice { let payment_hash = Sha256::hash(&payment_preimage.0); let private_key = SecretKey::from_slice(&[42; 32]).unwrap(); @@ -300,7 +301,7 @@ mod tests { .unwrap() } - fn zero_value_invoice(payment_preimage: PaymentPreimage) -> Invoice { + fn zero_value_invoice(payment_preimage: PaymentPreimage) -> Bolt11Invoice { let payment_hash = Sha256::hash(&payment_preimage.0); let private_key = SecretKey::from_slice(&[42; 32]).unwrap(); diff --git a/lightning-invoice/src/ser.rs b/lightning-invoice/src/ser.rs index 0dca180cab3..a29f3e665e0 100644 --- a/lightning-invoice/src/ser.rs +++ b/lightning-invoice/src/ser.rs @@ -3,7 +3,7 @@ use core::fmt::{Display, Formatter}; use bech32::{ToBase32, u5, WriteBase32, Base32Len}; use crate::prelude::*; -use super::{Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, +use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawInvoice, RawDataPart}; /// Converts a stream of bytes written to it to base32. On finalization the according padding will @@ -106,7 +106,7 @@ fn bytes_size_to_base32_size(byte_size: usize) -> usize { } } -impl Display for Invoice { +impl Display for Bolt11Invoice { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { self.signed_invoice.fmt(f) } diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 199aad06469..8d11d54e64f 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -1,6 +1,6 @@ //! Convenient utilities to create an invoice. -use crate::{CreationError, Currency, Invoice, InvoiceBuilder, SignOrCreationError}; +use crate::{Bolt11Invoice, CreationError, Currency, InvoiceBuilder, SignOrCreationError}; use crate::{prelude::*, Description, InvoiceDescription, Sha256}; use bech32::ToBase32; @@ -64,7 +64,7 @@ pub fn create_phantom_invoice( amt_msat: Option, payment_hash: Option, description: String, invoice_expiry_delta_secs: u32, phantom_route_hints: Vec, entropy_source: ES, node_signer: NS, logger: L, network: Currency, min_final_cltv_expiry_delta: Option, duration_since_epoch: Duration, -) -> Result> +) -> Result> where ES::Target: EntropySource, NS::Target: NodeSigner, @@ -120,7 +120,7 @@ pub fn create_phantom_invoice_with_description_hash, payment_hash: Option, invoice_expiry_delta_secs: u32, description_hash: Sha256, phantom_route_hints: Vec, entropy_source: ES, node_signer: NS, logger: L, network: Currency, min_final_cltv_expiry_delta: Option, duration_since_epoch: Duration, -) -> Result> +) -> Result> where ES::Target: EntropySource, NS::Target: NodeSigner, @@ -139,7 +139,7 @@ fn _create_phantom_invoice( amt_msat: Option, payment_hash: Option, description: InvoiceDescription, invoice_expiry_delta_secs: u32, phantom_route_hints: Vec, entropy_source: ES, node_signer: NS, logger: L, network: Currency, min_final_cltv_expiry_delta: Option, duration_since_epoch: Duration, -) -> Result> +) -> Result> where ES::Target: EntropySource, NS::Target: NodeSigner, @@ -219,7 +219,7 @@ where let data_without_signature = raw_invoice.data.to_base32(); let signed_raw_invoice = raw_invoice.sign(|_| node_signer.sign_invoice(hrp_bytes, &data_without_signature, Recipient::PhantomNode)); match signed_raw_invoice { - Ok(inv) => Ok(Invoice::from_signed(inv).unwrap()), + Ok(inv) => Ok(Bolt11Invoice::from_signed(inv).unwrap()), Err(e) => Err(SignOrCreationError::SignError(e)) } } @@ -333,7 +333,7 @@ pub fn create_invoice_from_channelmanager, node_signer: NS, logger: L, network: Currency, amt_msat: Option, description: String, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, -) -> Result> +) -> Result> where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, @@ -374,7 +374,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash, node_signer: NS, logger: L, network: Currency, amt_msat: Option, description_hash: Sha256, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, -) -> Result> +) -> Result> where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, @@ -404,7 +404,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_sin channelmanager: &ChannelManager, node_signer: NS, logger: L, network: Currency, amt_msat: Option, description_hash: Sha256, duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, -) -> Result> +) -> Result> where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, @@ -429,7 +429,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch, node_signer: NS, logger: L, network: Currency, amt_msat: Option, description: String, duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, -) -> Result> +) -> Result> where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, @@ -453,7 +453,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch, node_signer: NS, logger: L, network: Currency, amt_msat: Option, description: InvoiceDescription, duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, -) -> Result> +) -> Result> where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, @@ -486,7 +486,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_ channelmanager: &ChannelManager, node_signer: NS, logger: L, network: Currency, amt_msat: Option, description: String, duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, min_final_cltv_expiry_delta: Option, -) -> Result> +) -> Result> where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, @@ -516,7 +516,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has network: Currency, amt_msat: Option, description: InvoiceDescription, duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, payment_secret: PaymentSecret, min_final_cltv_expiry_delta: Option, -) -> Result> +) -> Result> where M::Target: chain::Watch<::Signer>, T::Target: BroadcasterInterface, @@ -571,7 +571,7 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has let data_without_signature = raw_invoice.data.to_base32(); let signed_raw_invoice = raw_invoice.sign(|_| node_signer.sign_invoice(hrp_bytes, &data_without_signature, Recipient::Node)); match signed_raw_invoice { - Ok(inv) => Ok(Invoice::from_signed(inv).unwrap()), + Ok(inv) => Ok(Bolt11Invoice::from_signed(inv).unwrap()), Err(e) => Err(SignOrCreationError::SignError(e)) } } diff --git a/lightning-invoice/tests/ser_de.rs b/lightning-invoice/tests/ser_de.rs index ef5a4d32b30..437d7418a18 100644 --- a/lightning-invoice/tests/ser_de.rs +++ b/lightning-invoice/tests/ser_de.rs @@ -412,35 +412,35 @@ fn invoice_deserialize() { } assert_eq!(deserialized_hunks, parsed_hunks); - Invoice::from_signed(serialized.parse::().unwrap()).unwrap(); + Bolt11Invoice::from_signed(serialized.parse::().unwrap()).unwrap(); } } #[test] fn test_bolt_invalid_invoices() { // Tests the BOLT 11 invalid invoice test vectors - assert_eq!(Invoice::from_str( + assert_eq!(Bolt11Invoice::from_str( "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q4psqqqqqqqqqqqqqqqqsgqtqyx5vggfcsll4wu246hz02kp85x4katwsk9639we5n5yngc3yhqkm35jnjw4len8vrnqnf5ejh0mzj9n3vz2px97evektfm2l6wqccp3y7372" ), Err(ParseOrSemanticError::SemanticError(SemanticError::InvalidFeatures))); - assert_eq!(Invoice::from_str( + assert_eq!(Bolt11Invoice::from_str( "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt" ), Err(ParseOrSemanticError::ParseError(ParseError::Bech32Error(bech32::Error::InvalidChecksum)))); - assert_eq!(Invoice::from_str( + assert_eq!(Bolt11Invoice::from_str( "pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny" ), Err(ParseOrSemanticError::ParseError(ParseError::Bech32Error(bech32::Error::MissingSeparator)))); - assert_eq!(Invoice::from_str( + assert_eq!(Bolt11Invoice::from_str( "LNBC2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny" ), Err(ParseOrSemanticError::ParseError(ParseError::Bech32Error(bech32::Error::MixedCase)))); - assert_eq!(Invoice::from_str( + assert_eq!(Bolt11Invoice::from_str( "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqwgt7mcn5yqw3yx0w94pswkpq6j9uh6xfqqqtsk4tnarugeektd4hg5975x9am52rz4qskukxdmjemg92vvqz8nvmsye63r5ykel43pgz7zq0g2" ), Err(ParseOrSemanticError::SemanticError(SemanticError::InvalidSignature))); - assert_eq!(Invoice::from_str( + assert_eq!(Bolt11Invoice::from_str( "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh" ), Err(ParseOrSemanticError::ParseError(ParseError::TooShortDataPart))); - assert_eq!(Invoice::from_str( + assert_eq!(Bolt11Invoice::from_str( "lnbc2500x1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqrrzc4cvfue4zp3hggxp47ag7xnrlr8vgcmkjxk3j5jqethnumgkpqp23z9jclu3v0a7e0aruz366e9wqdykw6dxhdzcjjhldxq0w6wgqcnu43j" ), Err(ParseOrSemanticError::ParseError(ParseError::UnknownSiPrefix))); - assert_eq!(Invoice::from_str( + assert_eq!(Bolt11Invoice::from_str( "lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgq0lzc236j96a95uv0m3umg28gclm5lqxtqqwk32uuk4k6673k6n5kfvx3d2h8s295fad45fdhmusm8sjudfhlf6dcsxmfvkeywmjdkxcp99202x" ), Err(ParseOrSemanticError::SemanticError(SemanticError::ImpreciseAmount))); } From 4c383a39a8a54a8c18e65fe72928d1ec98345349 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 13 Jul 2023 20:34:27 -0500 Subject: [PATCH 08/13] Qualify the BOLT 11 raw invoice types A previous commit qualified the BOLT 11 invoice type, so any related types should be similarly qualified, if public. --- lightning-invoice/src/de.rs | 28 +++++----- lightning-invoice/src/lib.rs | 90 +++++++++++++++---------------- lightning-invoice/src/ser.rs | 4 +- lightning-invoice/tests/ser_de.rs | 6 +-- 4 files changed, 64 insertions(+), 64 deletions(-) diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs index 2e638ff14cb..6e2a743c704 100644 --- a/lightning-invoice/src/de.rs +++ b/lightning-invoice/src/de.rs @@ -24,8 +24,8 @@ use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use secp256k1::PublicKey; use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, - SemanticError, PrivateRoute, ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawInvoice, - constants, SignedRawInvoice, RawDataPart, InvoiceFeatures}; + SemanticError, PrivateRoute, ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice, + constants, SignedRawBolt11Invoice, RawDataPart, InvoiceFeatures}; use self::hrp_sm::parse_hrp; @@ -231,7 +231,7 @@ impl FromStr for Bolt11Invoice { type Err = ParseOrSemanticError; fn from_str(s: &str) -> Result::Err> { - let signed = s.parse::()?; + let signed = s.parse::()?; Ok(Bolt11Invoice::from_signed(signed)?) } } @@ -253,7 +253,7 @@ impl FromStr for Bolt11Invoice { /// /// let parsed_1 = invoice.parse::(); /// -/// let parsed_2 = match invoice.parse::() { +/// let parsed_2 = match invoice.parse::() { /// Ok(signed) => match Bolt11Invoice::from_signed(signed) { /// Ok(invoice) => Ok(invoice), /// Err(e) => Err(ParseOrSemanticError::SemanticError(e)), @@ -264,7 +264,7 @@ impl FromStr for Bolt11Invoice { /// assert!(parsed_1.is_ok()); /// assert_eq!(parsed_1, parsed_2); /// ``` -impl FromStr for SignedRawInvoice { +impl FromStr for SignedRawBolt11Invoice { type Err = ParseError; fn from_str(s: &str) -> Result { @@ -283,12 +283,12 @@ impl FromStr for SignedRawInvoice { let raw_hrp: RawHrp = hrp.parse()?; let data_part = RawDataPart::from_base32(&data[..data.len()-104])?; - Ok(SignedRawInvoice { - raw_invoice: RawInvoice { + Ok(SignedRawBolt11Invoice { + raw_invoice: RawBolt11Invoice { hrp: raw_hrp, data: data_part, }, - hash: RawInvoice::hash_from_parts( + hash: RawBolt11Invoice::hash_from_parts( hrp.as_bytes(), &data[..data.len()-104] ), @@ -972,14 +972,14 @@ mod test { use lightning::ln::features::InvoiceFeatures; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use crate::TaggedField::*; - use crate::{SiPrefix, SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, + use crate::{SiPrefix, SignedRawBolt11Invoice, InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp}; // Feature bits 9, 15, and 99 are set. let expected_features = InvoiceFeatures::from_le_bytes(vec![0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8]); let invoice_str = "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqpqsq67gye39hfg3zd8rgc80k32tvy9xk2xunwm5lzexnvpx6fd77en8qaq424dxgt56cag2dpt359k3ssyhetktkpqh24jqnjyw6uqd08sgptq44qu"; - let invoice = SignedRawInvoice { - raw_invoice: RawInvoice { + let invoice = SignedRawBolt11Invoice { + raw_invoice: RawBolt11Invoice { hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: Some(25), @@ -1018,15 +1018,15 @@ mod test { fn test_raw_signed_invoice_deserialization() { use crate::TaggedField::*; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; - use crate::{SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256, + use crate::{SignedRawBolt11Invoice, InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp}; assert_eq!( "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmw\ wd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq8rkx3yf5tcsyz3d73gafnh3cax9rn449d9p5uxz9\ ezhhypd0elx87sjle52x86fux2ypatgddc6k63n7erqz25le42c4u4ecky03ylcqca784w".parse(), - Ok(SignedRawInvoice { - raw_invoice: RawInvoice { + Ok(SignedRawBolt11Invoice { + raw_invoice: RawBolt11Invoice { hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 94566ba7378..e840c29fe3a 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -251,7 +251,7 @@ pub struct InvoiceBuilder { Hash(&'f Sha256), } -/// Represents a signed [`RawInvoice`] with cached hash. The signature is not checked and may be +/// Represents a signed [`RawBolt11Invoice`] with cached hash. The signature is not checked and may be /// invalid. /// /// # Invariants -/// The hash has to be either from the deserialized invoice or from the serialized [`RawInvoice`]. +/// The hash has to be either from the deserialized invoice or from the serialized [`RawBolt11Invoice`]. #[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)] -pub struct SignedRawInvoice { - /// The rawInvoice that the signature belongs to - raw_invoice: RawInvoice, +pub struct SignedRawBolt11Invoice { + /// The raw invoice that the signature belongs to + raw_invoice: RawBolt11Invoice, - /// Hash of the [`RawInvoice`] that will be used to check the signature. + /// Hash of the [`RawBolt11Invoice`] that will be used to check the signature. /// - /// * if the `SignedRawInvoice` was deserialized the hash is of from the original encoded form, + /// * if the `SignedRawBolt11Invoice` was deserialized the hash is of from the original encoded form, /// since it's not guaranteed that encoding it again will lead to the same result since integers /// could have been encoded with leading zeroes etc. - /// * if the `SignedRawInvoice` was constructed manually the hash will be the calculated hash - /// from the [`RawInvoice`] + /// * if the `SignedRawBolt11Invoice` was constructed manually the hash will be the calculated hash + /// from the [`RawBolt11Invoice`] hash: [u8; 32], /// signature of the payment request @@ -297,7 +297,7 @@ pub struct SignedRawInvoice { /// /// For methods without docs see the corresponding methods in [`Bolt11Invoice`]. #[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)] -pub struct RawInvoice { +pub struct RawBolt11Invoice { /// human readable part pub hrp: RawHrp, @@ -305,7 +305,7 @@ pub struct RawInvoice { pub data: RawDataPart, } -/// Data of the [`RawInvoice`] that is encoded in the human readable part. +/// Data of the [`RawBolt11Invoice`] that is encoded in the human readable part. /// /// This is not exported to bindings users as we don't yet support `Option` #[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)] @@ -320,7 +320,7 @@ pub struct RawHrp { pub si_prefix: Option, } -/// Data of the [`RawInvoice`] that is encoded in the data part +/// Data of the [`RawBolt11Invoice`] that is encoded in the data part #[derive(Eq, PartialEq, Debug, Clone, Hash, Ord, PartialOrd)] pub struct RawDataPart { /// generation time of the invoice @@ -621,9 +621,9 @@ impl InvoiceBuilder { - /// Builds a [`RawInvoice`] if no [`CreationError`] occurred while construction any of the + /// Builds a [`RawBolt11Invoice`] if no [`CreationError`] occurred while construction any of the /// fields. - pub fn build_raw(self) -> Result { + pub fn build_raw(self) -> Result { // If an error occurred at any time before, return it now if let Some(e) = self.error { @@ -647,7 +647,7 @@ impl InvoiceBui tagged_fields, }; - Ok(RawInvoice { + Ok(RawBolt11Invoice { hrp, data, }) @@ -850,21 +850,21 @@ impl InvoiceBuilder (RawInvoice, [u8; 32], InvoiceSignature) { + pub fn into_parts(self) -> (RawBolt11Invoice, [u8; 32], InvoiceSignature) { (self.raw_invoice, self.hash, self.signature) } - /// The [`RawInvoice`] which was signed. - pub fn raw_invoice(&self) -> &RawInvoice { + /// The [`RawBolt11Invoice`] which was signed. + pub fn raw_invoice(&self) -> &RawBolt11Invoice { &self.raw_invoice } - /// The hash of the [`RawInvoice`] that was signed. + /// The hash of the [`RawBolt11Invoice`] that was signed. pub fn signable_hash(&self) -> &[u8; 32] { &self.hash } @@ -968,7 +968,7 @@ macro_rules! find_all_extract { } #[allow(missing_docs)] -impl RawInvoice { +impl RawBolt11Invoice { /// Hash the HRP as bytes and signatureless data part. fn hash_from_parts(hrp_bytes: &[u8], data_without_signature: &[u5]) -> [u8; 32] { let preimage = construct_invoice_preimage(hrp_bytes, data_without_signature); @@ -977,23 +977,23 @@ impl RawInvoice { hash } - /// Calculate the hash of the encoded `RawInvoice` which should be signed. + /// Calculate the hash of the encoded `RawBolt11Invoice` which should be signed. pub fn signable_hash(&self) -> [u8; 32] { use bech32::ToBase32; - RawInvoice::hash_from_parts( + RawBolt11Invoice::hash_from_parts( self.hrp.to_string().as_bytes(), &self.data.to_base32() ) } /// Signs the invoice using the supplied `sign_method`. This function MAY fail with an error of - /// type `E`. Since the signature of a [`SignedRawInvoice`] is not required to be valid there + /// type `E`. Since the signature of a [`SignedRawBolt11Invoice`] is not required to be valid there /// are no constraints regarding the validity of the produced signature. /// /// This is not exported to bindings users as we don't currently support passing function pointers into methods /// explicitly. - pub fn sign(self, sign_method: F) -> Result + pub fn sign(self, sign_method: F) -> Result where F: FnOnce(&Message) -> Result { let raw_hash = self.signable_hash(); @@ -1001,7 +1001,7 @@ impl RawInvoice { .expect("Hash is 32 bytes long, same as MESSAGE_SIZE"); let signature = sign_method(&hash)?; - Ok(SignedRawInvoice { + Ok(SignedRawBolt11Invoice { raw_invoice: self, hash: raw_hash, signature: InvoiceSignature(signature), @@ -1143,13 +1143,13 @@ impl From for SystemTime { } impl Bolt11Invoice { - /// The hash of the [`RawInvoice`] that was signed. + /// The hash of the [`RawBolt11Invoice`] that was signed. pub fn signable_hash(&self) -> [u8; 32] { self.signed_invoice.hash } /// Transform the `Bolt11Invoice` into its unchecked version. - pub fn into_signed_raw(self) -> SignedRawInvoice { + pub fn into_signed_raw(self) -> SignedRawBolt11Invoice { self.signed_invoice } @@ -1252,7 +1252,7 @@ impl Bolt11Invoice { Ok(()) } - /// Constructs a `Bolt11Invoice` from a [`SignedRawInvoice`] by checking all its invariants. + /// Constructs a `Bolt11Invoice` from a [`SignedRawBolt11Invoice`] by checking all its invariants. /// ``` /// use lightning_invoice::*; /// @@ -1268,11 +1268,11 @@ impl Bolt11Invoice { /// 8s0gyuxjjgux34w75dnc6xp2l35j7es3jd4ugt3lu0xzre26yg5m7ke54n2d5sym4xcmxtl8238xxvw5h5h5\ /// j5r6drg6k6zcqj0fcwg"; /// - /// let signed = invoice.parse::().unwrap(); + /// let signed = invoice.parse::().unwrap(); /// /// assert!(Bolt11Invoice::from_signed(signed).is_ok()); /// ``` - pub fn from_signed(signed_invoice: SignedRawInvoice) -> Result { + pub fn from_signed(signed_invoice: SignedRawBolt11Invoice) -> Result { let invoice = Bolt11Invoice { signed_invoice, }; @@ -1599,15 +1599,15 @@ impl Deref for InvoiceSignature { } } -impl Deref for SignedRawInvoice { - type Target = RawInvoice; +impl Deref for SignedRawBolt11Invoice { + type Target = RawBolt11Invoice; - fn deref(&self) -> &RawInvoice { + fn deref(&self) -> &RawBolt11Invoice { &self.raw_invoice } } -/// Errors that may occur when constructing a new [`RawInvoice`] or [`Bolt11Invoice`] +/// Errors that may occur when constructing a new [`RawBolt11Invoice`] or [`Bolt11Invoice`] #[derive(Eq, PartialEq, Debug, Clone)] pub enum CreationError { /// The supplied description string was longer than 639 __bytes__ (see [`Description::new`]) @@ -1651,7 +1651,7 @@ impl Display for CreationError { #[cfg(feature = "std")] impl std::error::Error for CreationError { } -/// Errors that may occur when converting a [`RawInvoice`] to a [`Bolt11Invoice`]. They relate to +/// Errors that may occur when converting a [`RawBolt11Invoice`] to a [`Bolt11Invoice`]. They relate to /// the requirements sections in BOLT #11 #[derive(Eq, PartialEq, Debug, Clone)] pub enum SemanticError { @@ -1760,10 +1760,10 @@ mod test { #[test] fn test_calc_invoice_hash() { - use crate::{RawInvoice, RawHrp, RawDataPart, Currency, PositiveTimestamp}; + use crate::{RawBolt11Invoice, RawHrp, RawDataPart, Currency, PositiveTimestamp}; use crate::TaggedField::*; - let invoice = RawInvoice { + let invoice = RawBolt11Invoice { hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, @@ -1797,11 +1797,11 @@ mod test { use secp256k1::Secp256k1; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use secp256k1::{SecretKey, PublicKey}; - use crate::{SignedRawInvoice, InvoiceSignature, RawInvoice, RawHrp, RawDataPart, Currency, Sha256, + use crate::{SignedRawBolt11Invoice, InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp}; - let invoice = SignedRawInvoice { - raw_invoice: RawInvoice { + let invoice = SignedRawBolt11Invoice { + raw_invoice: RawBolt11Invoice { hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, @@ -1866,12 +1866,12 @@ mod test { use lightning::ln::features::InvoiceFeatures; use secp256k1::Secp256k1; use secp256k1::SecretKey; - use crate::{Bolt11Invoice, RawInvoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, + use crate::{Bolt11Invoice, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, SemanticError}; let private_key = SecretKey::from_slice(&[42; 32]).unwrap(); let payment_secret = lightning::ln::PaymentSecret([21; 32]); - let invoice_template = RawInvoice { + let invoice_template = RawBolt11Invoice { hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, diff --git a/lightning-invoice/src/ser.rs b/lightning-invoice/src/ser.rs index a29f3e665e0..43ddedcd480 100644 --- a/lightning-invoice/src/ser.rs +++ b/lightning-invoice/src/ser.rs @@ -4,7 +4,7 @@ use bech32::{ToBase32, u5, WriteBase32, Base32Len}; use crate::prelude::*; use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, - PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawInvoice, RawDataPart}; + PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawBolt11Invoice, RawDataPart}; /// Converts a stream of bytes written to it to base32. On finalization the according padding will /// be applied. That means the results of writing two data blocks with one or two `BytesToBase32` @@ -112,7 +112,7 @@ impl Display for Bolt11Invoice { } } -impl Display for SignedRawInvoice { +impl Display for SignedRawBolt11Invoice { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { let hrp = self.raw_invoice.hrp.to_string(); let mut data = self.raw_invoice.data.to_base32(); diff --git a/lightning-invoice/tests/ser_de.rs b/lightning-invoice/tests/ser_de.rs index 437d7418a18..4e98133fd99 100644 --- a/lightning-invoice/tests/ser_de.rs +++ b/lightning-invoice/tests/ser_de.rs @@ -19,7 +19,7 @@ use std::collections::HashSet; use std::time::Duration; use std::str::FromStr; -fn get_test_tuples() -> Vec<(String, SignedRawInvoice, bool, bool)> { +fn get_test_tuples() -> Vec<(String, SignedRawBolt11Invoice, bool, bool)> { vec![ ( "lnbc1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq9qrsgq357wnc5r2ueh7ck6q93dj32dlqnls087fxdwk8qakdyafkq3yap9us6v52vjjsrvywa6rt52cm9r9zqt8r2t7mlcwspyetp5h2tztugp9lfyql".to_owned(), @@ -389,7 +389,7 @@ fn get_test_tuples() -> Vec<(String, SignedRawInvoice, bool, bool)> { fn invoice_deserialize() { for (serialized, deserialized, ignore_feature_diff, ignore_unknown_fields) in get_test_tuples() { eprintln!("Testing invoice {}...", serialized); - let parsed = serialized.parse::().unwrap(); + let parsed = serialized.parse::().unwrap(); let (parsed_invoice, _, parsed_sig) = parsed.into_parts(); let (deserialized_invoice, _, deserialized_sig) = deserialized.into_parts(); @@ -412,7 +412,7 @@ fn invoice_deserialize() { } assert_eq!(deserialized_hunks, parsed_hunks); - Bolt11Invoice::from_signed(serialized.parse::().unwrap()).unwrap(); + Bolt11Invoice::from_signed(serialized.parse::().unwrap()).unwrap(); } } From 6fb34d30b318aa64f64c1182c2b6fa1f1d8960b1 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 13 Jul 2023 20:49:02 -0500 Subject: [PATCH 09/13] Qualify the BOLT 11 parse error type A previous commit qualified the BOLT 12 parse error type. Qualify the BOLT 11 parse error type for consistency. --- lightning-invoice/src/de.rs | 196 +++++++++++++++--------------- lightning-invoice/src/lib.rs | 4 +- lightning-invoice/tests/ser_de.rs | 10 +- 3 files changed, 105 insertions(+), 105 deletions(-) diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs index 6e2a743c704..8bca12e344c 100644 --- a/lightning-invoice/src/de.rs +++ b/lightning-invoice/src/de.rs @@ -24,7 +24,7 @@ use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use secp256k1::PublicKey; use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, - SemanticError, PrivateRoute, ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice, + SemanticError, PrivateRoute, Bolt11ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice, constants, SignedRawBolt11Invoice, RawDataPart, InvoiceFeatures}; use self::hrp_sm::parse_hrp; @@ -44,20 +44,20 @@ mod hrp_sm { } impl States { - fn next_state(&self, read_symbol: char) -> Result { + fn next_state(&self, read_symbol: char) -> Result { match *self { States::Start => { if read_symbol == 'l' { Ok(States::ParseL) } else { - Err(super::ParseError::MalformedHRP) + Err(super::Bolt11ParseError::MalformedHRP) } } States::ParseL => { if read_symbol == 'n' { Ok(States::ParseN) } else { - Err(super::ParseError::MalformedHRP) + Err(super::Bolt11ParseError::MalformedHRP) } }, States::ParseN => { @@ -80,10 +80,10 @@ mod hrp_sm { } else if ['m', 'u', 'n', 'p'].contains(&read_symbol) { Ok(States::ParseAmountSiPrefix) } else { - Err(super::ParseError::UnknownSiPrefix) + Err(super::Bolt11ParseError::UnknownSiPrefix) } }, - States::ParseAmountSiPrefix => Err(super::ParseError::MalformedHRP), + States::ParseAmountSiPrefix => Err(super::Bolt11ParseError::MalformedHRP), } } @@ -120,7 +120,7 @@ mod hrp_sm { *range = Some(new_range); } - fn step(&mut self, c: char) -> Result<(), super::ParseError> { + fn step(&mut self, c: char) -> Result<(), super::Bolt11ParseError> { let next_state = self.state.next_state(c)?; match next_state { States::ParseCurrencyPrefix => { @@ -157,14 +157,14 @@ mod hrp_sm { } } - pub fn parse_hrp(input: &str) -> Result<(&str, &str, &str), super::ParseError> { + pub fn parse_hrp(input: &str) -> Result<(&str, &str, &str), super::Bolt11ParseError> { let mut sm = StateMachine::new(); for c in input.chars() { sm.step(c)?; } if !sm.is_final() { - return Err(super::ParseError::MalformedHRP); + return Err(super::Bolt11ParseError::MalformedHRP); } let currency = sm.currency_prefix().clone() @@ -180,31 +180,31 @@ mod hrp_sm { impl FromStr for super::Currency { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_str(currency_prefix: &str) -> Result { + fn from_str(currency_prefix: &str) -> Result { match currency_prefix { "bc" => Ok(Currency::Bitcoin), "tb" => Ok(Currency::BitcoinTestnet), "bcrt" => Ok(Currency::Regtest), "sb" => Ok(Currency::Simnet), "tbs" => Ok(Currency::Signet), - _ => Err(ParseError::UnknownCurrency) + _ => Err(Bolt11ParseError::UnknownCurrency) } } } impl FromStr for SiPrefix { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_str(currency_prefix: &str) -> Result { + fn from_str(currency_prefix: &str) -> Result { use crate::SiPrefix::*; match currency_prefix { "m" => Ok(Milli), "u" => Ok(Micro), "n" => Ok(Nano), "p" => Ok(Pico), - _ => Err(ParseError::UnknownSiPrefix) + _ => Err(Bolt11ParseError::UnknownSiPrefix) } } } @@ -265,7 +265,7 @@ impl FromStr for Bolt11Invoice { /// assert_eq!(parsed_1, parsed_2); /// ``` impl FromStr for SignedRawBolt11Invoice { - type Err = ParseError; + type Err = Bolt11ParseError; fn from_str(s: &str) -> Result { let (hrp, data, var) = bech32::decode(s)?; @@ -273,11 +273,11 @@ impl FromStr for SignedRawBolt11Invoice { if var == bech32::Variant::Bech32m { // Consider Bech32m addresses to be "Invalid Checksum", since that is what we'd get if // we didn't support Bech32m (which lightning does not use). - return Err(ParseError::Bech32Error(bech32::Error::InvalidChecksum)); + return Err(Bolt11ParseError::Bech32Error(bech32::Error::InvalidChecksum)); } if data.len() < 104 { - return Err(ParseError::TooShortDataPart); + return Err(Bolt11ParseError::TooShortDataPart); } let raw_hrp: RawHrp = hrp.parse()?; @@ -298,7 +298,7 @@ impl FromStr for SignedRawBolt11Invoice { } impl FromStr for RawHrp { - type Err = ParseError; + type Err = Bolt11ParseError; fn from_str(hrp: &str) -> Result::Err> { let parts = parse_hrp(hrp)?; @@ -317,7 +317,7 @@ impl FromStr for RawHrp { let si: SiPrefix = parts.2.parse()?; if let Some(amt) = amount { if amt.checked_mul(si.multiplier()).is_none() { - return Err(ParseError::IntegerOverflowError); + return Err(Bolt11ParseError::IntegerOverflowError); } } Some(si) @@ -332,11 +332,11 @@ impl FromStr for RawHrp { } impl FromBase32 for RawDataPart { - type Err = ParseError; + type Err = Bolt11ParseError; fn from_base32(data: &[u5]) -> Result { if data.len() < 7 { // timestamp length - return Err(ParseError::TooShortDataPart); + return Err(Bolt11ParseError::TooShortDataPart); } let timestamp = PositiveTimestamp::from_base32(&data[0..7])?; @@ -350,11 +350,11 @@ impl FromBase32 for RawDataPart { } impl FromBase32 for PositiveTimestamp { - type Err = ParseError; + type Err = Bolt11ParseError; fn from_base32(b32: &[u5]) -> Result { if b32.len() != 7 { - return Err(ParseError::InvalidSliceLength("PositiveTimestamp::from_base32()".into())); + return Err(Bolt11ParseError::InvalidSliceLength("PositiveTimestamp::from_base32()".into())); } let timestamp: u64 = parse_int_be(b32, 32) .expect("7*5bit < 64bit, no overflow possible"); @@ -366,10 +366,10 @@ impl FromBase32 for PositiveTimestamp { } impl FromBase32 for InvoiceSignature { - type Err = ParseError; + type Err = Bolt11ParseError; fn from_base32(signature: &[u5]) -> Result { if signature.len() != 104 { - return Err(ParseError::InvalidSliceLength("InvoiceSignature::from_base32()".into())); + return Err(Bolt11ParseError::InvalidSliceLength("InvoiceSignature::from_base32()".into())); } let recoverable_signature_bytes = Vec::::from_base32(signature)?; let signature = &recoverable_signature_bytes[0..64]; @@ -393,13 +393,13 @@ pub(crate) fn parse_int_be(digits: &[U], base: T) -> Option ) } -fn parse_tagged_parts(data: &[u5]) -> Result, ParseError> { +fn parse_tagged_parts(data: &[u5]) -> Result, Bolt11ParseError> { let mut parts = Vec::::new(); let mut data = data; while !data.is_empty() { if data.len() < 3 { - return Err(ParseError::UnexpectedEndOfTaggedFields); + return Err(Bolt11ParseError::UnexpectedEndOfTaggedFields); } // Ignore tag at data[0], it will be handled in the TaggedField parsers and @@ -408,7 +408,7 @@ fn parse_tagged_parts(data: &[u5]) -> Result, ParseError> { let last_element = 3 + len; if data.len() < last_element { - return Err(ParseError::UnexpectedEndOfTaggedFields); + return Err(Bolt11ParseError::UnexpectedEndOfTaggedFields); } // Get the tagged field's data slice @@ -421,7 +421,7 @@ fn parse_tagged_parts(data: &[u5]) -> Result, ParseError> { Ok(field) => { parts.push(RawTaggedField::KnownSemantics(field)) }, - Err(ParseError::Skip)|Err(ParseError::Bech32Error(bech32::Error::InvalidLength)) => { + Err(Bolt11ParseError::Skip)|Err(Bolt11ParseError::Bech32Error(bech32::Error::InvalidLength)) => { parts.push(RawTaggedField::UnknownSemantics(field.into())) }, Err(e) => {return Err(e)} @@ -431,11 +431,11 @@ fn parse_tagged_parts(data: &[u5]) -> Result, ParseError> { } impl FromBase32 for TaggedField { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_base32(field: &[u5]) -> Result { + fn from_base32(field: &[u5]) -> Result { if field.len() < 3 { - return Err(ParseError::UnexpectedEndOfTaggedFields); + return Err(Bolt11ParseError::UnexpectedEndOfTaggedFields); } let tag = field[0]; @@ -466,19 +466,19 @@ impl FromBase32 for TaggedField { Ok(TaggedField::Features(InvoiceFeatures::from_base32(field_data)?)), _ => { // "A reader MUST skip over unknown fields" - Err(ParseError::Skip) + Err(Bolt11ParseError::Skip) } } } } impl FromBase32 for Sha256 { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_base32(field_data: &[u5]) -> Result { + fn from_base32(field_data: &[u5]) -> Result { if field_data.len() != 52 { // "A reader MUST skip over […] a p, [or] h […] field that does not have data_length 52 […]." - Err(ParseError::Skip) + Err(Bolt11ParseError::Skip) } else { Ok(Sha256(sha256::Hash::from_slice(&Vec::::from_base32(field_data)?) .expect("length was checked before (52 u5 -> 32 u8)"))) @@ -487,9 +487,9 @@ impl FromBase32 for Sha256 { } impl FromBase32 for Description { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_base32(field_data: &[u5]) -> Result { + fn from_base32(field_data: &[u5]) -> Result { let bytes = Vec::::from_base32(field_data)?; let description = String::from(str::from_utf8(&bytes)?); Ok(Description::new(description).expect( @@ -499,12 +499,12 @@ impl FromBase32 for Description { } impl FromBase32 for PayeePubKey { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_base32(field_data: &[u5]) -> Result { + fn from_base32(field_data: &[u5]) -> Result { if field_data.len() != 53 { // "A reader MUST skip over […] a n […] field that does not have data_length 53 […]." - Err(ParseError::Skip) + Err(Bolt11ParseError::Skip) } else { let data_bytes = Vec::::from_base32(field_data)?; let pub_key = PublicKey::from_slice(&data_bytes)?; @@ -514,37 +514,37 @@ impl FromBase32 for PayeePubKey { } impl FromBase32 for ExpiryTime { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_base32(field_data: &[u5]) -> Result { + fn from_base32(field_data: &[u5]) -> Result { match parse_int_be::(field_data, 32) .map(ExpiryTime::from_seconds) { Some(t) => Ok(t), - None => Err(ParseError::IntegerOverflowError), + None => Err(Bolt11ParseError::IntegerOverflowError), } } } impl FromBase32 for MinFinalCltvExpiryDelta { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_base32(field_data: &[u5]) -> Result { + fn from_base32(field_data: &[u5]) -> Result { let expiry = parse_int_be::(field_data, 32); if let Some(expiry) = expiry { Ok(MinFinalCltvExpiryDelta(expiry)) } else { - Err(ParseError::IntegerOverflowError) + Err(Bolt11ParseError::IntegerOverflowError) } } } impl FromBase32 for Fallback { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_base32(field_data: &[u5]) -> Result { + fn from_base32(field_data: &[u5]) -> Result { if field_data.is_empty() { - return Err(ParseError::UnexpectedEndOfTaggedFields); + return Err(Bolt11ParseError::UnexpectedEndOfTaggedFields); } let version = field_data[0]; @@ -553,7 +553,7 @@ impl FromBase32 for Fallback { match version.to_u8() { 0..=16 => { if bytes.len() < 2 || bytes.len() > 40 { - return Err(ParseError::InvalidSegWitProgramLength); + return Err(Bolt11ParseError::InvalidSegWitProgramLength); } let version = WitnessVersion::try_from(version).expect("0 through 16 are valid SegWit versions"); Ok(Fallback::SegWitProgram { @@ -564,30 +564,30 @@ impl FromBase32 for Fallback { 17 => { let pkh = match PubkeyHash::from_slice(&bytes) { Ok(pkh) => pkh, - Err(bitcoin_hashes::Error::InvalidLength(_, _)) => return Err(ParseError::InvalidPubKeyHashLength), + Err(bitcoin_hashes::Error::InvalidLength(_, _)) => return Err(Bolt11ParseError::InvalidPubKeyHashLength), }; Ok(Fallback::PubKeyHash(pkh)) } 18 => { let sh = match ScriptHash::from_slice(&bytes) { Ok(sh) => sh, - Err(bitcoin_hashes::Error::InvalidLength(_, _)) => return Err(ParseError::InvalidScriptHashLength), + Err(bitcoin_hashes::Error::InvalidLength(_, _)) => return Err(Bolt11ParseError::InvalidScriptHashLength), }; Ok(Fallback::ScriptHash(sh)) } - _ => Err(ParseError::Skip) + _ => Err(Bolt11ParseError::Skip) } } } impl FromBase32 for PrivateRoute { - type Err = ParseError; + type Err = Bolt11ParseError; - fn from_base32(field_data: &[u5]) -> Result { + fn from_base32(field_data: &[u5]) -> Result { let bytes = Vec::::from_base32(field_data)?; if bytes.len() % 51 != 0 { - return Err(ParseError::UnexpectedEndOfTaggedFields); + return Err(Bolt11ParseError::UnexpectedEndOfTaggedFields); } let mut route_hops = Vec::::new(); @@ -619,52 +619,52 @@ impl FromBase32 for PrivateRoute { } } -impl Display for ParseError { +impl Display for Bolt11ParseError { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match *self { // TODO: find a way to combine the first three arms (e as error::Error?) - ParseError::Bech32Error(ref e) => { + Bolt11ParseError::Bech32Error(ref e) => { write!(f, "Invalid bech32: {}", e) } - ParseError::ParseAmountError(ref e) => { + Bolt11ParseError::ParseAmountError(ref e) => { write!(f, "Invalid amount in hrp ({})", e) } - ParseError::MalformedSignature(ref e) => { + Bolt11ParseError::MalformedSignature(ref e) => { write!(f, "Invalid secp256k1 signature: {}", e) } - ParseError::DescriptionDecodeError(ref e) => { + Bolt11ParseError::DescriptionDecodeError(ref e) => { write!(f, "Description is not a valid utf-8 string: {}", e) } - ParseError::InvalidSliceLength(ref function) => { + Bolt11ParseError::InvalidSliceLength(ref function) => { write!(f, "Slice in function {} had the wrong length", function) } - ParseError::BadPrefix => f.write_str("did not begin with 'ln'"), - ParseError::UnknownCurrency => f.write_str("currency code unknown"), - ParseError::UnknownSiPrefix => f.write_str("unknown SI prefix"), - ParseError::MalformedHRP => f.write_str("malformed human readable part"), - ParseError::TooShortDataPart => { + Bolt11ParseError::BadPrefix => f.write_str("did not begin with 'ln'"), + Bolt11ParseError::UnknownCurrency => f.write_str("currency code unknown"), + Bolt11ParseError::UnknownSiPrefix => f.write_str("unknown SI prefix"), + Bolt11ParseError::MalformedHRP => f.write_str("malformed human readable part"), + Bolt11ParseError::TooShortDataPart => { f.write_str("data part too short (should be at least 111 bech32 chars long)") }, - ParseError::UnexpectedEndOfTaggedFields => { + Bolt11ParseError::UnexpectedEndOfTaggedFields => { f.write_str("tagged fields part ended unexpectedly") }, - ParseError::PaddingError => f.write_str("some data field had bad padding"), - ParseError::IntegerOverflowError => { + Bolt11ParseError::PaddingError => f.write_str("some data field had bad padding"), + Bolt11ParseError::IntegerOverflowError => { f.write_str("parsed integer doesn't fit into receiving type") }, - ParseError::InvalidSegWitProgramLength => { + Bolt11ParseError::InvalidSegWitProgramLength => { f.write_str("fallback SegWit program is too long or too short") }, - ParseError::InvalidPubKeyHashLength => { + Bolt11ParseError::InvalidPubKeyHashLength => { f.write_str("fallback public key hash has a length unequal 20 bytes") }, - ParseError::InvalidScriptHashLength => { + Bolt11ParseError::InvalidScriptHashLength => { f.write_str("fallback script hash has a length unequal 32 bytes") }, - ParseError::InvalidRecoveryId => { + Bolt11ParseError::InvalidRecoveryId => { f.write_str("recovery id is out of range (should be in [0,3])") }, - ParseError::Skip => { + Bolt11ParseError::Skip => { f.write_str("the tagged field has to be skipped because of an unexpected, but allowed property") }, } @@ -681,14 +681,14 @@ impl Display for ParseOrSemanticError { } #[cfg(feature = "std")] -impl error::Error for ParseError {} +impl error::Error for Bolt11ParseError {} #[cfg(feature = "std")] impl error::Error for ParseOrSemanticError {} macro_rules! from_error { ($my_error:expr, $extern_error:ty) => { - impl From<$extern_error> for ParseError { + impl From<$extern_error> for Bolt11ParseError { fn from(e: $extern_error) -> Self { $my_error(e) } @@ -696,21 +696,21 @@ macro_rules! from_error { } } -from_error!(ParseError::MalformedSignature, secp256k1::Error); -from_error!(ParseError::ParseAmountError, ParseIntError); -from_error!(ParseError::DescriptionDecodeError, str::Utf8Error); +from_error!(Bolt11ParseError::MalformedSignature, secp256k1::Error); +from_error!(Bolt11ParseError::ParseAmountError, ParseIntError); +from_error!(Bolt11ParseError::DescriptionDecodeError, str::Utf8Error); -impl From for ParseError { +impl From for Bolt11ParseError { fn from(e: bech32::Error) -> Self { match e { - bech32::Error::InvalidPadding => ParseError::PaddingError, - _ => ParseError::Bech32Error(e) + bech32::Error::InvalidPadding => Bolt11ParseError::PaddingError, + _ => Bolt11ParseError::Bech32Error(e) } } } -impl From for ParseOrSemanticError { - fn from(e: ParseError) -> Self { +impl From for ParseOrSemanticError { + fn from(e: Bolt11ParseError) -> Self { ParseOrSemanticError::ParseError(e) } } @@ -723,7 +723,7 @@ impl From for ParseOrSemanticError { #[cfg(test)] mod test { - use crate::de::ParseError; + use crate::de::Bolt11ParseError; use secp256k1::PublicKey; use bech32::u5; use bitcoin_hashes::hex::FromHex; @@ -756,7 +756,7 @@ mod test { assert_eq!("bcrt".parse::(), Ok(Currency::Regtest)); assert_eq!("sb".parse::(), Ok(Currency::Simnet)); assert_eq!("tbs".parse::(), Ok(Currency::Signet)); - assert_eq!("something_else".parse::(), Err(ParseError::UnknownCurrency)) + assert_eq!("something_else".parse::(), Err(Bolt11ParseError::UnknownCurrency)) } #[test] @@ -789,7 +789,7 @@ mod test { let input_unexpected_length = from_bech32( "qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypyq".as_bytes() ); - assert_eq!(Sha256::from_base32(&input_unexpected_length), Err(ParseError::Skip)); + assert_eq!(Sha256::from_base32(&input_unexpected_length), Err(Bolt11ParseError::Skip)); } #[test] @@ -823,7 +823,7 @@ mod test { let input_unexpected_length = from_bech32( "q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhvq".as_bytes() ); - assert_eq!(PayeePubKey::from_base32(&input_unexpected_length), Err(ParseError::Skip)); + assert_eq!(PayeePubKey::from_base32(&input_unexpected_length), Err(Bolt11ParseError::Skip)); } #[test] @@ -836,7 +836,7 @@ mod test { assert_eq!(ExpiryTime::from_base32(&input), expected); let input_too_large = from_bech32("sqqqqqqqqqqqq".as_bytes()); - assert_eq!(ExpiryTime::from_base32(&input_too_large), Err(ParseError::IntegerOverflowError)); + assert_eq!(ExpiryTime::from_base32(&input_too_large), Err(Bolt11ParseError::IntegerOverflowError)); } #[test] @@ -885,23 +885,23 @@ mod test { ), ( vec![u5::try_from_u8(21).unwrap(); 41], - Err(ParseError::Skip) + Err(Bolt11ParseError::Skip) ), ( vec![], - Err(ParseError::UnexpectedEndOfTaggedFields) + Err(Bolt11ParseError::UnexpectedEndOfTaggedFields) ), ( vec![u5::try_from_u8(1).unwrap(); 81], - Err(ParseError::InvalidSegWitProgramLength) + Err(Bolt11ParseError::InvalidSegWitProgramLength) ), ( vec![u5::try_from_u8(17).unwrap(); 1], - Err(ParseError::InvalidPubKeyHashLength) + Err(Bolt11ParseError::InvalidPubKeyHashLength) ), ( vec![u5::try_from_u8(18).unwrap(); 1], - Err(ParseError::InvalidScriptHashLength) + Err(Bolt11ParseError::InvalidScriptHashLength) ) ]; @@ -963,7 +963,7 @@ mod test { assert_eq!( PrivateRoute::from_base32(&[u5::try_from_u8(0).unwrap(); 40][..]), - Err(ParseError::UnexpectedEndOfTaggedFields) + Err(Bolt11ParseError::UnexpectedEndOfTaggedFields) ); } diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index e840c29fe3a..dc13b5ec76a 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -106,7 +106,7 @@ mod sync; /// reasons, but should generally result in an "invalid BOLT11 invoice" message for the user. #[allow(missing_docs)] #[derive(PartialEq, Eq, Debug, Clone)] -pub enum ParseError { +pub enum Bolt11ParseError { Bech32Error(bech32::Error), ParseAmountError(ParseIntError), MalformedSignature(secp256k1::Error), @@ -136,7 +136,7 @@ pub enum ParseError { #[derive(PartialEq, Eq, Debug, Clone)] pub enum ParseOrSemanticError { /// The invoice couldn't be decoded - ParseError(ParseError), + ParseError(Bolt11ParseError), /// The invoice could be decoded but violates the BOLT11 standard SemanticError(crate::SemanticError), diff --git a/lightning-invoice/tests/ser_de.rs b/lightning-invoice/tests/ser_de.rs index 4e98133fd99..02c0aa58c21 100644 --- a/lightning-invoice/tests/ser_de.rs +++ b/lightning-invoice/tests/ser_de.rs @@ -424,22 +424,22 @@ fn test_bolt_invalid_invoices() { ), Err(ParseOrSemanticError::SemanticError(SemanticError::InvalidFeatures))); assert_eq!(Bolt11Invoice::from_str( "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt" - ), Err(ParseOrSemanticError::ParseError(ParseError::Bech32Error(bech32::Error::InvalidChecksum)))); + ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::InvalidChecksum)))); assert_eq!(Bolt11Invoice::from_str( "pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny" - ), Err(ParseOrSemanticError::ParseError(ParseError::Bech32Error(bech32::Error::MissingSeparator)))); + ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::MissingSeparator)))); assert_eq!(Bolt11Invoice::from_str( "LNBC2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny" - ), Err(ParseOrSemanticError::ParseError(ParseError::Bech32Error(bech32::Error::MixedCase)))); + ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::MixedCase)))); assert_eq!(Bolt11Invoice::from_str( "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqwgt7mcn5yqw3yx0w94pswkpq6j9uh6xfqqqtsk4tnarugeektd4hg5975x9am52rz4qskukxdmjemg92vvqz8nvmsye63r5ykel43pgz7zq0g2" ), Err(ParseOrSemanticError::SemanticError(SemanticError::InvalidSignature))); assert_eq!(Bolt11Invoice::from_str( "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh" - ), Err(ParseOrSemanticError::ParseError(ParseError::TooShortDataPart))); + ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::TooShortDataPart))); assert_eq!(Bolt11Invoice::from_str( "lnbc2500x1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqrrzc4cvfue4zp3hggxp47ag7xnrlr8vgcmkjxk3j5jqethnumgkpqp23z9jclu3v0a7e0aruz366e9wqdykw6dxhdzcjjhldxq0w6wgqcnu43j" - ), Err(ParseOrSemanticError::ParseError(ParseError::UnknownSiPrefix))); + ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::UnknownSiPrefix))); assert_eq!(Bolt11Invoice::from_str( "lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgq0lzc236j96a95uv0m3umg28gclm5lqxtqqwk32uuk4k6673k6n5kfvx3d2h8s295fad45fdhmusm8sjudfhlf6dcsxmfvkeywmjdkxcp99202x" ), Err(ParseOrSemanticError::SemanticError(SemanticError::ImpreciseAmount))); From 62ca48f979010b28de23f0b060aa056d502a3436 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 13 Jul 2023 20:56:30 -0500 Subject: [PATCH 10/13] Qualify the BOLT 11 semantic error type A previous commit qualified the BOLT 12 semantic error type. Qualify the BOLT 11 semantic error type for consistency. --- lightning-invoice/src/de.rs | 6 +-- lightning-invoice/src/lib.rs | 80 +++++++++++++++---------------- lightning-invoice/tests/ser_de.rs | 6 +-- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs index 8bca12e344c..3f0548efb75 100644 --- a/lightning-invoice/src/de.rs +++ b/lightning-invoice/src/de.rs @@ -24,7 +24,7 @@ use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use secp256k1::PublicKey; use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, - SemanticError, PrivateRoute, Bolt11ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice, + Bolt11SemanticError, PrivateRoute, Bolt11ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice, constants, SignedRawBolt11Invoice, RawDataPart, InvoiceFeatures}; use self::hrp_sm::parse_hrp; @@ -715,8 +715,8 @@ impl From for ParseOrSemanticError { } } -impl From for ParseOrSemanticError { - fn from(e: SemanticError) -> Self { +impl From for ParseOrSemanticError { + fn from(e: Bolt11SemanticError) -> Self { ParseOrSemanticError::SemanticError(e) } } diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index dc13b5ec76a..21db4960417 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -139,7 +139,7 @@ pub enum ParseOrSemanticError { ParseError(Bolt11ParseError), /// The invoice could be decoded but violates the BOLT11 standard - SemanticError(crate::SemanticError), + SemanticError(crate::Bolt11SemanticError), } /// The number of bits used to represent timestamps as defined in BOLT 11. @@ -1154,16 +1154,16 @@ impl Bolt11Invoice { } /// Check that all mandatory fields are present - fn check_field_counts(&self) -> Result<(), SemanticError> { + fn check_field_counts(&self) -> Result<(), Bolt11SemanticError> { // "A writer MUST include exactly one p field […]." let payment_hash_cnt = self.tagged_fields().filter(|&tf| match *tf { TaggedField::PaymentHash(_) => true, _ => false, }).count(); if payment_hash_cnt < 1 { - return Err(SemanticError::NoPaymentHash); + return Err(Bolt11SemanticError::NoPaymentHash); } else if payment_hash_cnt > 1 { - return Err(SemanticError::MultiplePaymentHashes); + return Err(Bolt11SemanticError::MultiplePaymentHashes); } // "A writer MUST include either exactly one d or exactly one h field." @@ -1172,9 +1172,9 @@ impl Bolt11Invoice { _ => false, }).count(); if description_cnt < 1 { - return Err(SemanticError::NoDescription); + return Err(Bolt11SemanticError::NoDescription); } else if description_cnt > 1 { - return Err(SemanticError::MultipleDescriptions); + return Err(Bolt11SemanticError::MultipleDescriptions); } self.check_payment_secret()?; @@ -1183,33 +1183,33 @@ impl Bolt11Invoice { } /// Checks that there is exactly one payment secret field - fn check_payment_secret(&self) -> Result<(), SemanticError> { + fn check_payment_secret(&self) -> Result<(), Bolt11SemanticError> { // "A writer MUST include exactly one `s` field." let payment_secret_count = self.tagged_fields().filter(|&tf| match *tf { TaggedField::PaymentSecret(_) => true, _ => false, }).count(); if payment_secret_count < 1 { - return Err(SemanticError::NoPaymentSecret); + return Err(Bolt11SemanticError::NoPaymentSecret); } else if payment_secret_count > 1 { - return Err(SemanticError::MultiplePaymentSecrets); + return Err(Bolt11SemanticError::MultiplePaymentSecrets); } Ok(()) } /// Check that amount is a whole number of millisatoshis - fn check_amount(&self) -> Result<(), SemanticError> { + fn check_amount(&self) -> Result<(), Bolt11SemanticError> { if let Some(amount_pico_btc) = self.amount_pico_btc() { if amount_pico_btc % 10 != 0 { - return Err(SemanticError::ImpreciseAmount); + return Err(Bolt11SemanticError::ImpreciseAmount); } } Ok(()) } /// Check that feature bits are set as required - fn check_feature_bits(&self) -> Result<(), SemanticError> { + fn check_feature_bits(&self) -> Result<(), Bolt11SemanticError> { self.check_payment_secret()?; // "A writer MUST set an s field if and only if the payment_secret feature is set." @@ -1220,12 +1220,12 @@ impl Bolt11Invoice { _ => false, }); match features { - None => Err(SemanticError::InvalidFeatures), + None => Err(Bolt11SemanticError::InvalidFeatures), Some(TaggedField::Features(features)) => { if features.requires_unknown_bits() { - Err(SemanticError::InvalidFeatures) + Err(Bolt11SemanticError::InvalidFeatures) } else if !features.supports_payment_secret() { - Err(SemanticError::InvalidFeatures) + Err(Bolt11SemanticError::InvalidFeatures) } else { Ok(()) } @@ -1235,18 +1235,18 @@ impl Bolt11Invoice { } /// Check that the invoice is signed correctly and that key recovery works - pub fn check_signature(&self) -> Result<(), SemanticError> { + pub fn check_signature(&self) -> Result<(), Bolt11SemanticError> { match self.signed_invoice.recover_payee_pub_key() { Err(secp256k1::Error::InvalidRecoveryId) => - return Err(SemanticError::InvalidRecoveryId), + return Err(Bolt11SemanticError::InvalidRecoveryId), Err(secp256k1::Error::InvalidSignature) => - return Err(SemanticError::InvalidSignature), + return Err(Bolt11SemanticError::InvalidSignature), Err(e) => panic!("no other error may occur, got {:?}", e), Ok(_) => {}, } if !self.signed_invoice.check_signature() { - return Err(SemanticError::InvalidSignature); + return Err(Bolt11SemanticError::InvalidSignature); } Ok(()) @@ -1272,7 +1272,7 @@ impl Bolt11Invoice { /// /// assert!(Bolt11Invoice::from_signed(signed).is_ok()); /// ``` - pub fn from_signed(signed_invoice: SignedRawBolt11Invoice) -> Result { + pub fn from_signed(signed_invoice: SignedRawBolt11Invoice) -> Result { let invoice = Bolt11Invoice { signed_invoice, }; @@ -1654,7 +1654,7 @@ impl std::error::Error for CreationError { } /// Errors that may occur when converting a [`RawBolt11Invoice`] to a [`Bolt11Invoice`]. They relate to /// the requirements sections in BOLT #11 #[derive(Eq, PartialEq, Debug, Clone)] -pub enum SemanticError { +pub enum Bolt11SemanticError { /// The invoice is missing the mandatory payment hash NoPaymentHash, @@ -1687,25 +1687,25 @@ pub enum SemanticError { ImpreciseAmount, } -impl Display for SemanticError { +impl Display for Bolt11SemanticError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - SemanticError::NoPaymentHash => f.write_str("The invoice is missing the mandatory payment hash"), - SemanticError::MultiplePaymentHashes => f.write_str("The invoice has multiple payment hashes which isn't allowed"), - SemanticError::NoDescription => f.write_str("No description or description hash are part of the invoice"), - SemanticError::MultipleDescriptions => f.write_str("The invoice contains multiple descriptions and/or description hashes which isn't allowed"), - SemanticError::NoPaymentSecret => f.write_str("The invoice is missing the mandatory payment secret"), - SemanticError::MultiplePaymentSecrets => f.write_str("The invoice contains multiple payment secrets"), - SemanticError::InvalidFeatures => f.write_str("The invoice's features are invalid"), - SemanticError::InvalidRecoveryId => f.write_str("The recovery id doesn't fit the signature/pub key"), - SemanticError::InvalidSignature => f.write_str("The invoice's signature is invalid"), - SemanticError::ImpreciseAmount => f.write_str("The invoice's amount was not a whole number of millisatoshis"), + Bolt11SemanticError::NoPaymentHash => f.write_str("The invoice is missing the mandatory payment hash"), + Bolt11SemanticError::MultiplePaymentHashes => f.write_str("The invoice has multiple payment hashes which isn't allowed"), + Bolt11SemanticError::NoDescription => f.write_str("No description or description hash are part of the invoice"), + Bolt11SemanticError::MultipleDescriptions => f.write_str("The invoice contains multiple descriptions and/or description hashes which isn't allowed"), + Bolt11SemanticError::NoPaymentSecret => f.write_str("The invoice is missing the mandatory payment secret"), + Bolt11SemanticError::MultiplePaymentSecrets => f.write_str("The invoice contains multiple payment secrets"), + Bolt11SemanticError::InvalidFeatures => f.write_str("The invoice's features are invalid"), + Bolt11SemanticError::InvalidRecoveryId => f.write_str("The recovery id doesn't fit the signature/pub key"), + Bolt11SemanticError::InvalidSignature => f.write_str("The invoice's signature is invalid"), + Bolt11SemanticError::ImpreciseAmount => f.write_str("The invoice's amount was not a whole number of millisatoshis"), } } } #[cfg(feature = "std")] -impl std::error::Error for SemanticError { } +impl std::error::Error for Bolt11SemanticError { } /// When signing using a fallible method either an user-supplied `SignError` or a [`CreationError`] /// may occur. @@ -1867,7 +1867,7 @@ mod test { use secp256k1::Secp256k1; use secp256k1::SecretKey; use crate::{Bolt11Invoice, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, - SemanticError}; + Bolt11SemanticError}; let private_key = SecretKey::from_slice(&[42; 32]).unwrap(); let payment_secret = lightning::ln::PaymentSecret([21; 32]); @@ -1898,7 +1898,7 @@ mod test { invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::InvalidFeatures)); // Missing feature bits let invoice = { @@ -1907,7 +1907,7 @@ mod test { invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::InvalidFeatures)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::InvalidFeatures)); let mut payment_secret_features = InvoiceFeatures::empty(); payment_secret_features.set_payment_secret_required(); @@ -1926,7 +1926,7 @@ mod test { let invoice = invoice_template.clone(); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret)); // No payment secret or feature bits let invoice = { @@ -1934,7 +1934,7 @@ mod test { invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret)); // Missing payment secret let invoice = { @@ -1942,7 +1942,7 @@ mod test { invoice.data.tagged_fields.push(Features(payment_secret_features).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::NoPaymentSecret)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret)); // Multiple payment secrets let invoice = { @@ -1951,7 +1951,7 @@ mod test { invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); - assert_eq!(Bolt11Invoice::from_signed(invoice), Err(SemanticError::MultiplePaymentSecrets)); + assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::MultiplePaymentSecrets)); } #[test] diff --git a/lightning-invoice/tests/ser_de.rs b/lightning-invoice/tests/ser_de.rs index 02c0aa58c21..e21b82eae3c 100644 --- a/lightning-invoice/tests/ser_de.rs +++ b/lightning-invoice/tests/ser_de.rs @@ -421,7 +421,7 @@ fn test_bolt_invalid_invoices() { // Tests the BOLT 11 invalid invoice test vectors assert_eq!(Bolt11Invoice::from_str( "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q4psqqqqqqqqqqqqqqqqsgqtqyx5vggfcsll4wu246hz02kp85x4katwsk9639we5n5yngc3yhqkm35jnjw4len8vrnqnf5ejh0mzj9n3vz2px97evektfm2l6wqccp3y7372" - ), Err(ParseOrSemanticError::SemanticError(SemanticError::InvalidFeatures))); + ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::InvalidFeatures))); assert_eq!(Bolt11Invoice::from_str( "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt" ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::InvalidChecksum)))); @@ -433,7 +433,7 @@ fn test_bolt_invalid_invoices() { ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::Bech32Error(bech32::Error::MixedCase)))); assert_eq!(Bolt11Invoice::from_str( "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqwgt7mcn5yqw3yx0w94pswkpq6j9uh6xfqqqtsk4tnarugeektd4hg5975x9am52rz4qskukxdmjemg92vvqz8nvmsye63r5ykel43pgz7zq0g2" - ), Err(ParseOrSemanticError::SemanticError(SemanticError::InvalidSignature))); + ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::InvalidSignature))); assert_eq!(Bolt11Invoice::from_str( "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh" ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::TooShortDataPart))); @@ -442,5 +442,5 @@ fn test_bolt_invalid_invoices() { ), Err(ParseOrSemanticError::ParseError(Bolt11ParseError::UnknownSiPrefix))); assert_eq!(Bolt11Invoice::from_str( "lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgq0lzc236j96a95uv0m3umg28gclm5lqxtqqwk32uuk4k6673k6n5kfvx3d2h8s295fad45fdhmusm8sjudfhlf6dcsxmfvkeywmjdkxcp99202x" - ), Err(ParseOrSemanticError::SemanticError(SemanticError::ImpreciseAmount))); + ), Err(ParseOrSemanticError::SemanticError(Bolt11SemanticError::ImpreciseAmount))); } From 8c4a85b35700d0e4b254c31a8d3171b14140038a Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Fri, 14 Jul 2023 14:41:58 -0500 Subject: [PATCH 11/13] Qualify the BOLT 11 invoice features type A previous commit qualified the BOLT 11 invoice type, so any related types should be similarly qualified, if public. --- lightning-invoice/src/de.rs | 8 ++-- lightning-invoice/src/lib.rs | 22 ++++----- lightning/src/ln/channelmanager.rs | 10 ++--- lightning/src/ln/features.rs | 64 +++++++++++++-------------- lightning/src/ln/onion_route_tests.rs | 4 +- lightning/src/ln/payment_tests.rs | 20 ++++----- lightning/src/routing/router.rs | 28 ++++++------ 7 files changed, 78 insertions(+), 78 deletions(-) diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs index 3f0548efb75..a62adaec1aa 100644 --- a/lightning-invoice/src/de.rs +++ b/lightning-invoice/src/de.rs @@ -25,7 +25,7 @@ use secp256k1::PublicKey; use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, Bolt11SemanticError, PrivateRoute, Bolt11ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice, - constants, SignedRawBolt11Invoice, RawDataPart, InvoiceFeatures}; + constants, SignedRawBolt11Invoice, RawDataPart, Bolt11InvoiceFeatures}; use self::hrp_sm::parse_hrp; @@ -463,7 +463,7 @@ impl FromBase32 for TaggedField { constants::TAG_PAYMENT_METADATA => Ok(TaggedField::PaymentMetadata(Vec::::from_base32(field_data)?)), constants::TAG_FEATURES => - Ok(TaggedField::Features(InvoiceFeatures::from_base32(field_data)?)), + Ok(TaggedField::Features(Bolt11InvoiceFeatures::from_base32(field_data)?)), _ => { // "A reader MUST skip over unknown fields" Err(Bolt11ParseError::Skip) @@ -969,14 +969,14 @@ mod test { #[test] fn test_payment_secret_and_features_de_and_ser() { - use lightning::ln::features::InvoiceFeatures; + use lightning::ln::features::Bolt11InvoiceFeatures; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use crate::TaggedField::*; use crate::{SiPrefix, SignedRawBolt11Invoice, InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp}; // Feature bits 9, 15, and 99 are set. - let expected_features = InvoiceFeatures::from_le_bytes(vec![0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8]); + let expected_features = Bolt11InvoiceFeatures::from_le_bytes(vec![0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8]); let invoice_str = "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q5sqqqqqqqqqqqqqqqpqsq67gye39hfg3zd8rgc80k32tvy9xk2xunwm5lzexnvpx6fd77en8qaq424dxgt56cag2dpt359k3ssyhetktkpqh24jqnjyw6uqd08sgptq44qu"; let invoice = SignedRawBolt11Invoice { raw_invoice: RawBolt11Invoice { diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 21db4960417..ee65f2fd6df 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -51,7 +51,7 @@ use bitcoin::{Address, Network, PubkeyHash, ScriptHash}; use bitcoin::util::address::{Payload, WitnessVersion}; use bitcoin_hashes::{Hash, sha256}; use lightning::ln::PaymentSecret; -use lightning::ln::features::InvoiceFeatures; +use lightning::ln::features::Bolt11InvoiceFeatures; #[cfg(any(doc, test))] use lightning::routing::gossip::RoutingFees; use lightning::routing::router::RouteHint; @@ -448,7 +448,7 @@ pub enum TaggedField { PrivateRoute(PrivateRoute), PaymentSecret(PaymentSecret), PaymentMetadata(Vec), - Features(InvoiceFeatures), + Features(Bolt11InvoiceFeatures), } /// SHA-256 hash @@ -744,7 +744,7 @@ impl InvoiceBui } self.tagged_fields.push(TaggedField::PaymentSecret(payment_secret)); if !found_features { - let mut features = InvoiceFeatures::empty(); + let mut features = Bolt11InvoiceFeatures::empty(); features.set_variable_length_onion_required(); features.set_payment_secret_required(); self.tagged_fields.push(TaggedField::Features(features)); @@ -770,7 +770,7 @@ impl InvoiceBui } } if !found_features { - let mut features = InvoiceFeatures::empty(); + let mut features = Bolt11InvoiceFeatures::empty(); features.set_payment_metadata_optional(); self.tagged_fields.push(TaggedField::Features(features)); } @@ -1059,7 +1059,7 @@ impl RawBolt11Invoice { find_extract!(self.known_tagged_fields(), TaggedField::PaymentMetadata(ref x), x) } - pub fn features(&self) -> Option<&InvoiceFeatures> { + pub fn features(&self) -> Option<&Bolt11InvoiceFeatures> { find_extract!(self.known_tagged_fields(), TaggedField::Features(ref x), x) } @@ -1336,7 +1336,7 @@ impl Bolt11Invoice { } /// Get the invoice features if they were included in the invoice - pub fn features(&self) -> Option<&InvoiceFeatures> { + pub fn features(&self) -> Option<&Bolt11InvoiceFeatures> { self.signed_invoice.features() } @@ -1863,7 +1863,7 @@ mod test { #[test] fn test_check_feature_bits() { use crate::TaggedField::*; - use lightning::ln::features::InvoiceFeatures; + use lightning::ln::features::Bolt11InvoiceFeatures; use secp256k1::Secp256k1; use secp256k1::SecretKey; use crate::{Bolt11Invoice, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, @@ -1904,12 +1904,12 @@ mod test { let invoice = { let mut invoice = invoice_template.clone(); invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); - invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into()); + invoice.data.tagged_fields.push(Features(Bolt11InvoiceFeatures::empty()).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::InvalidFeatures)); - let mut payment_secret_features = InvoiceFeatures::empty(); + let mut payment_secret_features = Bolt11InvoiceFeatures::empty(); payment_secret_features.set_payment_secret_required(); // Including payment secret and feature bits @@ -1931,7 +1931,7 @@ mod test { // No payment secret or feature bits let invoice = { let mut invoice = invoice_template.clone(); - invoice.data.tagged_fields.push(Features(InvoiceFeatures::empty()).into()); + invoice.data.tagged_fields.push(Features(Bolt11InvoiceFeatures::empty()).into()); invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) }.unwrap(); assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret)); @@ -2147,7 +2147,7 @@ mod test { assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&[21;32][..]).unwrap()); assert_eq!(invoice.payment_secret(), &PaymentSecret([42; 32])); - let mut expected_features = InvoiceFeatures::empty(); + let mut expected_features = Bolt11InvoiceFeatures::empty(); expected_features.set_variable_length_onion_required(); expected_features.set_payment_secret_required(); expected_features.set_basic_mpp_optional(); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 07bb18ff37c..a03a444e25d 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -43,7 +43,7 @@ use crate::ln::{inbound_payment, PaymentHash, PaymentPreimage, PaymentSecret}; use crate::ln::channel::{Channel, ChannelContext, ChannelError, ChannelUpdateStatus, ShutdownResult, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel}; use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; #[cfg(any(feature = "_test_utils", test))] -use crate::ln::features::InvoiceFeatures; +use crate::ln::features::Bolt11InvoiceFeatures; use crate::routing::gossip::NetworkGraph; use crate::routing::router::{BlindedTail, DefaultRouter, InFlightHtlcs, Path, Payee, PaymentParameters, Route, RouteParameters, Router}; use crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParameters}; @@ -6928,13 +6928,13 @@ where provided_node_features(&self.default_configuration) } - /// Fetches the set of [`InvoiceFeatures`] flags which are provided by or required by + /// Fetches the set of [`Bolt11InvoiceFeatures`] flags which are provided by or required by /// [`ChannelManager`]. /// /// Note that the invoice feature flags can vary depending on if the invoice is a "phantom invoice" /// or not. Thus, this method is not public. #[cfg(any(feature = "_test_utils", test))] - pub fn invoice_features(&self) -> InvoiceFeatures { + pub fn invoice_features(&self) -> Bolt11InvoiceFeatures { provided_invoice_features(&self.default_configuration) } @@ -7366,13 +7366,13 @@ pub(crate) fn provided_node_features(config: &UserConfig) -> NodeFeatures { provided_init_features(config).to_context() } -/// Fetches the set of [`InvoiceFeatures`] flags which are provided by or required by +/// Fetches the set of [`Bolt11InvoiceFeatures`] flags which are provided by or required by /// [`ChannelManager`]. /// /// Note that the invoice feature flags can vary depending on if the invoice is a "phantom invoice" /// or not. Thus, this method is not public. #[cfg(any(feature = "_test_utils", test))] -pub(crate) fn provided_invoice_features(config: &UserConfig) -> InvoiceFeatures { +pub(crate) fn provided_invoice_features(config: &UserConfig) -> Bolt11InvoiceFeatures { provided_init_features(config).to_context() } diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index ca6ea70b61d..6309eea413a 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -168,7 +168,7 @@ mod sealed { ZeroConf | Keysend, ]); define_context!(ChannelContext, []); - define_context!(InvoiceContext, [ + define_context!(Bolt11InvoiceContext, [ // Byte 0 , // Byte 1 @@ -369,17 +369,17 @@ mod sealed { define_feature!(7, GossipQueries, [InitContext, NodeContext], "Feature flags for `gossip_queries`.", set_gossip_queries_optional, set_gossip_queries_required, supports_gossip_queries, requires_gossip_queries); - define_feature!(9, VariableLengthOnion, [InitContext, NodeContext, InvoiceContext], + define_feature!(9, VariableLengthOnion, [InitContext, NodeContext, Bolt11InvoiceContext], "Feature flags for `var_onion_optin`.", set_variable_length_onion_optional, set_variable_length_onion_required, supports_variable_length_onion, requires_variable_length_onion); define_feature!(13, StaticRemoteKey, [InitContext, NodeContext, ChannelTypeContext], "Feature flags for `option_static_remotekey`.", set_static_remote_key_optional, set_static_remote_key_required, supports_static_remote_key, requires_static_remote_key); - define_feature!(15, PaymentSecret, [InitContext, NodeContext, InvoiceContext], + define_feature!(15, PaymentSecret, [InitContext, NodeContext, Bolt11InvoiceContext], "Feature flags for `payment_secret`.", set_payment_secret_optional, set_payment_secret_required, supports_payment_secret, requires_payment_secret); - define_feature!(17, BasicMPP, [InitContext, NodeContext, InvoiceContext, Bolt12InvoiceContext], + define_feature!(17, BasicMPP, [InitContext, NodeContext, Bolt11InvoiceContext, Bolt12InvoiceContext], "Feature flags for `basic_mpp`.", set_basic_mpp_optional, set_basic_mpp_required, supports_basic_mpp, requires_basic_mpp); define_feature!(19, Wumbo, [InitContext, NodeContext], @@ -403,7 +403,7 @@ mod sealed { define_feature!(47, SCIDPrivacy, [InitContext, NodeContext, ChannelTypeContext], "Feature flags for only forwarding with SCID aliasing. Called `option_scid_alias` in the BOLTs", set_scid_privacy_optional, set_scid_privacy_required, supports_scid_privacy, requires_scid_privacy); - define_feature!(49, PaymentMetadata, [InvoiceContext], + define_feature!(49, PaymentMetadata, [Bolt11InvoiceContext], "Feature flags for payment metadata in invoices.", set_payment_metadata_optional, set_payment_metadata_required, supports_payment_metadata, requires_payment_metadata); define_feature!(51, ZeroConf, [InitContext, NodeContext, ChannelTypeContext], @@ -416,7 +416,7 @@ mod sealed { #[cfg(test)] define_feature!(123456789, UnknownFeature, - [NodeContext, ChannelContext, InvoiceContext, OfferContext, InvoiceRequestContext, Bolt12InvoiceContext, BlindedHopContext], + [NodeContext, ChannelContext, Bolt11InvoiceContext, OfferContext, InvoiceRequestContext, Bolt12InvoiceContext, BlindedHopContext], "Feature flags for an unknown feature used in testing.", set_unknown_feature_optional, set_unknown_feature_required, supports_unknown_test_feature, requires_unknown_test_feature); } @@ -492,7 +492,7 @@ pub type NodeFeatures = Features; /// Features used within a `channel_announcement` message. pub type ChannelFeatures = Features; /// Features used within an invoice. -pub type InvoiceFeatures = Features; +pub type Bolt11InvoiceFeatures = Features; /// Features used within an `offer`. pub type OfferFeatures = Features; /// Features used within an `invoice_request`. @@ -538,8 +538,8 @@ impl InitFeatures { } } -impl InvoiceFeatures { - /// Converts `InvoiceFeatures` to `Features`. Only known `InvoiceFeatures` relevant to +impl Bolt11InvoiceFeatures { + /// Converts `Bolt11InvoiceFeatures` to `Features`. Only known `Bolt11InvoiceFeatures` relevant to /// context `C` are included in the result. pub(crate) fn to_context(&self) -> Features { self.to_context_internal() @@ -549,15 +549,15 @@ impl InvoiceFeatures { /// features (since they were not announced in a node announcement). However, keysend payments /// don't have an invoice to pull the payee's features from, so this method is provided for use in /// [`PaymentParameters::for_keysend`], thus omitting the need for payers to manually construct an - /// `InvoiceFeatures` for [`find_route`]. + /// `Bolt11InvoiceFeatures` for [`find_route`]. /// /// MPP keysend is not widely supported yet, so we parameterize support to allow the user to /// choose whether their router should find multi-part routes. /// /// [`PaymentParameters::for_keysend`]: crate::routing::router::PaymentParameters::for_keysend /// [`find_route`]: crate::routing::router::find_route - pub(crate) fn for_keysend(allow_mpp: bool) -> InvoiceFeatures { - let mut res = InvoiceFeatures::empty(); + pub(crate) fn for_keysend(allow_mpp: bool) -> Bolt11InvoiceFeatures { + let mut res = Bolt11InvoiceFeatures::empty(); res.set_variable_length_onion_optional(); if allow_mpp { res.set_basic_mpp_optional(); @@ -567,8 +567,8 @@ impl InvoiceFeatures { } impl Bolt12InvoiceFeatures { - /// Converts `Bolt12InvoiceFeatures` to `Features`. Only known `Bolt12InvoiceFeatures` relevant - /// to context `C` are included in the result. + /// Converts [`Bolt12InvoiceFeatures`] to [`Features`]. Only known [`Bolt12InvoiceFeatures`] + /// relevant to context `C` are included in the result. pub(crate) fn to_context(&self) -> Features { self.to_context_internal() } @@ -604,7 +604,7 @@ impl ChannelTypeFeatures { } } -impl ToBase32 for InvoiceFeatures { +impl ToBase32 for Bolt11InvoiceFeatures { fn write_base32(&self, writer: &mut W) -> Result<(), ::Err> { // Explanation for the "4": the normal way to round up when dividing is to add the divisor // minus one before dividing @@ -634,16 +634,16 @@ impl ToBase32 for InvoiceFeatures { } } -impl Base32Len for InvoiceFeatures { +impl Base32Len for Bolt11InvoiceFeatures { fn base32_len(&self) -> usize { self.to_base32().len() } } -impl FromBase32 for InvoiceFeatures { +impl FromBase32 for Bolt11InvoiceFeatures { type Err = bech32::Error; - fn from_base32(field_data: &[u5]) -> Result { + fn from_base32(field_data: &[u5]) -> Result { // Explanation for the "7": the normal way to round up when dividing is to add the divisor // minus one before dividing let length_bytes = (field_data.len() * 5 + 7) / 8 as usize; @@ -662,7 +662,7 @@ impl FromBase32 for InvoiceFeatures { while !res_bytes.is_empty() && res_bytes[res_bytes.len() - 1] == 0 { res_bytes.pop(); } - Ok(InvoiceFeatures::from_le_bytes(res_bytes)) + Ok(Bolt11InvoiceFeatures::from_le_bytes(res_bytes)) } } @@ -903,7 +903,7 @@ macro_rules! impl_feature_len_prefixed_write { impl_feature_len_prefixed_write!(InitFeatures); impl_feature_len_prefixed_write!(ChannelFeatures); impl_feature_len_prefixed_write!(NodeFeatures); -impl_feature_len_prefixed_write!(InvoiceFeatures); +impl_feature_len_prefixed_write!(Bolt11InvoiceFeatures); impl_feature_len_prefixed_write!(Bolt12InvoiceFeatures); impl_feature_len_prefixed_write!(BlindedHopFeatures); @@ -943,7 +943,7 @@ impl Readable for WithoutLength> { #[cfg(test)] mod tests { - use super::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, InvoiceFeatures, NodeFeatures, OfferFeatures, sealed}; + use super::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, Bolt11InvoiceFeatures, NodeFeatures, OfferFeatures, sealed}; use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5}; use crate::util::ser::{Readable, WithoutLength, Writeable}; @@ -1058,17 +1058,17 @@ mod tests { fn convert_to_context_with_unknown_flags() { // Ensure the `from` context has fewer known feature bytes than the `to` context. assert!(::KNOWN_FEATURE_MASK.len() < - ::KNOWN_FEATURE_MASK.len()); + ::KNOWN_FEATURE_MASK.len()); let mut channel_features = ChannelFeatures::empty(); channel_features.set_unknown_feature_optional(); assert!(channel_features.supports_unknown_bits()); - let invoice_features: InvoiceFeatures = channel_features.to_context_internal(); + let invoice_features: Bolt11InvoiceFeatures = channel_features.to_context_internal(); assert!(!invoice_features.supports_unknown_bits()); } #[test] fn set_feature_bits() { - let mut features = InvoiceFeatures::empty(); + let mut features = Bolt11InvoiceFeatures::empty(); features.set_basic_mpp_optional(); features.set_payment_secret_required(); assert!(features.supports_basic_mpp()); @@ -1079,7 +1079,7 @@ mod tests { #[test] fn set_custom_bits() { - let mut features = InvoiceFeatures::empty(); + let mut features = Bolt11InvoiceFeatures::empty(); features.set_variable_length_onion_optional(); assert_eq!(features.flags[1], 0b00000010); @@ -1089,19 +1089,19 @@ mod tests { assert_eq!(features.flags[31], 0b00000000); assert_eq!(features.flags[32], 0b00000101); - let known_bit = ::EVEN_BIT; - let byte_offset = ::BYTE_OFFSET; + let known_bit = ::EVEN_BIT; + let byte_offset = ::BYTE_OFFSET; assert_eq!(byte_offset, 1); assert_eq!(features.flags[byte_offset], 0b00000010); assert!(features.set_required_custom_bit(known_bit).is_err()); assert_eq!(features.flags[byte_offset], 0b00000010); - let mut features = InvoiceFeatures::empty(); + let mut features = Bolt11InvoiceFeatures::empty(); assert!(features.set_optional_custom_bit(256).is_ok()); assert!(features.set_optional_custom_bit(259).is_ok()); assert_eq!(features.flags[32], 0b00001010); - let mut features = InvoiceFeatures::empty(); + let mut features = Bolt11InvoiceFeatures::empty(); assert!(features.set_required_custom_bit(257).is_ok()); assert!(features.set_required_custom_bit(258).is_ok()); assert_eq!(features.flags[32], 0b00000101); @@ -1138,7 +1138,7 @@ mod tests { u5::try_from_u8(16).unwrap(), u5::try_from_u8(1).unwrap(), ]; - let features = InvoiceFeatures::from_le_bytes(vec![1, 2, 3, 4, 5, 42, 100, 101]); + let features = Bolt11InvoiceFeatures::from_le_bytes(vec![1, 2, 3, 4, 5, 42, 100, 101]); // Test length calculation. assert_eq!(features.base32_len(), 13); @@ -1148,13 +1148,13 @@ mod tests { assert_eq!(features_as_u5s, features_serialized); // Test deserialization. - let features_deserialized = InvoiceFeatures::from_base32(&features_as_u5s).unwrap(); + let features_deserialized = Bolt11InvoiceFeatures::from_base32(&features_as_u5s).unwrap(); assert_eq!(features, features_deserialized); } #[test] fn test_channel_type_mapping() { - // If we map an InvoiceFeatures with StaticRemoteKey optional, it should map into a + // If we map an Bolt11InvoiceFeatures with StaticRemoteKey optional, it should map into a // required-StaticRemoteKey ChannelTypeFeatures. let mut init_features = InitFeatures::empty(); init_features.set_static_remote_key_optional(); diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs index e5faedfe7fc..1230d48ba1e 100644 --- a/lightning/src/ln/onion_route_tests.rs +++ b/lightning/src/ln/onion_route_tests.rs @@ -20,7 +20,7 @@ use crate::ln::channelmanager::{HTLCForwardInfo, FailureCode, CLTV_FAR_FAR_AWAY, use crate::ln::onion_utils; use crate::routing::gossip::{NetworkUpdate, RoutingFees}; use crate::routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop}; -use crate::ln::features::{InitFeatures, InvoiceFeatures}; +use crate::ln::features::{InitFeatures, Bolt11InvoiceFeatures}; use crate::ln::msgs; use crate::ln::msgs::{ChannelMessageHandler, ChannelUpdate}; use crate::ln::wire::Encode; @@ -862,7 +862,7 @@ fn test_always_create_tlv_format_onion_payloads() { create_announced_chan_between_nodes(&nodes, 1, 2); let payment_params = PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV) - .with_bolt11_features(InvoiceFeatures::empty()).unwrap(); + .with_bolt11_features(Bolt11InvoiceFeatures::empty()).unwrap(); let (route, _payment_hash, _payment_preimage, _payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, 40000); let hops = &route.paths[0].hops; diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index fa607f68098..b23b6364182 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -18,7 +18,7 @@ use crate::chain::transaction::OutPoint; use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentFailureReason}; use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS; use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS, RecentPaymentDetails, RecipientOnionFields, HTLCForwardInfo, PendingHTLCRouting, PendingAddHTLCInfo}; -use crate::ln::features::InvoiceFeatures; +use crate::ln::features::Bolt11InvoiceFeatures; use crate::ln::{msgs, PaymentSecret, PaymentPreimage}; use crate::ln::msgs::ChannelMessageHandler; use crate::ln::outbound_payment::Retry; @@ -1903,7 +1903,7 @@ fn do_automatic_retries(test: AutoRetry) { #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; let amt_msat = 1000; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2122,7 +2122,7 @@ fn auto_retry_partial_failure() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2334,7 +2334,7 @@ fn auto_retry_zero_attempts_send_error() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2374,7 +2374,7 @@ fn fails_paying_after_rejected_by_payee() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2421,7 +2421,7 @@ fn retry_multi_path_single_failed_payment() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2514,7 +2514,7 @@ fn immediate_retry_on_failure() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2602,7 +2602,7 @@ fn no_extra_retries_on_back_to_back_fail() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2804,7 +2804,7 @@ fn test_simple_partial_retry() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); @@ -2970,7 +2970,7 @@ fn test_threaded_payment_retries() { let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60; #[cfg(not(feature = "std"))] let payment_expiry_secs = 60 * 60; - let mut invoice_features = InvoiceFeatures::empty(); + let mut invoice_features = Bolt11InvoiceFeatures::empty(); invoice_features.set_variable_length_onion_required(); invoice_features.set_payment_secret_required(); invoice_features.set_basic_mpp_optional(); diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 141e7d26cc1..9242e98b1ab 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -16,7 +16,7 @@ use bitcoin::hashes::sha256::Hash as Sha256; use crate::blinded_path::{BlindedHop, BlindedPath}; use crate::ln::PaymentHash; use crate::ln::channelmanager::{ChannelDetails, PaymentId}; -use crate::ln::features::{Bolt12InvoiceFeatures, ChannelFeatures, InvoiceFeatures, NodeFeatures}; +use crate::ln::features::{Bolt11InvoiceFeatures, Bolt12InvoiceFeatures, ChannelFeatures, NodeFeatures}; use crate::ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT}; use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice}; use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId, RoutingFees}; @@ -640,7 +640,7 @@ impl PaymentParameters { /// [`RecipientOnionFields::secret_only`]: crate::ln::channelmanager::RecipientOnionFields::secret_only pub fn for_keysend(payee_pubkey: PublicKey, final_cltv_expiry_delta: u32, allow_mpp: bool) -> Self { Self::from_node_id(payee_pubkey, final_cltv_expiry_delta) - .with_bolt11_features(InvoiceFeatures::for_keysend(allow_mpp)) + .with_bolt11_features(Bolt11InvoiceFeatures::for_keysend(allow_mpp)) .expect("PaymentParameters::from_node_id should always initialize the payee as unblinded") } @@ -680,7 +680,7 @@ impl PaymentParameters { /// [`PaymentParameters::from_bolt12_invoice`]. /// /// This is not exported to bindings users since bindings don't support move semantics - pub fn with_bolt11_features(self, features: InvoiceFeatures) -> Result { + pub fn with_bolt11_features(self, features: Bolt11InvoiceFeatures) -> Result { match self.payee { Payee::Blinded { .. } => Err(()), Payee::Clear { route_hints, node_id, final_cltv_expiry_delta, .. } => @@ -766,7 +766,7 @@ pub enum Payee { /// does not contain any features. /// /// [`for_keysend`]: PaymentParameters::for_keysend - features: Option, + features: Option, /// The minimum CLTV delta at the end of the route. This value must not be zero. final_cltv_expiry_delta: u32, }, @@ -819,11 +819,11 @@ impl Payee { } enum FeaturesRef<'a> { - Bolt11(&'a InvoiceFeatures), + Bolt11(&'a Bolt11InvoiceFeatures), Bolt12(&'a Bolt12InvoiceFeatures), } enum Features { - Bolt11(InvoiceFeatures), + Bolt11(Bolt11InvoiceFeatures), Bolt12(Bolt12InvoiceFeatures), } @@ -834,7 +834,7 @@ impl Features { _ => None, } } - fn bolt11(self) -> Option { + fn bolt11(self) -> Option { match self { Self::Bolt11(f) => Some(f), _ => None, @@ -6104,7 +6104,7 @@ mod tests { let params = ProbabilisticScoringFeeParameters::default(); let mut scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &graph, &logger); - let features = super::InvoiceFeatures::empty(); + let features = super::Bolt11InvoiceFeatures::empty(); super::bench_utils::generate_test_routes(&graph, &mut scorer, ¶ms, features, random_init_seed(), 0, 2); } @@ -6680,7 +6680,7 @@ pub(crate) mod bench_utils { use crate::chain::transaction::OutPoint; use crate::sign::{EntropySource, KeysManager}; use crate::ln::channelmanager::{self, ChannelCounterparty, ChannelDetails}; - use crate::ln::features::InvoiceFeatures; + use crate::ln::features::Bolt11InvoiceFeatures; use crate::routing::gossip::NetworkGraph; use crate::util::config::UserConfig; use crate::util::ser::ReadableArgs; @@ -6772,7 +6772,7 @@ pub(crate) mod bench_utils { } pub(crate) fn generate_test_routes(graph: &NetworkGraph<&TestLogger>, scorer: &mut S, - score_params: &S::ScoreParams, features: InvoiceFeatures, mut seed: u64, + score_params: &S::ScoreParams, features: Bolt11InvoiceFeatures, mut seed: u64, starting_amount: u64, route_count: usize, ) -> Vec<(ChannelDetails, PaymentParameters, u64)> { let payer = payer_pubkey(); @@ -6853,7 +6853,7 @@ pub mod benches { use super::*; use crate::sign::{EntropySource, KeysManager}; use crate::ln::channelmanager; - use crate::ln::features::InvoiceFeatures; + use crate::ln::features::Bolt11InvoiceFeatures; use crate::routing::gossip::NetworkGraph; use crate::routing::scoring::{FixedPenaltyScorer, ProbabilisticScorer, ProbabilisticScoringFeeParameters, ProbabilisticScoringDecayParameters}; use crate::util::config::UserConfig; @@ -6871,7 +6871,7 @@ pub mod benches { let logger = TestLogger::new(); let network_graph = bench_utils::read_network_graph(&logger).unwrap(); let scorer = FixedPenaltyScorer::with_penalty(0); - generate_routes(bench, &network_graph, scorer, &(), InvoiceFeatures::empty(), 0, + generate_routes(bench, &network_graph, scorer, &(), Bolt11InvoiceFeatures::empty(), 0, "generate_routes_with_zero_penalty_scorer"); } @@ -6889,7 +6889,7 @@ pub mod benches { let network_graph = bench_utils::read_network_graph(&logger).unwrap(); let params = ProbabilisticScoringFeeParameters::default(); let scorer = ProbabilisticScorer::new(ProbabilisticScoringDecayParameters::default(), &network_graph, &logger); - generate_routes(bench, &network_graph, scorer, ¶ms, InvoiceFeatures::empty(), 0, + generate_routes(bench, &network_graph, scorer, ¶ms, Bolt11InvoiceFeatures::empty(), 0, "generate_routes_with_probabilistic_scorer"); } @@ -6915,7 +6915,7 @@ pub mod benches { fn generate_routes( bench: &mut Criterion, graph: &NetworkGraph<&TestLogger>, mut scorer: S, - score_params: &S::ScoreParams, features: InvoiceFeatures, starting_amount: u64, + score_params: &S::ScoreParams, features: Bolt11InvoiceFeatures, starting_amount: u64, bench_name: &'static str, ) { let payer = bench_utils::payer_pubkey(); From a28c90a1b37f5a3fe371ca91ea5e150f2653f320 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Fri, 14 Jul 2023 15:53:07 -0500 Subject: [PATCH 12/13] Qualify the BOLT 11 invoice signature type A previous commit qualified the BOLT 11 invoice type, so any related types should be similarly qualified, if public. --- lightning-invoice/src/de.rs | 18 +++++++++--------- lightning-invoice/src/lib.rs | 20 ++++++++++---------- lightning-invoice/src/ser.rs | 4 ++-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lightning-invoice/src/de.rs b/lightning-invoice/src/de.rs index a62adaec1aa..5bfa9a042c3 100644 --- a/lightning-invoice/src/de.rs +++ b/lightning-invoice/src/de.rs @@ -23,7 +23,7 @@ use num_traits::{CheckedAdd, CheckedMul}; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use secp256k1::PublicKey; -use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, +use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, Bolt11InvoiceSignature, PositiveTimestamp, Bolt11SemanticError, PrivateRoute, Bolt11ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice, constants, SignedRawBolt11Invoice, RawDataPart, Bolt11InvoiceFeatures}; @@ -292,7 +292,7 @@ impl FromStr for SignedRawBolt11Invoice { hrp.as_bytes(), &data[..data.len()-104] ), - signature: InvoiceSignature::from_base32(&data[data.len()-104..])?, + signature: Bolt11InvoiceSignature::from_base32(&data[data.len()-104..])?, }) } } @@ -365,17 +365,17 @@ impl FromBase32 for PositiveTimestamp { } } -impl FromBase32 for InvoiceSignature { +impl FromBase32 for Bolt11InvoiceSignature { type Err = Bolt11ParseError; fn from_base32(signature: &[u5]) -> Result { if signature.len() != 104 { - return Err(Bolt11ParseError::InvalidSliceLength("InvoiceSignature::from_base32()".into())); + return Err(Bolt11ParseError::InvalidSliceLength("Bolt11InvoiceSignature::from_base32()".into())); } let recoverable_signature_bytes = Vec::::from_base32(signature)?; let signature = &recoverable_signature_bytes[0..64]; let recovery_id = RecoveryId::from_i32(recoverable_signature_bytes[64] as i32)?; - Ok(InvoiceSignature(RecoverableSignature::from_compact( + Ok(Bolt11InvoiceSignature(RecoverableSignature::from_compact( signature, recovery_id )?)) @@ -972,7 +972,7 @@ mod test { use lightning::ln::features::Bolt11InvoiceFeatures; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use crate::TaggedField::*; - use crate::{SiPrefix, SignedRawBolt11Invoice, InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, + use crate::{SiPrefix, SignedRawBolt11Invoice, Bolt11InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp}; // Feature bits 9, 15, and 99 are set. @@ -998,7 +998,7 @@ mod test { hash: [0xb1, 0x96, 0x46, 0xc3, 0xbc, 0x56, 0x76, 0x1d, 0x20, 0x65, 0x6e, 0x0e, 0x32, 0xec, 0xd2, 0x69, 0x27, 0xb7, 0x62, 0x6e, 0x2a, 0x8b, 0xe6, 0x97, 0x71, 0x9f, 0xf8, 0x7e, 0x44, 0x54, 0x55, 0xb9], - signature: InvoiceSignature(RecoverableSignature::from_compact( + signature: Bolt11InvoiceSignature(RecoverableSignature::from_compact( &[0xd7, 0x90, 0x4c, 0xc4, 0xb7, 0x4a, 0x22, 0x26, 0x9c, 0x68, 0xc1, 0xdf, 0x68, 0xa9, 0x6c, 0x21, 0x4d, 0x65, 0x1b, 0x93, 0x76, 0xe9, 0xf1, 0x64, 0xd3, 0x60, 0x4d, 0xa4, 0xb7, 0xde, 0xcc, 0xce, 0x0e, 0x82, 0xaa, 0xab, 0x4c, 0x85, 0xd3, @@ -1018,7 +1018,7 @@ mod test { fn test_raw_signed_invoice_deserialization() { use crate::TaggedField::*; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; - use crate::{SignedRawBolt11Invoice, InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, + use crate::{SignedRawBolt11Invoice, Bolt11InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp}; assert_eq!( @@ -1051,7 +1051,7 @@ mod test { 0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d, 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9 ], - signature: InvoiceSignature(RecoverableSignature::from_compact( + signature: Bolt11InvoiceSignature(RecoverableSignature::from_compact( & [ 0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a, 0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43, diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index ee65f2fd6df..f26903a74ba 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -288,7 +288,7 @@ pub struct SignedRawBolt11Invoice { hash: [u8; 32], /// signature of the payment request - signature: InvoiceSignature, + signature: Bolt11InvoiceSignature, } /// Represents an syntactically correct [`Bolt11Invoice`] for a payment on the lightning network, @@ -499,15 +499,15 @@ pub enum Fallback { /// Recoverable signature #[derive(Clone, Debug, Hash, Eq, PartialEq)] -pub struct InvoiceSignature(pub RecoverableSignature); +pub struct Bolt11InvoiceSignature(pub RecoverableSignature); -impl PartialOrd for InvoiceSignature { +impl PartialOrd for Bolt11InvoiceSignature { fn partial_cmp(&self, other: &Self) -> Option { self.0.serialize_compact().1.partial_cmp(&other.0.serialize_compact().1) } } -impl Ord for InvoiceSignature { +impl Ord for Bolt11InvoiceSignature { fn cmp(&self, other: &Self) -> Ordering { self.0.serialize_compact().1.cmp(&other.0.serialize_compact().1) } @@ -855,7 +855,7 @@ impl SignedRawBolt11Invoice { /// 1. raw invoice /// 2. hash of the raw invoice /// 3. signature - pub fn into_parts(self) -> (RawBolt11Invoice, [u8; 32], InvoiceSignature) { + pub fn into_parts(self) -> (RawBolt11Invoice, [u8; 32], Bolt11InvoiceSignature) { (self.raw_invoice, self.hash, self.signature) } @@ -870,7 +870,7 @@ impl SignedRawBolt11Invoice { } /// Signature for the invoice. - pub fn signature(&self) -> &InvoiceSignature { + pub fn signature(&self) -> &Bolt11InvoiceSignature { &self.signature } @@ -1004,7 +1004,7 @@ impl RawBolt11Invoice { Ok(SignedRawBolt11Invoice { raw_invoice: self, hash: raw_hash, - signature: InvoiceSignature(signature), + signature: Bolt11InvoiceSignature(signature), }) } @@ -1591,7 +1591,7 @@ impl Deref for PrivateRoute { } } -impl Deref for InvoiceSignature { +impl Deref for Bolt11InvoiceSignature { type Target = RecoverableSignature; fn deref(&self) -> &RecoverableSignature { @@ -1797,7 +1797,7 @@ mod test { use secp256k1::Secp256k1; use secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; use secp256k1::{SecretKey, PublicKey}; - use crate::{SignedRawBolt11Invoice, InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, + use crate::{SignedRawBolt11Invoice, Bolt11InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp}; let invoice = SignedRawBolt11Invoice { @@ -1826,7 +1826,7 @@ mod test { 0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d, 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9 ], - signature: InvoiceSignature(RecoverableSignature::from_compact( + signature: Bolt11InvoiceSignature(RecoverableSignature::from_compact( & [ 0x38u8, 0xec, 0x68, 0x91, 0x34, 0x5e, 0x20, 0x41, 0x45, 0xbe, 0x8a, 0x3a, 0x99, 0xde, 0x38, 0xe9, 0x8a, 0x39, 0xd6, 0xa5, 0x69, 0x43, diff --git a/lightning-invoice/src/ser.rs b/lightning-invoice/src/ser.rs index 43ddedcd480..dc5dba45da0 100644 --- a/lightning-invoice/src/ser.rs +++ b/lightning-invoice/src/ser.rs @@ -3,7 +3,7 @@ use core::fmt::{Display, Formatter}; use bech32::{ToBase32, u5, WriteBase32, Base32Len}; use crate::prelude::*; -use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, InvoiceSignature, PositiveTimestamp, +use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, Bolt11InvoiceSignature, PositiveTimestamp, PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawBolt11Invoice, RawDataPart}; /// Converts a stream of bytes written to it to base32. On finalization the according padding will @@ -456,7 +456,7 @@ impl ToBase32 for TaggedField { } } -impl ToBase32 for InvoiceSignature { +impl ToBase32 for Bolt11InvoiceSignature { fn write_base32(&self, writer: &mut W) -> Result<(), ::Err> { let mut converter = BytesToBase32::new(writer); let (recovery_id, signature) = self.0.serialize_compact(); From 7ad3f88ebadb39864c192e0961c2542422801e21 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Fri, 14 Jul 2023 15:59:33 -0500 Subject: [PATCH 13/13] Qualify the BOLT 11 invoice description type A previous commit qualified the BOLT 11 invoice type, so any related types should be similarly qualified, if public. --- lightning-invoice/src/lib.rs | 18 +++++++-------- lightning-invoice/src/utils.rs | 42 +++++++++++++++++----------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index f26903a74ba..d1b381130c0 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -260,7 +260,7 @@ pub struct Bolt11Invoice { /// This is not exported to bindings users as we don't have a good way to map the reference lifetimes making this /// practically impossible to use safely in languages like C. #[derive(Eq, PartialEq, Debug, Clone, Ord, PartialOrd)] -pub enum InvoiceDescription<'f> { +pub enum Bolt11InvoiceDescription<'f> { /// Reference to the directly supplied description in the invoice Direct(&'f Description), @@ -671,12 +671,12 @@ impl InvoiceBui } /// Set the description or description hash. This function is only available if no description (hash) was set. - pub fn invoice_description(self, description: InvoiceDescription) -> InvoiceBuilder { + pub fn invoice_description(self, description: Bolt11InvoiceDescription) -> InvoiceBuilder { match description { - InvoiceDescription::Direct(desc) => { + Bolt11InvoiceDescription::Direct(desc) => { self.description(desc.clone().into_inner()) } - InvoiceDescription::Hash(hash) => { + Bolt11InvoiceDescription::Hash(hash) => { self.description_hash(hash.0) } } @@ -1310,12 +1310,12 @@ impl Bolt11Invoice { /// Return the description or a hash of it for longer ones /// - /// This is not exported to bindings users because we don't yet export InvoiceDescription - pub fn description(&self) -> InvoiceDescription { + /// This is not exported to bindings users because we don't yet export Bolt11InvoiceDescription + pub fn description(&self) -> Bolt11InvoiceDescription { if let Some(direct) = self.signed_invoice.description() { - return InvoiceDescription::Direct(direct); + return Bolt11InvoiceDescription::Direct(direct); } else if let Some(hash) = self.signed_invoice.description_hash() { - return InvoiceDescription::Hash(hash); + return Bolt11InvoiceDescription::Hash(hash); } unreachable!("ensured by constructor"); } @@ -2142,7 +2142,7 @@ mod test { assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]); assert_eq!( invoice.description(), - InvoiceDescription::Hash(&Sha256(sha256::Hash::from_slice(&[3;32][..]).unwrap())) + Bolt11InvoiceDescription::Hash(&Sha256(sha256::Hash::from_slice(&[3;32][..]).unwrap())) ); assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&[21;32][..]).unwrap()); assert_eq!(invoice.payment_secret(), &PaymentSecret([42; 32])); diff --git a/lightning-invoice/src/utils.rs b/lightning-invoice/src/utils.rs index 8d11d54e64f..25a7cf77d5e 100644 --- a/lightning-invoice/src/utils.rs +++ b/lightning-invoice/src/utils.rs @@ -2,7 +2,7 @@ use crate::{Bolt11Invoice, CreationError, Currency, InvoiceBuilder, SignOrCreationError}; -use crate::{prelude::*, Description, InvoiceDescription, Sha256}; +use crate::{prelude::*, Description, Bolt11InvoiceDescription, Sha256}; use bech32::ToBase32; use bitcoin_hashes::Hash; use lightning::chain; @@ -71,7 +71,7 @@ where L::Target: Logger, { let description = Description::new(description).map_err(SignOrCreationError::CreationError)?; - let description = InvoiceDescription::Direct(&description,); + let description = Bolt11InvoiceDescription::Direct(&description,); _create_phantom_invoice::( amt_msat, payment_hash, description, invoice_expiry_delta_secs, phantom_route_hints, entropy_source, node_signer, logger, network, min_final_cltv_expiry_delta, duration_since_epoch, @@ -127,7 +127,7 @@ where L::Target: Logger, { _create_phantom_invoice::( - amt_msat, payment_hash, InvoiceDescription::Hash(&description_hash), + amt_msat, payment_hash, Bolt11InvoiceDescription::Hash(&description_hash), invoice_expiry_delta_secs, phantom_route_hints, entropy_source, node_signer, logger, network, min_final_cltv_expiry_delta, duration_since_epoch, ) @@ -136,7 +136,7 @@ where const MAX_CHANNEL_HINTS: usize = 3; fn _create_phantom_invoice( - amt_msat: Option, payment_hash: Option, description: InvoiceDescription, + amt_msat: Option, payment_hash: Option, description: Bolt11InvoiceDescription, invoice_expiry_delta_secs: u32, phantom_route_hints: Vec, entropy_source: ES, node_signer: NS, logger: L, network: Currency, min_final_cltv_expiry_delta: Option, duration_since_epoch: Duration, ) -> Result> @@ -157,10 +157,10 @@ where } let invoice = match description { - InvoiceDescription::Direct(description) => { + Bolt11InvoiceDescription::Direct(description) => { InvoiceBuilder::new(network).description(description.0.clone()) } - InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0), + Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0), }; // If we ever see performance here being too slow then we should probably take this ExpandedKey as a parameter instead. @@ -417,7 +417,7 @@ pub fn create_invoice_from_channelmanager_with_description_hash_and_duration_sin { _create_invoice_from_channelmanager_and_duration_since_epoch( channelmanager, node_signer, logger, network, amt_msat, - InvoiceDescription::Hash(&description_hash), + Bolt11InvoiceDescription::Hash(&description_hash), duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta, ) } @@ -442,7 +442,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch( channelmanager: &ChannelManager, node_signer: NS, logger: L, - network: Currency, amt_msat: Option, description: InvoiceDescription, + network: Currency, amt_msat: Option, description: Bolt11InvoiceDescription, duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, min_final_cltv_expiry_delta: Option, ) -> Result> where @@ -503,7 +503,7 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_ .map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?; _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash( channelmanager, node_signer, logger, network, amt_msat, - InvoiceDescription::Direct( + Bolt11InvoiceDescription::Direct( &Description::new(description).map_err(SignOrCreationError::CreationError)?, ), duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret, @@ -513,9 +513,9 @@ pub fn create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash( channelmanager: &ChannelManager, node_signer: NS, logger: L, - network: Currency, amt_msat: Option, description: InvoiceDescription, duration_since_epoch: Duration, - invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, payment_secret: PaymentSecret, - min_final_cltv_expiry_delta: Option, + network: Currency, amt_msat: Option, description: Bolt11InvoiceDescription, + duration_since_epoch: Duration, invoice_expiry_delta_secs: u32, payment_hash: PaymentHash, + payment_secret: PaymentSecret, min_final_cltv_expiry_delta: Option, ) -> Result> where M::Target: chain::Watch<::Signer>, @@ -537,10 +537,10 @@ fn _create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_has log_trace!(logger, "Creating invoice with payment hash {}", log_bytes!(payment_hash.0)); let invoice = match description { - InvoiceDescription::Direct(description) => { + Bolt11InvoiceDescription::Direct(description) => { InvoiceBuilder::new(network).description(description.0.clone()) } - InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0), + Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0), }; let mut invoice = invoice @@ -794,7 +794,7 @@ fn prefer_current_channel(min_inbound_capacity_msat: Option, current_channe mod test { use core::cell::RefCell; use core::time::Duration; - use crate::{Currency, Description, InvoiceDescription, SignOrCreationError, CreationError}; + use crate::{Currency, Description, Bolt11InvoiceDescription, SignOrCreationError, CreationError}; use bitcoin_hashes::{Hash, sha256}; use bitcoin_hashes::sha256::Hash as Sha256; use lightning::sign::PhantomKeysManager; @@ -852,7 +852,7 @@ mod test { assert_eq!(invoice.amount_pico_btc(), Some(100_000)); // If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`. assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); - assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string()))); + assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string()))); assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into())); // Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is @@ -948,7 +948,7 @@ mod test { ).unwrap(); assert_eq!(invoice.amount_pico_btc(), Some(100_000)); assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); - assert_eq!(invoice.description(), InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Testing description_hash".as_bytes())))); + assert_eq!(invoice.description(), Bolt11InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Testing description_hash".as_bytes())))); } #[test] @@ -965,7 +965,7 @@ mod test { ).unwrap(); assert_eq!(invoice.amount_pico_btc(), Some(100_000)); assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); - assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string()))); + assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string()))); assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&payment_hash.0[..]).unwrap()); } @@ -1317,7 +1317,7 @@ mod test { }; assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); - assert_eq!(invoice.description(), InvoiceDescription::Direct(&Description("test".to_string()))); + assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description("test".to_string()))); assert_eq!(invoice.route_hints().len(), 2); assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into())); assert!(!invoice.features().unwrap().supports_basic_mpp()); @@ -1455,7 +1455,7 @@ mod test { assert_eq!(invoice.amount_pico_btc(), Some(200_000)); assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64); assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into())); - assert_eq!(invoice.description(), InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Description hash phantom invoice".as_bytes())))); + assert_eq!(invoice.description(), Bolt11InvoiceDescription::Hash(&crate::Sha256(Sha256::hash("Description hash phantom invoice".as_bytes())))); } #[test]