X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-invoice%2Fsrc%2Flib.rs;h=5784607dde937b85fa384ed65a630d7af1d3ca3a;hb=7181b53aa47b8c25aca01fda9661508d0ec7be59;hp=d676f6c28d6faf7926fa970030ffb1d258fa1af7;hpb=de1aca5ca27ae372a4b240489ccdd49a8f4dc436;p=rust-lightning diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index d676f6c2..5784607d 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -5,6 +5,8 @@ #![deny(unused_mut)] #![deny(broken_intra_doc_links)] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] + #![cfg_attr(feature = "strict", deny(warnings))] #![cfg_attr(all(not(feature = "std"), not(test)), no_std)] @@ -51,9 +53,11 @@ use secp256k1::recovery::RecoverableSignature; use core::fmt::{Display, Formatter, self}; use core::iter::FilterMap; +use core::num::ParseIntError; use core::ops::Deref; use core::slice::Iter; use core::time::Duration; +use core::str; mod de; mod ser; @@ -84,7 +88,45 @@ mod sync { #[cfg(not(feature = "std"))] mod sync; -pub use de::{ParseError, ParseOrSemanticError}; +/// Errors that indicate what is wrong with the invoice. They have some granularity for debug +/// reasons, but should generally result in an "invalid BOLT11 invoice" message for the user. +#[allow(missing_docs)] +#[derive(PartialEq, Debug, Clone)] +pub enum ParseError { + Bech32Error(bech32::Error), + ParseAmountError(ParseIntError), + MalformedSignature(secp256k1::Error), + BadPrefix, + UnknownCurrency, + UnknownSiPrefix, + MalformedHRP, + TooShortDataPart, + UnexpectedEndOfTaggedFields, + DescriptionDecodeError(str::Utf8Error), + PaddingError, + IntegerOverflowError, + InvalidSegWitProgramLength, + InvalidPubKeyHashLength, + InvalidScriptHashLength, + InvalidRecoveryId, + InvalidSliceLength(String), + + /// Not an error, but used internally to signal that a part of the invoice should be ignored + /// according to BOLT11 + Skip, +} + +/// Indicates that something went wrong while parsing or validating the invoice. Parsing errors +/// should be mostly seen as opaque and are only there for debugging reasons. Semantic errors +/// like wrong signatures, missing fields etc. could mean that someone tampered with the invoice. +#[derive(PartialEq, Debug, Clone)] +pub enum ParseOrSemanticError { + /// The invoice couldn't be decoded + ParseError(ParseError), + + /// The invoice could be decoded but violates the BOLT11 standard + SemanticError(::SemanticError), +} /// The number of bits used to represent timestamps as defined in BOLT 11. const TIMESTAMP_BITS: usize = 35; @@ -610,9 +652,9 @@ impl InvoiceBuilder InvoiceBuilder { /// Sets the payment secret and relevant features. pub fn payment_secret(mut self, payment_secret: PaymentSecret) -> InvoiceBuilder { - let features = InvoiceFeatures::empty() - .set_variable_length_onion_required() - .set_payment_secret_required(); + let mut features = InvoiceFeatures::empty(); + features.set_variable_length_onion_required(); + features.set_payment_secret_required(); self.tagged_fields.push(TaggedField::PaymentSecret(payment_secret)); self.tagged_fields.push(TaggedField::Features(features)); self.set_flags() @@ -622,13 +664,11 @@ impl InvoiceBuilder InvoiceBuilder { /// Sets the `basic_mpp` feature as optional. pub fn basic_mpp(mut self) -> Self { - self.tagged_fields = self.tagged_fields - .drain(..) - .map(|field| match field { - TaggedField::Features(f) => TaggedField::Features(f.set_basic_mpp_optional()), - _ => field, - }) - .collect(); + for field in self.tagged_fields.iter_mut() { + if let TaggedField::Features(f) = field { + f.set_basic_mpp_optional(); + } + } self } }