From 7ed62510faad5233a20dd783d17d6f0a0eb1e6b1 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Tue, 5 Nov 2024 10:09:05 +0100 Subject: [PATCH] `rustfmt`: Run on `lightning-invoice/src/lib.rs` --- lightning-invoice/src/lib.rs | 675 +++++++++++++++++++---------------- 1 file changed, 374 insertions(+), 301 deletions(-) diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 744548f2c..348f87909 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -1,14 +1,11 @@ #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] - #![deny(missing_docs)] #![deny(non_upper_case_globals)] #![deny(non_camel_case_types)] #![deny(non_snake_case)] #![deny(unused_mut)] - #![cfg_attr(docsrs, feature(doc_auto_cfg))] - #![cfg_attr(all(not(feature = "std"), not(test)), no_std)] //! This crate provides data structures to represent @@ -22,11 +19,11 @@ //! //! [`Bolt11Invoice::from_str`]: crate::Bolt11Invoice#impl-FromStr -extern crate bech32; -extern crate lightning_types; extern crate alloc; +extern crate bech32; #[cfg(any(test, feature = "std"))] extern crate core; +extern crate lightning_types; #[cfg(feature = "serde")] extern crate serde; @@ -35,31 +32,31 @@ use std::time::SystemTime; use bech32::primitives::decode::CheckedHrpstringError; use bech32::Fe32; +use bitcoin::hashes::{sha256, Hash}; use bitcoin::{Address, Network, PubkeyHash, ScriptHash, WitnessProgram, WitnessVersion}; -use bitcoin::hashes::{Hash, sha256}; use lightning_types::features::Bolt11InvoiceFeatures; +use bitcoin::secp256k1::ecdsa::RecoverableSignature; use bitcoin::secp256k1::PublicKey; use bitcoin::secp256k1::{Message, Secp256k1}; -use bitcoin::secp256k1::ecdsa::RecoverableSignature; use alloc::boxed::Box; +use alloc::string; use core::cmp::Ordering; -use core::fmt::{Display, Formatter, self}; +use core::fmt::{self, Display, Formatter}; use core::iter::FilterMap; use core::num::ParseIntError; use core::ops::Deref; use core::slice::Iter; use core::time::Duration; -use alloc::string; #[cfg(feature = "serde")] -use serde::{Deserialize, Deserializer,Serialize, Serializer, de::Error}; +use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; #[doc(no_inline)] pub use lightning_types::payment::PaymentSecret; #[doc(no_inline)] -pub use lightning_types::routing::{RoutingFees, RouteHint, RouteHintHop}; +pub use lightning_types::routing::{RouteHint, RouteHintHop, RoutingFees}; use lightning_types::string::UntrustedString; mod de; @@ -71,7 +68,7 @@ mod test_ser_de; #[allow(unused_imports)] mod prelude { - pub use alloc::{vec, vec::Vec, string::String}; + pub use alloc::{string::String, vec, vec::Vec}; pub use alloc::string::ToString; } @@ -204,7 +201,14 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18; /// /// This is not exported to bindings users as we likely need to manually select one set of boolean type parameters. #[derive(Eq, PartialEq, Debug, Clone)] -pub struct InvoiceBuilder { +pub struct InvoiceBuilder< + D: tb::Bool, + H: tb::Bool, + T: tb::Bool, + C: tb::Bool, + S: tb::Bool, + M: tb::Bool, +> { currency: Currency, amount: Option, si_prefix: Option, @@ -501,8 +505,10 @@ pub enum TaggedField { /// SHA-256 hash #[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] -pub struct Sha256(/// This is not exported to bindings users as the native hash types are not currently mapped - pub sha256::Hash); +pub struct Sha256( + /// This is not exported to bindings users as the native hash types are not currently mapped + pub sha256::Hash, +); impl Sha256 { /// Constructs a new [`Sha256`] from the given bytes, which are assumed to be the output of a @@ -537,10 +543,7 @@ pub struct MinFinalCltvExpiryDelta(pub u64); #[allow(missing_docs)] #[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] pub enum Fallback { - SegWitProgram { - version: WitnessVersion, - program: Vec, - }, + SegWitProgram { version: WitnessVersion, program: Vec }, PubKeyHash(PubkeyHash), ScriptHash(ScriptHash), } @@ -607,9 +610,20 @@ impl InvoiceBuilder InvoiceBuilder { +impl + InvoiceBuilder +{ /// Helper function to set the completeness flags. - fn set_flags(self) -> InvoiceBuilder { + fn set_flags< + DN: tb::Bool, + HN: tb::Bool, + TN: tb::Bool, + CN: tb::Bool, + SN: tb::Bool, + MN: tb::Bool, + >( + self, + ) -> InvoiceBuilder { InvoiceBuilder:: { currency: self.currency, amount: self.amount, @@ -634,8 +648,8 @@ impl amt, None => { self.error = Some(CreationError::InvalidAmount); - return self - } + return self; + }, }; let biggest_possible_si_prefix = SiPrefix::values_desc() .iter() @@ -675,41 +689,37 @@ impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Builds a [`RawBolt11Invoice`] if no [`CreationError`] occurred while construction any of the /// fields. pub fn build_raw(self) -> Result { - // If an error occurred at any time before, return it now if let Some(e) = self.error { return Err(e); } - let hrp = RawHrp { - currency: self.currency, - raw_amount: self.amount, - si_prefix: self.si_prefix, - }; + let hrp = + RawHrp { currency: self.currency, raw_amount: self.amount, si_prefix: self.si_prefix }; let timestamp = self.timestamp.expect("ensured to be Some(t) by type T"); - let tagged_fields = self.tagged_fields.into_iter().map(|tf| { - RawTaggedField::KnownSemantics(tf) - }).collect::>(); + let tagged_fields = self + .tagged_fields + .into_iter() + .map(|tf| RawTaggedField::KnownSemantics(tf)) + .collect::>(); - let data = RawDataPart { - timestamp, - tagged_fields, - }; + let data = RawDataPart { timestamp, tagged_fields }; - Ok(RawBolt11Invoice { - hrp, - data, - }) + Ok(RawBolt11Invoice { hrp, data }) } } -impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Set the description. This function is only available if no description (hash) was set. pub fn description(mut self, description: String) -> InvoiceBuilder { match Description::new(description) { @@ -720,25 +730,27 @@ impl InvoiceBui } /// Set the description hash. This function is only available if no description (hash) was set. - pub fn description_hash(mut self, description_hash: sha256::Hash) -> InvoiceBuilder { + pub fn description_hash( + mut self, description_hash: sha256::Hash, + ) -> InvoiceBuilder { self.tagged_fields.push(TaggedField::DescriptionHash(Sha256(description_hash))); self.set_flags() } /// Set the description or description hash. This function is only available if no description (hash) was set. - pub fn invoice_description(self, description: Bolt11InvoiceDescription) -> InvoiceBuilder { + pub fn invoice_description( + self, description: Bolt11InvoiceDescription, + ) -> InvoiceBuilder { match description { - Bolt11InvoiceDescription::Direct(desc) => { - self.description(desc.0.0) - } - Bolt11InvoiceDescription::Hash(hash) => { - self.description_hash(hash.0) - } + Bolt11InvoiceDescription::Direct(desc) => self.description(desc.0 .0), + Bolt11InvoiceDescription::Hash(hash) => self.description_hash(hash.0), } } } -impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Set the payment hash. This function is only available if no payment hash was set. pub fn payment_hash(mut self, hash: sha256::Hash) -> InvoiceBuilder { self.tagged_fields.push(TaggedField::PaymentHash(Sha256(hash))); @@ -746,7 +758,9 @@ impl InvoiceBui } } -impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Sets the timestamp to a specific [`SystemTime`]. #[cfg(feature = "std")] pub fn timestamp(mut self, time: SystemTime) -> InvoiceBuilder { @@ -760,7 +774,9 @@ impl InvoiceBui /// Sets the timestamp to a duration since the Unix epoch, dropping the subsecond part (which /// is not representable in BOLT 11 invoices). - pub fn duration_since_epoch(mut self, time: Duration) -> InvoiceBuilder { + pub fn duration_since_epoch( + mut self, time: Duration, + ) -> InvoiceBuilder { match PositiveTimestamp::from_duration_since_epoch(time) { Ok(t) => self.timestamp = Some(t), Err(e) => self.error = Some(e), @@ -778,17 +794,27 @@ impl InvoiceBui } } -impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Sets `min_final_cltv_expiry_delta`. - pub fn min_final_cltv_expiry_delta(mut self, min_final_cltv_expiry_delta: u64) -> InvoiceBuilder { - self.tagged_fields.push(TaggedField::MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta(min_final_cltv_expiry_delta))); + pub fn min_final_cltv_expiry_delta( + mut self, min_final_cltv_expiry_delta: u64, + ) -> InvoiceBuilder { + self.tagged_fields.push(TaggedField::MinFinalCltvExpiryDelta(MinFinalCltvExpiryDelta( + min_final_cltv_expiry_delta, + ))); self.set_flags() } } -impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Sets the payment secret and relevant features. - pub fn payment_secret(mut self, payment_secret: PaymentSecret) -> InvoiceBuilder { + pub fn payment_secret( + mut self, payment_secret: PaymentSecret, + ) -> InvoiceBuilder { let mut found_features = false; for field in self.tagged_fields.iter_mut() { if let TaggedField::Features(f) = field { @@ -808,14 +834,18 @@ impl InvoiceBui } } -impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Sets the payment metadata. /// /// By default features are set to *optionally* allow the sender to include the payment metadata. /// If you wish to require that the sender include the metadata (and fail to parse the invoice if /// they don't support payment metadata fields), you need to call /// [`InvoiceBuilder::require_payment_metadata`] after this. - pub fn payment_metadata(mut self, payment_metadata: Vec) -> InvoiceBuilder { + pub fn payment_metadata( + mut self, payment_metadata: Vec, + ) -> InvoiceBuilder { self.tagged_fields.push(TaggedField::PaymentMetadata(payment_metadata)); let mut found_features = false; for field in self.tagged_fields.iter_mut() { @@ -833,7 +863,9 @@ impl InvoiceBui } } -impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Sets forwarding of payment metadata as required. A reader of the invoice which does not /// support sending payment metadata will fail to read the invoice. pub fn require_payment_metadata(mut self) -> InvoiceBuilder { @@ -846,7 +878,9 @@ impl InvoiceBui } } -impl InvoiceBuilder { +impl + InvoiceBuilder +{ /// Sets the `basic_mpp` feature as optional. pub fn basic_mpp(mut self) -> Self { for field in self.tagged_fields.iter_mut() { @@ -863,11 +897,10 @@ impl InvoiceBuilder(self, sign_function: F) -> Result - where F: FnOnce(&Message) -> RecoverableSignature + where + F: FnOnce(&Message) -> RecoverableSignature, { - let invoice = self.try_build_signed::<_, ()>(|hash| { - Ok(sign_function(hash)) - }); + let invoice = self.try_build_signed::<_, ()>(|hash| Ok(sign_function(hash))); match invoice { Ok(i) => Ok(i), @@ -879,8 +912,11 @@ impl InvoiceBuilder(self, sign_function: F) -> Result> - where F: FnOnce(&Message) -> Result + pub fn try_build_signed( + self, sign_function: F, + ) -> Result> + where + F: FnOnce(&Message) -> Result, { let raw = match self.build_raw() { Ok(r) => r, @@ -892,9 +928,7 @@ impl InvoiceBuilder return Err(SignOrCreationError::SignError(e)), }; - let invoice = Bolt11Invoice { - signed_invoice: signed, - }; + let invoice = Bolt11Invoice { signed_invoice: signed }; invoice.check_field_counts().expect("should be ensured by type signature of builder"); invoice.check_feature_bits().expect("should be ensured by type signature of builder"); @@ -904,7 +938,6 @@ impl InvoiceBuilder Result { let hash = Message::from_digest(self.hash); - Ok(PayeePubKey(Secp256k1::new().recover_ecdsa( - &hash, - &self.signature - )?)) + Ok(PayeePubKey(Secp256k1::new().recover_ecdsa(&hash, &self.signature)?)) } /// Checks if the signature is valid for the included payee public key or if none exists if it's @@ -953,17 +983,14 @@ impl SignedRawBolt11Invoice { recovered_pub_key = Some(recovered); } - let pub_key = included_pub_key.or(recovered_pub_key.as_ref()) - .expect("One is always present"); + let pub_key = + included_pub_key.or(recovered_pub_key.as_ref()).expect("One is always present"); let hash = Message::from_digest(self.hash); let secp_context = Secp256k1::new(); - let verification_result = secp_context.verify_ecdsa( - &hash, - &self.signature.to_standard(), - pub_key - ); + let verification_result = + secp_context.verify_ecdsa(&hash, &self.signature.to_standard(), pub_key); match verification_result { Ok(()) => true, @@ -1023,7 +1050,9 @@ macro_rules! find_all_extract { #[allow(missing_docs)] impl RawBolt11Invoice { /// Hash the HRP (as bytes) and signatureless data part (as Fe32 iterator) - fn hash_from_parts<'s>(hrp_bytes: &[u8], data_without_signature: Box + 's>) -> [u8; 32] { + fn hash_from_parts<'s>( + hrp_bytes: &[u8], data_without_signature: Box + 's>, + ) -> [u8; 32] { use crate::bech32::Fe32IterExt; use bitcoin::hashes::HashEngine; @@ -1047,7 +1076,7 @@ impl RawBolt11Invoice { // Iterate over data // Note: if it was not for padding, this could go on the supplied original iterator // (see https://github.com/rust-bitcoin/rust-bech32/issues/198) - data_part.into_iter().fes_to_bytes().for_each(|v| { engine.input(&[v])}); + data_part.into_iter().fes_to_bytes().for_each(|v| engine.input(&[v])); let raw_hash = sha256::Hash::from_engine(engine); let mut hash: [u8; 32] = Default::default(); @@ -1059,10 +1088,7 @@ impl RawBolt11Invoice { pub fn signable_hash(&self) -> [u8; 32] { use crate::ser::Base32Iterable; - Self::hash_from_parts( - self.hrp.to_string().as_bytes(), - self.data.fe_iter(), - ) + Self::hash_from_parts(self.hrp.to_string().as_bytes(), self.data.fe_iter()) } /// Signs the invoice using the supplied `sign_method`. This function MAY fail with an error of @@ -1072,7 +1098,8 @@ impl RawBolt11Invoice { /// 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 - where F: FnOnce(&Message) -> Result + where + F: FnOnce(&Message) -> Result, { let raw_hash = self.signable_hash(); let hash = Message::from_digest(raw_hash); @@ -1088,9 +1115,9 @@ impl RawBolt11Invoice { /// Returns an iterator over all tagged fields with known semantics. /// /// This is not exported to bindings users as there is not yet a manual mapping for a FilterMap - pub fn known_tagged_fields(&self) - -> FilterMap, fn(&RawTaggedField) -> Option<&TaggedField>> - { + pub fn known_tagged_fields( + &self, + ) -> FilterMap, fn(&RawTaggedField) -> Option<&TaggedField>> { // For 1.14.0 compatibility: closures' types can't be written an fn()->() in the // function's type signature. // TODO: refactor once impl Trait is available @@ -1101,7 +1128,7 @@ impl RawBolt11Invoice { } } - self.data.tagged_fields.iter().filter_map(match_raw ) + self.data.tagged_fields.iter().filter_map(match_raw) } pub fn payment_hash(&self) -> Option<&Sha256> { @@ -1152,7 +1179,9 @@ impl RawBolt11Invoice { /// Returns `None` if no amount is set or on overflow. pub fn amount_pico_btc(&self) -> Option { self.hrp.raw_amount.and_then(|v| { - v.checked_mul(self.hrp.si_prefix.as_ref().map_or(1_000_000_000_000, |si| { si.multiplier() })) + v.checked_mul( + self.hrp.si_prefix.as_ref().map_or(1_000_000_000_000, |si| si.multiplier()), + ) }) } @@ -1240,10 +1269,13 @@ impl Bolt11Invoice { /// Check that all mandatory fields are present 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(); + let payment_hash_cnt = self + .tagged_fields() + .filter(|&tf| match *tf { + TaggedField::PaymentHash(_) => true, + _ => false, + }) + .count(); if payment_hash_cnt < 1 { return Err(Bolt11SemanticError::NoPaymentHash); } else if payment_hash_cnt > 1 { @@ -1251,14 +1283,17 @@ impl Bolt11Invoice { } // "A writer MUST include either exactly one d or exactly one h field." - let description_cnt = self.tagged_fields().filter(|&tf| match *tf { - TaggedField::Description(_) | TaggedField::DescriptionHash(_) => true, - _ => false, - }).count(); - if description_cnt < 1 { + let description_cnt = self + .tagged_fields() + .filter(|&tf| match *tf { + TaggedField::Description(_) | TaggedField::DescriptionHash(_) => true, + _ => false, + }) + .count(); + if description_cnt < 1 { return Err(Bolt11SemanticError::NoDescription); } else if description_cnt > 1 { - return Err(Bolt11SemanticError::MultipleDescriptions); + return Err(Bolt11SemanticError::MultipleDescriptions); } self.check_payment_secret()?; @@ -1269,10 +1304,13 @@ impl Bolt11Invoice { /// Checks that there is exactly one payment secret field 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(); + let payment_secret_count = self + .tagged_fields() + .filter(|&tf| match *tf { + TaggedField::PaymentSecret(_) => true, + _ => false, + }) + .count(); if payment_secret_count < 1 { return Err(Bolt11SemanticError::NoPaymentSecret); } else if payment_secret_count > 1 { @@ -1321,10 +1359,12 @@ impl Bolt11Invoice { /// Check that the invoice is signed correctly and that key recovery works pub fn check_signature(&self) -> Result<(), Bolt11SemanticError> { match self.signed_invoice.recover_payee_pub_key() { - Err(bitcoin::secp256k1::Error::InvalidRecoveryId) => - return Err(Bolt11SemanticError::InvalidRecoveryId), - Err(bitcoin::secp256k1::Error::InvalidSignature) => - return Err(Bolt11SemanticError::InvalidSignature), + Err(bitcoin::secp256k1::Error::InvalidRecoveryId) => { + return Err(Bolt11SemanticError::InvalidRecoveryId) + }, + Err(bitcoin::secp256k1::Error::InvalidSignature) => { + return Err(Bolt11SemanticError::InvalidSignature) + }, Err(e) => panic!("no other error may occur, got {:?}", e), Ok(_) => {}, } @@ -1356,10 +1396,10 @@ impl Bolt11Invoice { /// /// assert!(Bolt11Invoice::from_signed(signed).is_ok()); /// ``` - pub fn from_signed(signed_invoice: SignedRawBolt11Invoice) -> Result { - let invoice = Bolt11Invoice { - signed_invoice, - }; + pub fn from_signed( + signed_invoice: SignedRawBolt11Invoice, + ) -> Result { + let invoice = Bolt11Invoice { signed_invoice }; invoice.check_field_counts()?; invoice.check_feature_bits()?; invoice.check_signature()?; @@ -1382,8 +1422,9 @@ impl Bolt11Invoice { /// 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) - -> FilterMap, fn(&RawTaggedField) -> Option<&TaggedField>> { + pub fn tagged_fields( + &self, + ) -> FilterMap, fn(&RawTaggedField) -> Option<&TaggedField>> { self.signed_invoice.raw_invoice().known_tagged_fields() } @@ -1434,7 +1475,7 @@ impl Bolt11Invoice { pub fn get_payee_pub_key(&self) -> PublicKey { match self.payee_pub_key() { Some(pk) => *pk, - None => self.recover_payee_pub_key() + None => self.recover_payee_pub_key(), } } @@ -1446,7 +1487,8 @@ impl Bolt11Invoice { /// Returns the invoice's expiry time, if present, otherwise [`DEFAULT_EXPIRY_TIME`]. pub fn expiry_time(&self) -> Duration { - self.signed_invoice.expiry_time() + self.signed_invoice + .expiry_time() .map(|x| x.0) .unwrap_or(Duration::from_secs(DEFAULT_EXPIRY_TIME)) } @@ -1469,7 +1511,8 @@ impl Bolt11Invoice { /// Returns the Duration remaining until the invoice expires. #[cfg(feature = "std")] pub fn duration_until_expiry(&self) -> Duration { - SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) .map(|now| self.expiration_remaining_from_epoch(now)) .unwrap_or(Duration::from_nanos(0)) } @@ -1485,13 +1528,15 @@ impl Bolt11Invoice { pub fn would_expire(&self, at_time: Duration) -> bool { self.duration_since_epoch() .checked_add(self.expiry_time()) - .unwrap_or_else(|| Duration::new(u64::max_value(), 1_000_000_000 - 1)) < at_time + .unwrap_or_else(|| Duration::new(u64::max_value(), 1_000_000_000 - 1)) + < at_time } /// Returns the invoice's `min_final_cltv_expiry_delta` time, if present, otherwise /// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA`]. pub fn min_final_cltv_expiry_delta(&self) -> u64 { - self.signed_invoice.min_final_cltv_expiry_delta() + self.signed_invoice + .min_final_cltv_expiry_delta() .map(|x| x.0) .unwrap_or(DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA) } @@ -1509,16 +1554,14 @@ impl Bolt11Invoice { let address = match fallback { Fallback::SegWitProgram { version, program } => { match WitnessProgram::new(*version, &program) { - Ok(witness_program) => Address::from_witness_program(witness_program, self.network()), + Ok(witness_program) => { + Address::from_witness_program(witness_program, self.network()) + }, Err(_) => return None, } - } - Fallback::PubKeyHash(pkh) => { - Address::p2pkh(*pkh, self.network()) - } - Fallback::ScriptHash(sh) => { - Address::p2sh_from_hash(*sh, self.network()) - } + }, + Fallback::PubKeyHash(pkh) => Address::p2pkh(*pkh, self.network()), + Fallback::ScriptHash(sh) => Address::p2sh_from_hash(*sh, self.network()), }; Some(address) @@ -1534,8 +1577,12 @@ impl Bolt11Invoice { /// Returns a list of all routes included in the invoice as the underlying hints pub fn route_hints(&self) -> Vec { find_all_extract!( - self.signed_invoice.known_tagged_fields(), TaggedField::PrivateRoute(ref x), x - ).map(|route| (**route).clone()).collect() + self.signed_invoice.known_tagged_fields(), + TaggedField::PrivateRoute(ref x), + x + ) + .map(|route| (**route).clone()) + .collect() } /// Returns the currency for which the invoice was issued @@ -1589,7 +1636,6 @@ impl TaggedField { } impl Description { - /// Creates a new `Description` if `description` is at most 1023 * 5 bits (i.e., 639 bytes) /// long, and returns [`CreationError::DescriptionTooLong`] otherwise. /// @@ -1745,7 +1791,7 @@ impl Display for CreationError { } #[cfg(feature = "std")] -impl std::error::Error for CreationError { } +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 @@ -1801,7 +1847,7 @@ impl Display for Bolt11SemanticError { } #[cfg(feature = "std")] -impl std::error::Error for Bolt11SemanticError { } +impl std::error::Error for Bolt11SemanticError {} /// When signing using a fallible method either an user-supplied `SignError` or a [`CreationError`] /// may occur. @@ -1825,13 +1871,19 @@ impl Display for SignOrCreationError { #[cfg(feature = "serde")] impl Serialize for Bolt11Invoice { - fn serialize(&self, serializer: S) -> Result where S: Serializer { + 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 Bolt11Invoice { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { let bolt11 = String::deserialize(deserializer)? .parse::() .map_err(|e| D::Error::custom(format_args!("{:?}", e)))?; @@ -1842,8 +1894,8 @@ impl<'de> Deserialize<'de> for Bolt11Invoice { #[cfg(test)] mod test { - use bitcoin::ScriptBuf; use bitcoin::hashes::sha256; + use bitcoin::ScriptBuf; use std::str::FromStr; #[test] @@ -1856,24 +1908,28 @@ mod test { #[test] fn test_calc_invoice_hash() { - use crate::{RawBolt11Invoice, RawHrp, RawDataPart, Currency, PositiveTimestamp}; use crate::TaggedField::*; + use crate::{Currency, PositiveTimestamp, RawBolt11Invoice, RawDataPart, RawHrp}; let invoice = RawBolt11Invoice { - hrp: RawHrp { - currency: Currency::Bitcoin, - raw_amount: None, - si_prefix: None, - }, + hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None }, data: RawDataPart { timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(), tagged_fields: vec![ - PaymentHash(crate::Sha256(sha256::Hash::from_str( - "0001020304050607080900010203040506070809000102030405060708090102" - ).unwrap())).into(), - Description(crate::Description::new( - "Please consider supporting this project".to_owned() - ).unwrap()).into(), + PaymentHash(crate::Sha256( + sha256::Hash::from_str( + "0001020304050607080900010203040506070809000102030405060708090102", + ) + .unwrap(), + )) + .into(), + Description( + crate::Description::new( + "Please consider supporting this project".to_owned(), + ) + .unwrap(), + ) + .into(), ], }, }; @@ -1881,7 +1937,7 @@ mod test { let expected_hash = [ 0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, 0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d, 0xb2, 0xec, - 0xd5, 0x18, 0xe1, 0xc9 + 0xd5, 0x18, 0xe1, 0xc9, ]; assert_eq!(invoice.signable_hash(), expected_hash) @@ -1890,22 +1946,21 @@ mod test { #[test] fn test_check_signature() { use crate::TaggedField::*; + use crate::{ + Bolt11InvoiceSignature, Currency, PositiveTimestamp, RawBolt11Invoice, RawDataPart, + RawHrp, Sha256, SignedRawBolt11Invoice, + }; + use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId}; use bitcoin::secp256k1::Secp256k1; - use bitcoin::secp256k1::ecdsa::{RecoveryId, RecoverableSignature}; - use bitcoin::secp256k1::{SecretKey, PublicKey}; - use crate::{SignedRawBolt11Invoice, Bolt11InvoiceSignature, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, - PositiveTimestamp}; - - let invoice = SignedRawBolt11Invoice { - raw_invoice: RawBolt11Invoice { - hrp: RawHrp { - currency: Currency::Bitcoin, - raw_amount: None, - si_prefix: None, - }, - data: RawDataPart { - timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(), - tagged_fields: vec ! [ + use bitcoin::secp256k1::{PublicKey, SecretKey}; + + let invoice = + SignedRawBolt11Invoice { + raw_invoice: RawBolt11Invoice { + hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None }, + data: RawDataPart { + timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(), + tagged_fields: vec ! [ PaymentHash(Sha256(sha256::Hash::from_str( "0001020304050607080900010203040506070809000102030405060708090102" ).unwrap())).into(), @@ -1915,25 +1970,28 @@ mod test { ).unwrap() ).into(), ], + }, }, - }, - hash: [ - 0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, - 0x7b, 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, - 0x83, 0x5d, 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9 - ], - 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, - 0x4e, 0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f, - 0x42, 0x5f, 0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad, - 0x0d, 0x6e, 0x35, 0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9, - 0xaa, 0xb1, 0x5e, 0x57, 0x38, 0xb1, 0x1f, 0x12, 0x7f + hash: [ + 0xc3, 0xd4, 0xe8, 0x3f, 0x64, 0x6f, 0xa7, 0x9a, 0x39, 0x3d, 0x75, 0x27, 0x7b, + 0x1d, 0x85, 0x8d, 0xb1, 0xd1, 0xf7, 0xab, 0x71, 0x37, 0xdc, 0xb7, 0x83, 0x5d, + 0xb2, 0xec, 0xd5, 0x18, 0xe1, 0xc9, ], - RecoveryId::from_i32(0).unwrap() - ).unwrap()), - }; + 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, 0x4e, + 0x18, 0x45, 0xc8, 0xaf, 0x72, 0x05, 0xaf, 0xcf, 0xcc, 0x7f, 0x42, 0x5f, + 0xcd, 0x14, 0x63, 0xe9, 0x3c, 0x32, 0x88, 0x1e, 0xad, 0x0d, 0x6e, 0x35, + 0x6d, 0x46, 0x7e, 0xc8, 0xc0, 0x25, 0x53, 0xf9, 0xaa, 0xb1, 0x5e, 0x57, + 0x38, 0xb1, 0x1f, 0x12, 0x7f, + ], + RecoveryId::from_i32(0).unwrap(), + ) + .unwrap(), + ), + }; assert!(invoice.check_signature()); @@ -1941,17 +1999,18 @@ mod test { &[ 0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f, 0xe2, 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04, 0xa8, 0xca, - 0x3b, 0x2d, 0xb7, 0x34 - ][..] - ).unwrap(); + 0x3b, 0x2d, 0xb7, 0x34, + ][..], + ) + .unwrap(); let public_key = PublicKey::from_secret_key(&Secp256k1::new(), &private_key); assert_eq!(invoice.recover_payee_pub_key(), Ok(crate::PayeePubKey(public_key))); let (raw_invoice, _, _) = invoice.into_parts(); - let new_signed = raw_invoice.sign::<_, ()>(|hash| { - Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)) - }).unwrap(); + let new_signed = raw_invoice + .sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) + .unwrap(); assert!(new_signed.check_signature()); } @@ -1959,31 +2018,35 @@ mod test { #[test] fn test_check_feature_bits() { use crate::TaggedField::*; - use lightning_types::features::Bolt11InvoiceFeatures; + use crate::{ + Bolt11Invoice, Bolt11SemanticError, Currency, PositiveTimestamp, RawBolt11Invoice, + RawDataPart, RawHrp, Sha256, + }; use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::SecretKey; - use crate::{Bolt11Invoice, RawBolt11Invoice, RawHrp, RawDataPart, Currency, Sha256, PositiveTimestamp, - Bolt11SemanticError}; + use lightning_types::features::Bolt11InvoiceFeatures; let private_key = SecretKey::from_slice(&[42; 32]).unwrap(); let payment_secret = lightning_types::payment::PaymentSecret([21; 32]); let invoice_template = RawBolt11Invoice { - hrp: RawHrp { - currency: Currency::Bitcoin, - raw_amount: None, - si_prefix: None, - }, + hrp: RawHrp { currency: Currency::Bitcoin, raw_amount: None, si_prefix: None }, data: RawDataPart { timestamp: PositiveTimestamp::from_unix_timestamp(1496314658).unwrap(), - tagged_fields: vec ! [ - PaymentHash(Sha256(sha256::Hash::from_str( - "0001020304050607080900010203040506070809000102030405060708090102" - ).unwrap())).into(), + tagged_fields: vec![ + PaymentHash(Sha256( + sha256::Hash::from_str( + "0001020304050607080900010203040506070809000102030405060708090102", + ) + .unwrap(), + )) + .into(), Description( crate::Description::new( - "Please consider supporting this project".to_owned() - ).unwrap() - ).into(), + "Please consider supporting this project".to_owned(), + ) + .unwrap(), + ) + .into(), ], }, }; @@ -1992,8 +2055,11 @@ mod test { let invoice = { let mut invoice = invoice_template.clone(); invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); - invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) - }.unwrap(); + invoice.sign::<_, ()>(|hash| { + Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)) + }) + } + .unwrap(); assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::InvalidFeatures)); // Missing feature bits @@ -2001,8 +2067,11 @@ mod test { let mut invoice = invoice_template.clone(); invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); invoice.data.tagged_fields.push(Features(Bolt11InvoiceFeatures::empty()).into()); - invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) - }.unwrap(); + 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 = Bolt11InvoiceFeatures::empty(); @@ -2013,31 +2082,43 @@ mod test { let mut invoice = invoice_template.clone(); invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); invoice.data.tagged_fields.push(Features(payment_secret_features.clone()).into()); - invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) - }.unwrap(); + invoice.sign::<_, ()>(|hash| { + Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)) + }) + } + .unwrap(); 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(); + invoice.sign::<_, ()>(|hash| { + Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)) + }) + } + .unwrap(); assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret)); // No payment secret or feature bits let invoice = { let mut invoice = invoice_template.clone(); invoice.data.tagged_fields.push(Features(Bolt11InvoiceFeatures::empty()).into()); - invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) - }.unwrap(); + invoice.sign::<_, ()>(|hash| { + Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)) + }) + } + .unwrap(); assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret)); // Missing payment secret let invoice = { let mut invoice = invoice_template.clone(); invoice.data.tagged_fields.push(Features(payment_secret_features).into()); - invoice.sign::<_, ()>(|hash| Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key))) - }.unwrap(); + invoice.sign::<_, ()>(|hash| { + Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)) + }) + } + .unwrap(); assert_eq!(Bolt11Invoice::from_signed(invoice), Err(Bolt11SemanticError::NoPaymentSecret)); // Multiple payment secrets @@ -2045,9 +2126,15 @@ mod test { let mut invoice = invoice_template; invoice.data.tagged_fields.push(PaymentSecret(payment_secret).into()); 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(Bolt11SemanticError::MultiplePaymentSecrets)); + invoice.sign::<_, ()>(|hash| { + Ok(Secp256k1::new().sign_ecdsa_recoverable(hash, &private_key)) + }) + } + .unwrap(); + assert_eq!( + Bolt11Invoice::from_signed(invoice), + Err(Bolt11SemanticError::MultiplePaymentSecrets) + ); } #[test] @@ -2056,22 +2143,15 @@ mod test { let builder = InvoiceBuilder::new(Currency::Bitcoin) .description("Test".into()) - .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap()) + .payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap()) .duration_since_epoch(Duration::from_secs(1234567)); - let invoice = builder.clone() - .amount_milli_satoshis(1500) - .build_raw() - .unwrap(); + let invoice = builder.clone().amount_milli_satoshis(1500).build_raw().unwrap(); assert_eq!(invoice.hrp.si_prefix, Some(SiPrefix::Nano)); assert_eq!(invoice.hrp.raw_amount, Some(15)); - - let invoice = builder - .amount_milli_satoshis(150) - .build_raw() - .unwrap(); + let invoice = builder.amount_milli_satoshis(150).build_raw().unwrap(); assert_eq!(invoice.hrp.si_prefix, Some(SiPrefix::Pico)); assert_eq!(invoice.hrp.raw_amount, Some(1500)); @@ -2080,63 +2160,53 @@ mod test { #[test] fn test_builder_fail() { use crate::*; + use bitcoin::secp256k1::PublicKey; use lightning_types::routing::RouteHintHop; use std::iter::FromIterator; - use bitcoin::secp256k1::PublicKey; let builder = InvoiceBuilder::new(Currency::Bitcoin) - .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap()) + .payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap()) .duration_since_epoch(Duration::from_secs(1234567)) .min_final_cltv_expiry_delta(144); - let too_long_string = String::from_iter( - (0..1024).map(|_| '?') - ); + let too_long_string = String::from_iter((0..1024).map(|_| '?')); - let long_desc_res = builder.clone() - .description(too_long_string) - .build_raw(); + let long_desc_res = builder.clone().description(too_long_string).build_raw(); assert_eq!(long_desc_res, Err(CreationError::DescriptionTooLong)); let route_hop = RouteHintHop { src_node_id: PublicKey::from_slice( - &[ - 0x03, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, - 0x3c, 0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, - 0x95, 0xc3, 0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55 - ][..] - ).unwrap(), + &[ + 0x03, 0x9e, 0x03, 0xa9, 0x01, 0xb8, 0x55, 0x34, 0xff, 0x1e, 0x92, 0xc4, 0x3c, + 0x74, 0x43, 0x1f, 0x7c, 0xe7, 0x20, 0x46, 0x06, 0x0f, 0xcf, 0x7a, 0x95, 0xc3, + 0x7e, 0x14, 0x8f, 0x78, 0xc7, 0x72, 0x55, + ][..], + ) + .unwrap(), short_channel_id: 0, - fees: RoutingFees { - base_msat: 0, - proportional_millionths: 0, - }, + fees: RoutingFees { base_msat: 0, proportional_millionths: 0 }, cltv_expiry_delta: 0, htlc_minimum_msat: None, htlc_maximum_msat: None, }; let too_long_route = RouteHint(vec![route_hop; 13]); - let long_route_res = builder.clone() - .description("Test".into()) - .private_route(too_long_route) - .build_raw(); + let long_route_res = + builder.clone().description("Test".into()).private_route(too_long_route).build_raw(); assert_eq!(long_route_res, Err(CreationError::RouteTooLong)); let sign_error_res = builder .description("Test".into()) .payment_secret(PaymentSecret([0; 32])) - .try_build_signed(|_| { - Err("ImaginaryError") - }); + .try_build_signed(|_| Err("ImaginaryError")); assert_eq!(sign_error_res, Err(SignOrCreationError::SignError("ImaginaryError"))); } #[test] fn test_builder_ok() { use crate::*; - use lightning_types::routing::RouteHintHop; use bitcoin::secp256k1::Secp256k1; - use bitcoin::secp256k1::{SecretKey, PublicKey}; + use bitcoin::secp256k1::{PublicKey, SecretKey}; + use lightning_types::routing::RouteHintHop; use std::time::Duration; let secp_ctx = Secp256k1::new(); @@ -2145,19 +2215,17 @@ mod test { &[ 0xe1, 0x26, 0xf6, 0x8f, 0x7e, 0xaf, 0xcc, 0x8b, 0x74, 0xf5, 0x4d, 0x26, 0x9f, 0xe2, 0x06, 0xbe, 0x71, 0x50, 0x00, 0xf9, 0x4d, 0xac, 0x06, 0x7d, 0x1c, 0x04, 0xa8, 0xca, - 0x3b, 0x2d, 0xb7, 0x34 - ][..] - ).unwrap(); + 0x3b, 0x2d, 0xb7, 0x34, + ][..], + ) + .unwrap(); let public_key = PublicKey::from_secret_key(&secp_ctx, &private_key); let route_1 = RouteHint(vec![ RouteHintHop { src_node_id: public_key, short_channel_id: u64::from_be_bytes([123; 8]), - fees: RoutingFees { - base_msat: 2, - proportional_millionths: 1, - }, + fees: RoutingFees { base_msat: 2, proportional_millionths: 1 }, cltv_expiry_delta: 145, htlc_minimum_msat: None, htlc_maximum_msat: None, @@ -2165,24 +2233,18 @@ mod test { RouteHintHop { src_node_id: public_key, short_channel_id: u64::from_be_bytes([42; 8]), - fees: RoutingFees { - base_msat: 3, - proportional_millionths: 2, - }, + fees: RoutingFees { base_msat: 3, proportional_millionths: 2 }, cltv_expiry_delta: 146, htlc_minimum_msat: None, htlc_maximum_msat: None, - } + }, ]); let route_2 = RouteHint(vec![ RouteHintHop { src_node_id: public_key, short_channel_id: 0, - fees: RoutingFees { - base_msat: 4, - proportional_millionths: 3, - }, + fees: RoutingFees { base_msat: 4, proportional_millionths: 3 }, cltv_expiry_delta: 147, htlc_minimum_msat: None, htlc_maximum_msat: None, @@ -2190,14 +2252,11 @@ mod test { RouteHintHop { src_node_id: public_key, short_channel_id: u64::from_be_bytes([1; 8]), - fees: RoutingFees { - base_msat: 5, - proportional_millionths: 4, - }, + fees: RoutingFees { base_msat: 5, proportional_millionths: 4 }, cltv_expiry_delta: 148, htlc_minimum_msat: None, htlc_maximum_msat: None, - } + }, ]); let builder = InvoiceBuilder::new(Currency::BitcoinTestnet) @@ -2206,17 +2265,18 @@ mod test { .payee_pub_key(public_key) .expiry_time(Duration::from_secs(54321)) .min_final_cltv_expiry_delta(144) - .fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[0;20]).unwrap())) + .fallback(Fallback::PubKeyHash(PubkeyHash::from_slice(&[0; 20]).unwrap())) .private_route(route_1.clone()) .private_route(route_2.clone()) - .description_hash(sha256::Hash::from_slice(&[3;32][..]).unwrap()) - .payment_hash(sha256::Hash::from_slice(&[21;32][..]).unwrap()) + .description_hash(sha256::Hash::from_slice(&[3; 32][..]).unwrap()) + .payment_hash(sha256::Hash::from_slice(&[21; 32][..]).unwrap()) .payment_secret(PaymentSecret([42; 32])) .basic_mpp(); - let invoice = builder.clone().build_signed(|hash| { - secp_ctx.sign_ecdsa_recoverable(hash, &private_key) - }).unwrap(); + let invoice = builder + .clone() + .build_signed(|hash| secp_ctx.sign_ecdsa_recoverable(hash, &private_key)) + .unwrap(); assert!(invoice.check_signature().is_ok()); assert_eq!(invoice.tagged_fields().count(), 10); @@ -2232,15 +2292,24 @@ mod test { assert_eq!(invoice.payee_pub_key(), Some(&public_key)); assert_eq!(invoice.expiry_time(), Duration::from_secs(54321)); assert_eq!(invoice.min_final_cltv_expiry_delta(), 144); - assert_eq!(invoice.fallbacks(), vec![&Fallback::PubKeyHash(PubkeyHash::from_slice(&[0;20]).unwrap())]); - let address = Address::from_script(&ScriptBuf::new_p2pkh(&PubkeyHash::from_slice(&[0;20]).unwrap()), Network::Testnet).unwrap(); + assert_eq!( + invoice.fallbacks(), + vec![&Fallback::PubKeyHash(PubkeyHash::from_slice(&[0; 20]).unwrap())] + ); + let address = Address::from_script( + &ScriptBuf::new_p2pkh(&PubkeyHash::from_slice(&[0; 20]).unwrap()), + Network::Testnet, + ) + .unwrap(); assert_eq!(invoice.fallback_addresses(), vec![address]); assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]); assert_eq!( invoice.description(), - Bolt11InvoiceDescriptionRef::Hash(&Sha256(sha256::Hash::from_slice(&[3;32][..]).unwrap())) + Bolt11InvoiceDescriptionRef::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_hash(), &sha256::Hash::from_slice(&[21; 32][..]).unwrap()); assert_eq!(invoice.payment_secret(), &PaymentSecret([42; 32])); let mut expected_features = Bolt11InvoiceFeatures::empty(); @@ -2261,7 +2330,7 @@ mod test { let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin) .description("Test".into()) - .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap()) + .payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap()) .payment_secret(PaymentSecret([0; 32])) .duration_since_epoch(Duration::from_secs(1234567)) .build_raw() @@ -2287,7 +2356,7 @@ mod test { let signed_invoice = InvoiceBuilder::new(Currency::Bitcoin) .description("Test".into()) - .payment_hash(sha256::Hash::from_slice(&[0;32][..]).unwrap()) + .payment_hash(sha256::Hash::from_slice(&[0; 32][..]).unwrap()) .payment_secret(PaymentSecret([0; 32])) .duration_since_epoch(Duration::from_secs(1234567)) .build_raw() @@ -2319,7 +2388,8 @@ mod test { j5r6drg6k6zcqj0fcwg"; let invoice = invoice_str.parse::().unwrap(); let serialized_invoice = serde_json::to_string(&invoice).unwrap(); - let deserialized_invoice: super::Bolt11Invoice = 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('\"')); @@ -2327,16 +2397,19 @@ mod test { #[test] fn raw_tagged_field_ordering() { - use crate::{Description, Fe32, RawTaggedField, TaggedField, Sha256, sha256, UntrustedString}; + use crate::{ + sha256, Description, Fe32, RawTaggedField, Sha256, TaggedField, UntrustedString, + }; - let field10 = RawTaggedField::KnownSemantics( - TaggedField::PaymentHash(Sha256(sha256::Hash::from_str( - "0001020304050607080900010203040506070809000102030405060708090102" - ).unwrap())) - ); - let field11 = RawTaggedField::KnownSemantics( - TaggedField::Description(Description(UntrustedString("Description".to_string()))) - ); + let field10 = RawTaggedField::KnownSemantics(TaggedField::PaymentHash(Sha256( + sha256::Hash::from_str( + "0001020304050607080900010203040506070809000102030405060708090102", + ) + .unwrap(), + ))); + let field11 = RawTaggedField::KnownSemantics(TaggedField::Description(Description( + UntrustedString("Description".to_string()), + ))); let field20 = RawTaggedField::UnknownSemantics(vec![Fe32::Q]); let field21 = RawTaggedField::UnknownSemantics(vec![Fe32::R]); -- 2.39.5