Skip to content

Commit 0e1723d

Browse files
committed
Owned and ref versions of Bolt11InvoiceDescription
Split Bolt11InvoiceDescription into a version used with references to the description or description hash in the invoice and an owned version of these for when constructing an invoice. The latter is useful as it removes an unnecessary clone and can be used in a future change specifying either a description or description hash in larger set of invoice parameters. Since it doesn't use a reference, it can be exposed in bindings as well.
1 parent 206ab82 commit 0e1723d

File tree

2 files changed

+43
-23
lines changed

2 files changed

+43
-23
lines changed

lightning-invoice/src/lib.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,25 +233,45 @@ pub struct Bolt11Invoice {
233233
signed_invoice: SignedRawBolt11Invoice,
234234
}
235235

236+
/// Represents the description of an invoice which has to be either a directly included string or
237+
/// a hash of a description provided out of band.
238+
#[derive(Eq, PartialEq, Debug, Clone, Ord, PartialOrd)]
239+
pub enum Bolt11InvoiceDescription {
240+
/// Description of what the invoice is for
241+
Direct(Description),
242+
243+
/// Hash of the description of what the invoice is for
244+
Hash(Sha256),
245+
}
246+
247+
impl Display for Bolt11InvoiceDescription {
248+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
249+
match self {
250+
Bolt11InvoiceDescription::Direct(desc) => write!(f, "{}", desc.0),
251+
Bolt11InvoiceDescription::Hash(hash) => write!(f, "{}", hash.0),
252+
}
253+
}
254+
}
255+
236256
/// Represents the description of an invoice which has to be either a directly included string or
237257
/// a hash of a description provided out of band.
238258
///
239259
/// This is not exported to bindings users as we don't have a good way to map the reference lifetimes making this
240260
/// practically impossible to use safely in languages like C.
241261
#[derive(Eq, PartialEq, Debug, Clone, Ord, PartialOrd)]
242-
pub enum Bolt11InvoiceDescription<'f> {
262+
pub enum Bolt11InvoiceDescriptionRef<'f> {
243263
/// Reference to the directly supplied description in the invoice
244264
Direct(&'f Description),
245265

246266
/// Reference to the description's hash included in the invoice
247267
Hash(&'f Sha256),
248268
}
249269

250-
impl<'f> Display for Bolt11InvoiceDescription<'f> {
270+
impl<'f> Display for Bolt11InvoiceDescriptionRef<'f> {
251271
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
252272
match self {
253-
Bolt11InvoiceDescription::Direct(desc) => write!(f, "{}", desc.0),
254-
Bolt11InvoiceDescription::Hash(hash) => write!(f, "{}", hash.0),
273+
Bolt11InvoiceDescriptionRef::Direct(desc) => write!(f, "{}", desc.0),
274+
Bolt11InvoiceDescriptionRef::Hash(hash) => write!(f, "{}", hash.0),
255275
}
256276
}
257277
}
@@ -708,7 +728,7 @@ impl<H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool> InvoiceBui
708728
pub fn invoice_description(self, description: Bolt11InvoiceDescription) -> InvoiceBuilder<tb::True, H, T, C, S, M> {
709729
match description {
710730
Bolt11InvoiceDescription::Direct(desc) => {
711-
self.description(desc.clone().into_inner().0)
731+
self.description(desc.0.0)
712732
}
713733
Bolt11InvoiceDescription::Hash(hash) => {
714734
self.description_hash(hash.0)
@@ -1374,11 +1394,11 @@ impl Bolt11Invoice {
13741394
/// Return the description or a hash of it for longer ones
13751395
///
13761396
/// This is not exported to bindings users because we don't yet export Bolt11InvoiceDescription
1377-
pub fn description(&self) -> Bolt11InvoiceDescription {
1397+
pub fn description(&self) -> Bolt11InvoiceDescriptionRef {
13781398
if let Some(direct) = self.signed_invoice.description() {
1379-
return Bolt11InvoiceDescription::Direct(direct);
1399+
return Bolt11InvoiceDescriptionRef::Direct(direct);
13801400
} else if let Some(hash) = self.signed_invoice.description_hash() {
1381-
return Bolt11InvoiceDescription::Hash(hash);
1401+
return Bolt11InvoiceDescriptionRef::Hash(hash);
13821402
}
13831403
unreachable!("ensured by constructor");
13841404
}
@@ -2211,7 +2231,7 @@ mod test {
22112231
assert_eq!(invoice.private_routes(), vec![&PrivateRoute(route_1), &PrivateRoute(route_2)]);
22122232
assert_eq!(
22132233
invoice.description(),
2214-
Bolt11InvoiceDescription::Hash(&Sha256(sha256::Hash::from_slice(&[3;32][..]).unwrap()))
2234+
Bolt11InvoiceDescriptionRef::Hash(&Sha256(sha256::Hash::from_slice(&[3;32][..]).unwrap()))
22152235
);
22162236
assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&[21;32][..]).unwrap());
22172237
assert_eq!(invoice.payment_secret(), &PaymentSecret([42; 32]));

lightning/src/ln/invoice_utils.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ where
7575
L::Target: Logger,
7676
{
7777
let description = Description::new(description).map_err(SignOrCreationError::CreationError)?;
78-
let description = Bolt11InvoiceDescription::Direct(&description,);
78+
let description = Bolt11InvoiceDescription::Direct(description);
7979
_create_phantom_invoice::<ES, NS, L>(
8080
amt_msat, payment_hash, description, invoice_expiry_delta_secs, phantom_route_hints,
8181
entropy_source, node_signer, logger, network, min_final_cltv_expiry_delta, duration_since_epoch,
@@ -130,7 +130,7 @@ where
130130
L::Target: Logger,
131131
{
132132
_create_phantom_invoice::<ES, NS, L>(
133-
amt_msat, payment_hash, Bolt11InvoiceDescription::Hash(&description_hash),
133+
amt_msat, payment_hash, Bolt11InvoiceDescription::Hash(description_hash),
134134
invoice_expiry_delta_secs, phantom_route_hints, entropy_source, node_signer, logger, network,
135135
min_final_cltv_expiry_delta, duration_since_epoch,
136136
)
@@ -161,7 +161,7 @@ where
161161

162162
let invoice = match description {
163163
Bolt11InvoiceDescription::Direct(description) => {
164-
InvoiceBuilder::new(network).description(description.as_inner().0.clone())
164+
InvoiceBuilder::new(network).description(description.into_inner().0)
165165
}
166166
Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0),
167167
};
@@ -424,7 +424,7 @@ where
424424
{
425425
_create_invoice_from_channelmanager_and_duration_since_epoch(
426426
channelmanager, node_signer, logger, network, amt_msat,
427-
Bolt11InvoiceDescription::Hash(&description_hash),
427+
Bolt11InvoiceDescription::Hash(description_hash),
428428
duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
429429
)
430430
}
@@ -454,7 +454,7 @@ where
454454
_create_invoice_from_channelmanager_and_duration_since_epoch(
455455
channelmanager, node_signer, logger, network, amt_msat,
456456
Bolt11InvoiceDescription::Direct(
457-
&Description::new(description).map_err(SignOrCreationError::CreationError)?,
457+
Description::new(description).map_err(SignOrCreationError::CreationError)?,
458458
),
459459
duration_since_epoch, invoice_expiry_delta_secs, min_final_cltv_expiry_delta,
460460
)
@@ -518,7 +518,7 @@ where
518518
.map_err(|()| SignOrCreationError::CreationError(CreationError::InvalidAmount))?;
519519
_create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash(
520520
channelmanager, node_signer, logger, network, amt_msat,
521-
Bolt11InvoiceDescription::Hash(&description_hash),
521+
Bolt11InvoiceDescription::Hash(description_hash),
522522
duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret,
523523
min_final_cltv_expiry_delta,
524524
)
@@ -551,7 +551,7 @@ where
551551
_create_invoice_from_channelmanager_and_duration_since_epoch_with_payment_hash(
552552
channelmanager, node_signer, logger, network, amt_msat,
553553
Bolt11InvoiceDescription::Direct(
554-
&Description::new(description).map_err(SignOrCreationError::CreationError)?,
554+
Description::new(description).map_err(SignOrCreationError::CreationError)?,
555555
),
556556
duration_since_epoch, invoice_expiry_delta_secs, payment_hash, payment_secret,
557557
min_final_cltv_expiry_delta,
@@ -586,7 +586,7 @@ where
586586

587587
let invoice = match description {
588588
Bolt11InvoiceDescription::Direct(description) => {
589-
InvoiceBuilder::new(network).description(description.as_inner().0.clone())
589+
InvoiceBuilder::new(network).description(description.into_inner().0)
590590
}
591591
Bolt11InvoiceDescription::Hash(hash) => InvoiceBuilder::new(network).description_hash(hash.0),
592592
};
@@ -864,7 +864,7 @@ impl<'a, 'b, L: Deref> WithChannelDetails<'a, 'b, L> where L::Target: Logger {
864864
mod test {
865865
use super::*;
866866
use core::time::Duration;
867-
use lightning_invoice::{Currency, Description, Bolt11InvoiceDescription, SignOrCreationError, CreationError};
867+
use lightning_invoice::{Currency, Description, Bolt11InvoiceDescriptionRef, SignOrCreationError, CreationError};
868868
use bitcoin::hashes::{Hash, sha256};
869869
use bitcoin::hashes::sha256::Hash as Sha256;
870870
use crate::sign::PhantomKeysManager;
@@ -921,7 +921,7 @@ mod test {
921921
assert_eq!(invoice.amount_milli_satoshis(), Some(10_000));
922922
// If no `min_final_cltv_expiry_delta` is specified, then it should be `MIN_FINAL_CLTV_EXPIRY_DELTA`.
923923
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
924-
assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description::new("test".to_string()).unwrap()));
924+
assert_eq!(invoice.description(), Bolt11InvoiceDescriptionRef::Direct(&Description::new("test".to_string()).unwrap()));
925925
assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
926926

927927
// Invoice SCIDs should always use inbound SCID aliases over the real channel ID, if one is
@@ -1009,7 +1009,7 @@ mod test {
10091009
).unwrap();
10101010
assert_eq!(invoice.amount_milli_satoshis(), Some(10_000));
10111011
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
1012-
assert_eq!(invoice.description(), Bolt11InvoiceDescription::Hash(&Sha256(Sha256::hash("Testing description_hash".as_bytes()))));
1012+
assert_eq!(invoice.description(), Bolt11InvoiceDescriptionRef::Hash(&Sha256(Sha256::hash("Testing description_hash".as_bytes()))));
10131013
}
10141014

10151015
#[test]
@@ -1026,7 +1026,7 @@ mod test {
10261026
).unwrap();
10271027
assert_eq!(invoice.amount_milli_satoshis(), Some(10_000));
10281028
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
1029-
assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description::new("test".to_string()).unwrap()));
1029+
assert_eq!(invoice.description(), Bolt11InvoiceDescriptionRef::Direct(&Description::new("test".to_string()).unwrap()));
10301030
assert_eq!(invoice.payment_hash(), &sha256::Hash::from_slice(&payment_hash.0[..]).unwrap());
10311031
}
10321032

@@ -1379,7 +1379,7 @@ mod test {
13791379
};
13801380

13811381
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
1382-
assert_eq!(invoice.description(), Bolt11InvoiceDescription::Direct(&Description::new("test".to_string()).unwrap()));
1382+
assert_eq!(invoice.description(), Bolt11InvoiceDescriptionRef::Direct(&Description::new("test".to_string()).unwrap()));
13831383
assert_eq!(invoice.route_hints().len(), 2);
13841384
assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
13851385
assert!(!invoice.features().unwrap().supports_basic_mpp());
@@ -1498,7 +1498,7 @@ mod test {
14981498
assert_eq!(invoice.amount_milli_satoshis(), Some(20_000));
14991499
assert_eq!(invoice.min_final_cltv_expiry_delta(), MIN_FINAL_CLTV_EXPIRY_DELTA as u64);
15001500
assert_eq!(invoice.expiry_time(), Duration::from_secs(non_default_invoice_expiry_secs.into()));
1501-
assert_eq!(invoice.description(), Bolt11InvoiceDescription::Hash(&Sha256(Sha256::hash("Description hash phantom invoice".as_bytes()))));
1501+
assert_eq!(invoice.description(), Bolt11InvoiceDescriptionRef::Hash(&Sha256(Sha256::hash("Description hash phantom invoice".as_bytes()))));
15021502
}
15031503

15041504
#[test]

0 commit comments

Comments
 (0)