X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-invoice%2Fsrc%2Flib.rs;h=593701cab458c85079dff3e135dcebbf63845277;hb=36235c38f16dd99f62d1b3eb458d69211e4fdef6;hp=17b6e2de2b6efe8582f9f78823289f306c9f4991;hpb=3bd395f2a8a7398d7bf5ad9b2c7257e64f9c126b;p=rust-lightning diff --git a/lightning-invoice/src/lib.rs b/lightning-invoice/src/lib.rs index 17b6e2de2..593701cab 100644 --- a/lightning-invoice/src/lib.rs +++ b/lightning-invoice/src/lib.rs @@ -216,7 +216,7 @@ pub const DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA: u64 = 18; /// * `H`: exactly one `PaymentHash` /// * `T`: the timestamp is set /// -/// (C-not exported) as we likely need to manually select one set of boolean type parameters. +/// 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 { currency: Currency, @@ -247,7 +247,7 @@ pub struct Invoice { /// Represents the description of an invoice which has to be either a directly included string or /// a hash of a description provided out of band. /// -/// (C-not exported) As we don't have a good way to map the reference lifetimes making this +/// 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)] pub enum InvoiceDescription<'f> { @@ -297,7 +297,7 @@ pub struct RawInvoice { /// Data of the `RawInvoice` that is encoded in the human readable part /// -/// (C-not exported) As we don't yet support `Option` +/// This is not exported to bindings users as we don't yet support `Option` #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub struct RawHrp { /// The currency deferred from the 3rd and 4th character of the bech32 transaction @@ -357,7 +357,7 @@ impl SiPrefix { /// Returns all enum variants of `SiPrefix` sorted in descending order of their associated /// multiplier. /// - /// (C-not exported) As we don't yet support a slice of enums, and also because this function + /// This is not exported to bindings users as we don't yet support a slice of enums, and also because this function /// isn't the most critical to expose. pub fn values_desc() -> &'static [SiPrefix] { use crate::SiPrefix::*; @@ -387,7 +387,7 @@ pub enum Currency { /// Tagged field which may have an unknown tag /// -/// (C-not exported) as we don't currently support TaggedField +/// This is not exported to bindings users as we don't currently support TaggedField #[derive(Clone, Debug, Hash, Eq, PartialEq)] pub enum RawTaggedField { /// Parsed tagged field with known tag @@ -400,7 +400,7 @@ pub enum RawTaggedField { /// /// For descriptions of the enum values please refer to the enclosed type's docs. /// -/// (C-not exported) As we don't yet support enum variants with the same name the struct contained +/// This is not exported to bindings users as we don't yet support enum variants with the same name the struct contained /// in the variant. #[allow(missing_docs)] #[derive(Clone, Debug, Hash, Eq, PartialEq)] @@ -419,7 +419,7 @@ pub enum TaggedField { /// SHA-256 hash #[derive(Clone, Debug, Hash, Eq, PartialEq)] -pub struct Sha256(/// (C-not exported) as the native hash types are not currently mapped +pub struct Sha256(/// This is not exported to bindings users as the native hash types are not currently mapped pub sha256::Hash); /// Description string @@ -585,13 +585,13 @@ impl InvoiceBuilder>(); let data = RawDataPart { - timestamp: timestamp, - tagged_fields: tagged_fields, + timestamp, + tagged_fields, }; Ok(RawInvoice { - hrp: hrp, - data: data, + hrp, + data, }) } } @@ -611,6 +611,18 @@ impl InvoiceBuilder InvoiceBuilder { + match description { + InvoiceDescription::Direct(desc) => { + self.description(desc.clone().into_inner()) + } + InvoiceDescription::Hash(hash) => { + self.description_hash(hash.0) + } + } + } } impl InvoiceBuilder { @@ -781,7 +793,7 @@ impl SignedRawInvoice { recovered_pub_key = Some(recovered); } - let pub_key = included_pub_key.or_else(|| recovered_pub_key.as_ref()) + let pub_key = included_pub_key.or(recovered_pub_key.as_ref()) .expect("One is always present"); let hash = Message::from_slice(&self.hash[..]) @@ -873,7 +885,7 @@ impl RawInvoice { /// of type `E`. Since the signature of a `SignedRawInvoice` is not required to be valid there /// are no constraints regarding the validity of the produced signature. /// - /// (C-not exported) As we don't currently support passing function pointers into methods + /// 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 @@ -892,7 +904,7 @@ impl RawInvoice { /// Returns an iterator over all tagged fields with known semantics. /// - /// (C-not exported) As there is not yet a manual mapping for a FilterMap + /// 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>> { @@ -941,7 +953,7 @@ impl RawInvoice { find_extract!(self.known_tagged_fields(), TaggedField::Features(ref x), x) } - /// (C-not exported) as we don't support Vec<&NonOpaqueType> + /// This is not exported to bindings users as we don't support Vec<&NonOpaqueType> pub fn fallbacks(&self) -> Vec<&Fallback> { find_all_extract!(self.known_tagged_fields(), TaggedField::Fallback(ref x), x).collect() } @@ -1014,9 +1026,9 @@ impl PositiveTimestamp { } #[cfg(feature = "std")] -impl Into for PositiveTimestamp { - fn into(self) -> SystemTime { - SystemTime::UNIX_EPOCH + self.0 +impl From for SystemTime { + fn from(val: PositiveTimestamp) -> Self { + SystemTime::UNIX_EPOCH + val.0 } } @@ -1147,7 +1159,7 @@ impl Invoice { /// ``` pub fn from_signed(signed_invoice: SignedRawInvoice) -> Result { let invoice = Invoice { - signed_invoice: signed_invoice, + signed_invoice, }; invoice.check_field_counts()?; invoice.check_feature_bits()?; @@ -1170,7 +1182,7 @@ impl Invoice { /// Returns an iterator over all tagged fields of this Invoice. /// - /// (C-not exported) As there is not yet a manual mapping for a FilterMap + /// 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>> { self.signed_invoice.raw_invoice().known_tagged_fields() @@ -1183,11 +1195,11 @@ impl Invoice { /// Return the description or a hash of it for longer ones /// - /// (C-not exported) because we don't yet export InvoiceDescription + /// This is not exported to bindings users because we don't yet export InvoiceDescription pub fn description(&self) -> InvoiceDescription { - if let Some(ref direct) = self.signed_invoice.description() { + if let Some(direct) = self.signed_invoice.description() { return InvoiceDescription::Direct(direct); - } else if let Some(ref hash) = self.signed_invoice.description_hash() { + } else if let Some(hash) = self.signed_invoice.description_hash() { return InvoiceDescription::Hash(hash); } unreachable!("ensured by constructor"); @@ -1213,6 +1225,12 @@ impl Invoice { self.signed_invoice.recover_payee_pub_key().expect("was checked by constructor").0 } + /// Returns the Duration since the Unix epoch at which the invoice expires. + /// Returning None if overflow occurred. + pub fn expires_at(&self) -> Option { + self.duration_since_epoch().checked_add(self.expiry_time()) + } + /// Returns the invoice's expiry time, if present, otherwise [`DEFAULT_EXPIRY_TIME`]. pub fn expiry_time(&self) -> Duration { self.signed_invoice.expiry_time() @@ -1235,6 +1253,20 @@ impl Invoice { } } + /// 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) + .map(|now| self.expiration_remaining_from_epoch(now)) + .unwrap_or(Duration::from_nanos(0)) + } + + /// Returns the Duration remaining until the invoice expires given the current time. + /// `time` is the timestamp as a duration since the Unix epoch. + pub fn expiration_remaining_from_epoch(&self, time: Duration) -> Duration { + self.expires_at().map(|x| x.checked_sub(time)).flatten().unwrap_or(Duration::from_nanos(0)) + } + /// Returns whether the expiry time would pass at the given point in time. /// `at_time` is the timestamp as a duration since the Unix epoch. pub fn would_expire(&self, at_time: Duration) -> bool { @@ -1253,7 +1285,7 @@ impl Invoice { /// Returns a list of all fallback addresses /// - /// (C-not exported) as we don't support Vec<&NonOpaqueType> + /// This is not exported to bindings users as we don't support Vec<&NonOpaqueType> pub fn fallbacks(&self) -> Vec<&Fallback> { self.signed_invoice.fallbacks() } @@ -1332,9 +1364,9 @@ impl Description { } } -impl Into for Description { - fn into(self) -> String { - self.into_inner() +impl From for String { + fn from(val: Description) -> Self { + val.into_inner() } } @@ -1398,9 +1430,9 @@ impl PrivateRoute { } } -impl Into for PrivateRoute { - fn into(self) -> RouteHint { - self.into_inner() +impl From for RouteHint { + fn from(val: PrivateRoute) -> Self { + val.into_inner() } } @@ -1766,7 +1798,7 @@ mod test { // Multiple payment secrets let invoice = { - let mut invoice = invoice_template.clone(); + 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))) @@ -1792,7 +1824,7 @@ mod test { assert_eq!(invoice.hrp.raw_amount, Some(15)); - let invoice = builder.clone() + let invoice = builder .amount_milli_satoshis(150) .build_raw() .unwrap(); @@ -1846,7 +1878,7 @@ mod test { .build_raw(); assert_eq!(long_route_res, Err(CreationError::RouteTooLong)); - let sign_error_res = builder.clone() + let sign_error_res = builder .description("Test".into()) .payment_secret(PaymentSecret([0; 32])) .try_build_signed(|_| { @@ -1876,7 +1908,7 @@ mod test { let route_1 = RouteHint(vec![ RouteHintHop { - src_node_id: public_key.clone(), + src_node_id: public_key, short_channel_id: de::parse_int_be(&[123; 8], 256).expect("short chan ID slice too big?"), fees: RoutingFees { base_msat: 2, @@ -1887,7 +1919,7 @@ mod test { htlc_maximum_msat: None, }, RouteHintHop { - src_node_id: public_key.clone(), + src_node_id: public_key, short_channel_id: de::parse_int_be(&[42; 8], 256).expect("short chan ID slice too big?"), fees: RoutingFees { base_msat: 3, @@ -1901,7 +1933,7 @@ mod test { let route_2 = RouteHint(vec![ RouteHintHop { - src_node_id: public_key.clone(), + src_node_id: public_key, short_channel_id: 0, fees: RoutingFees { base_msat: 4, @@ -1912,7 +1944,7 @@ mod test { htlc_maximum_msat: None, }, RouteHintHop { - src_node_id: public_key.clone(), + src_node_id: public_key, short_channel_id: de::parse_int_be(&[1; 8], 256).expect("short chan ID slice too big?"), fees: RoutingFees { base_msat: 5, @@ -1927,7 +1959,7 @@ mod test { let builder = InvoiceBuilder::new(Currency::BitcoinTestnet) .amount_milli_satoshis(123) .duration_since_epoch(Duration::from_secs(1234567)) - .payee_pub_key(public_key.clone()) + .payee_pub_key(public_key) .expiry_time(Duration::from_secs(54321)) .min_final_cltv_expiry_delta(144) .fallback(Fallback::PubKeyHash([0;20]))