X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-invoice%2Fsrc%2Flib.rs;h=1dd7123a486d1077f1295b7655b1fac497cfb57f;hb=7714393cf00b5a7fbe29566814125305598dc656;hp=0e05bf6d4aa74b96f15a9ea0f71141a6985b0967;hpb=3b14a76d0114f6f815c711ce03f15b98fe48825c;p=rust-lightning diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 0e05bf6d..1dd7123a 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)] @@ -43,6 +45,7 @@ use lightning::ln::features::InvoiceFeatures; #[cfg(any(doc, test))] use lightning::routing::network_graph::RoutingFees; use lightning::routing::router::RouteHint; +use lightning::util::invoice::construct_invoice_preimage; use secp256k1::key::PublicKey; use secp256k1::{Message, Secp256k1}; @@ -609,9 +612,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() @@ -621,13 +624,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 } } @@ -799,32 +800,9 @@ macro_rules! find_all_extract { #[allow(missing_docs)] impl RawInvoice { - /// Construct the invoice's HRP and signatureless data into a preimage to be hashed. - pub(crate) fn construct_invoice_preimage(hrp_bytes: &[u8], data_without_signature: &[u5]) -> Vec { - use bech32::FromBase32; - - let mut preimage = Vec::::from(hrp_bytes); - - let mut data_part = Vec::from(data_without_signature); - let overhang = (data_part.len() * 5) % 8; - if overhang > 0 { - // add padding if data does not end at a byte boundary - data_part.push(u5::try_from_u8(0).unwrap()); - - // if overhang is in (1..3) we need to add u5(0) padding two times - if overhang < 3 { - data_part.push(u5::try_from_u8(0).unwrap()); - } - } - - preimage.extend_from_slice(&Vec::::from_base32(&data_part) - .expect("No padding error may occur due to appended zero above.")); - preimage - } - /// Hash the HRP as bytes and signatureless data part. fn hash_from_parts(hrp_bytes: &[u8], data_without_signature: &[u5]) -> [u8; 32] { - let preimage = RawInvoice::construct_invoice_preimage(hrp_bytes, data_without_signature); + let preimage = construct_invoice_preimage(hrp_bytes, data_without_signature); let mut hash: [u8; 32] = Default::default(); hash.copy_from_slice(&sha256::Hash::hash(&preimage)[..]); hash @@ -1409,6 +1387,12 @@ pub enum CreationError { /// The supplied millisatoshi amount was greater than the total bitcoin supply. InvalidAmount, + + /// Route hints were required for this invoice and were missing. Applies to + /// [phantom invoices]. + /// + /// [phantom invoices]: crate::utils::create_phantom_invoice + MissingRouteHints, } impl Display for CreationError { @@ -1418,6 +1402,7 @@ impl Display for CreationError { CreationError::RouteTooLong => f.write_str("The specified route has too many hops and can't be encoded"), CreationError::TimestampOutOfBounds => f.write_str("The Unix timestamp of the supplied date is less than zero or greater than 35-bits"), CreationError::InvalidAmount => f.write_str("The supplied millisatoshi amount was greater than the total bitcoin supply"), + CreationError::MissingRouteHints => f.write_str("The invoice required route hints and they weren't provided"), } } }