Skip to content

Commit 4763612

Browse files
committed
Make separate no-std version for invoice response
Both Refund::respond_with and InvoiceRequest::respond_with take a created_at since the Unix epoch Duration in no-std. However, this can cause problems if two downstream dependencies want to use the lightning crate with different feature flags set. Instead, define respond_with_no_std versions of each method in addition to a respond_with version in std.
1 parent 3302f25 commit 4763612

File tree

3 files changed

+73
-47
lines changed

3 files changed

+73
-47
lines changed

lightning/src/offers/invoice.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
.respond_with(payment_paths, payment_hash)?
5050
")]
5151
#![cfg_attr(not(feature = "std"), doc = "
52-
.respond_with(payment_paths, payment_hash, core::time::Duration::from_secs(0))?
52+
.respond_with_no_std(payment_paths, payment_hash, core::time::Duration::from_secs(0))?
5353
")]
5454
//! .relative_expiry(3600)
5555
//! .allow_mpp()
@@ -78,7 +78,7 @@
7878
.respond_with(payment_paths, payment_hash, pubkey)?
7979
")]
8080
#![cfg_attr(not(feature = "std"), doc = "
81-
.respond_with(payment_paths, payment_hash, pubkey, core::time::Duration::from_secs(0))?
81+
.respond_with_no_std(payment_paths, payment_hash, pubkey, core::time::Duration::from_secs(0))?
8282
")]
8383
//! .relative_expiry(3600)
8484
//! .allow_mpp()
@@ -886,7 +886,7 @@ mod tests {
886886
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
887887
.build().unwrap()
888888
.sign(payer_sign).unwrap()
889-
.respond_with(payment_paths.clone(), payment_hash, now).unwrap()
889+
.respond_with_no_std(payment_paths.clone(), payment_hash, now).unwrap()
890890
.build().unwrap()
891891
.sign(recipient_sign).unwrap();
892892

@@ -962,7 +962,8 @@ mod tests {
962962
let now = now();
963963
let invoice = RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
964964
.build().unwrap()
965-
.respond_with(payment_paths.clone(), payment_hash, recipient_pubkey(), now).unwrap()
965+
.respond_with_no_std(payment_paths.clone(), payment_hash, recipient_pubkey(), now)
966+
.unwrap()
966967
.build().unwrap()
967968
.sign(recipient_sign).unwrap();
968969

@@ -1040,7 +1041,8 @@ mod tests {
10401041
if let Err(e) = RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
10411042
.absolute_expiry(future_expiry)
10421043
.build().unwrap()
1043-
.respond_with(payment_paths(), payment_hash(), recipient_pubkey(), now()).unwrap()
1044+
.respond_with(payment_paths(), payment_hash(), recipient_pubkey())
1045+
.unwrap()
10441046
.build()
10451047
{
10461048
panic!("error building invoice: {:?}", e);
@@ -1049,7 +1051,8 @@ mod tests {
10491051
match RefundBuilder::new("foo".into(), vec![1; 32], payer_pubkey(), 1000).unwrap()
10501052
.absolute_expiry(past_expiry)
10511053
.build().unwrap()
1052-
.respond_with(payment_paths(), payment_hash(), recipient_pubkey(), now()).unwrap()
1054+
.respond_with(payment_paths(), payment_hash(), recipient_pubkey())
1055+
.unwrap()
10531056
.build()
10541057
{
10551058
Ok(_) => panic!("expected error"),
@@ -1068,7 +1071,7 @@ mod tests {
10681071
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
10691072
.build().unwrap()
10701073
.sign(payer_sign).unwrap()
1071-
.respond_with(payment_paths(), payment_hash(), now).unwrap()
1074+
.respond_with_no_std(payment_paths(), payment_hash(), now).unwrap()
10721075
.relative_expiry(one_hour.as_secs() as u32)
10731076
.build().unwrap()
10741077
.sign(recipient_sign).unwrap();
@@ -1084,7 +1087,7 @@ mod tests {
10841087
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
10851088
.build().unwrap()
10861089
.sign(payer_sign).unwrap()
1087-
.respond_with(payment_paths(), payment_hash(), now - one_hour).unwrap()
1090+
.respond_with_no_std(payment_paths(), payment_hash(), now - one_hour).unwrap()
10881091
.relative_expiry(one_hour.as_secs() as u32 - 1)
10891092
.build().unwrap()
10901093
.sign(recipient_sign).unwrap();
@@ -1104,7 +1107,7 @@ mod tests {
11041107
.amount_msats(1001).unwrap()
11051108
.build().unwrap()
11061109
.sign(payer_sign).unwrap()
1107-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1110+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
11081111
.build().unwrap()
11091112
.sign(recipient_sign).unwrap();
11101113
let (_, _, _, tlv_stream, _) = invoice.as_tlv_stream();
@@ -1125,7 +1128,7 @@ mod tests {
11251128
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
11261129
.build().unwrap()
11271130
.sign(payer_sign).unwrap()
1128-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1131+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
11291132
.fallback_v0_p2wsh(&script.wscript_hash())
11301133
.fallback_v0_p2wpkh(&pubkey.wpubkey_hash().unwrap())
11311134
.fallback_v1_p2tr_tweaked(&tweaked_pubkey)
@@ -1170,7 +1173,7 @@ mod tests {
11701173
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
11711174
.build().unwrap()
11721175
.sign(payer_sign).unwrap()
1173-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1176+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
11741177
.allow_mpp()
11751178
.build().unwrap()
11761179
.sign(recipient_sign).unwrap();
@@ -1187,7 +1190,7 @@ mod tests {
11871190
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
11881191
.build().unwrap()
11891192
.sign(payer_sign).unwrap()
1190-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1193+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
11911194
.build().unwrap()
11921195
.sign(|_| Err(()))
11931196
{
@@ -1201,7 +1204,7 @@ mod tests {
12011204
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
12021205
.build().unwrap()
12031206
.sign(payer_sign).unwrap()
1204-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1207+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
12051208
.build().unwrap()
12061209
.sign(payer_sign)
12071210
{
@@ -1218,7 +1221,7 @@ mod tests {
12181221
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
12191222
.build().unwrap()
12201223
.sign(payer_sign).unwrap()
1221-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1224+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
12221225
.build().unwrap()
12231226
.sign(recipient_sign).unwrap();
12241227

@@ -1273,7 +1276,7 @@ mod tests {
12731276
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
12741277
.build().unwrap()
12751278
.sign(payer_sign).unwrap()
1276-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1279+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
12771280
.build().unwrap()
12781281
.sign(recipient_sign).unwrap();
12791282

@@ -1303,7 +1306,7 @@ mod tests {
13031306
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
13041307
.build().unwrap()
13051308
.sign(payer_sign).unwrap()
1306-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1309+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
13071310
.relative_expiry(3600)
13081311
.build().unwrap()
13091312
.sign(recipient_sign).unwrap();
@@ -1325,7 +1328,7 @@ mod tests {
13251328
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
13261329
.build().unwrap()
13271330
.sign(payer_sign).unwrap()
1328-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1331+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
13291332
.build().unwrap()
13301333
.sign(recipient_sign).unwrap();
13311334

@@ -1355,7 +1358,7 @@ mod tests {
13551358
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
13561359
.build().unwrap()
13571360
.sign(payer_sign).unwrap()
1358-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1361+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
13591362
.build().unwrap()
13601363
.sign(recipient_sign).unwrap();
13611364

@@ -1383,7 +1386,7 @@ mod tests {
13831386
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
13841387
.build().unwrap()
13851388
.sign(payer_sign).unwrap()
1386-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1389+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
13871390
.allow_mpp()
13881391
.build().unwrap()
13891392
.sign(recipient_sign).unwrap();
@@ -1416,7 +1419,7 @@ mod tests {
14161419
.build().unwrap()
14171420
.sign(payer_sign).unwrap();
14181421
let mut unsigned_invoice = invoice_request
1419-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1422+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
14201423
.fallback_v0_p2wsh(&script.wscript_hash())
14211424
.fallback_v0_p2wpkh(&pubkey.wpubkey_hash().unwrap())
14221425
.fallback_v1_p2tr_tweaked(&tweaked_pubkey)
@@ -1473,7 +1476,7 @@ mod tests {
14731476
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
14741477
.build().unwrap()
14751478
.sign(payer_sign).unwrap()
1476-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1479+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
14771480
.build().unwrap()
14781481
.sign(recipient_sign).unwrap();
14791482

@@ -1515,7 +1518,7 @@ mod tests {
15151518
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
15161519
.build().unwrap()
15171520
.sign(payer_sign).unwrap()
1518-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1521+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
15191522
.build().unwrap()
15201523
.invoice
15211524
.write(&mut buffer).unwrap();
@@ -1534,7 +1537,7 @@ mod tests {
15341537
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
15351538
.build().unwrap()
15361539
.sign(payer_sign).unwrap()
1537-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1540+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
15381541
.build().unwrap()
15391542
.sign(recipient_sign).unwrap();
15401543
let last_signature_byte = invoice.bytes.last_mut().unwrap();
@@ -1559,7 +1562,7 @@ mod tests {
15591562
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
15601563
.build().unwrap()
15611564
.sign(payer_sign).unwrap()
1562-
.respond_with(payment_paths(), payment_hash(), now()).unwrap()
1565+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
15631566
.build().unwrap()
15641567
.sign(recipient_sign).unwrap();
15651568

lightning/src/offers/invoice_request.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,30 @@ impl InvoiceRequest {
322322
self.signature
323323
}
324324

325+
/// Creates an [`Invoice`] for the request with the given required fields and using the
326+
/// [`Duration`] since [`std::time::SystemTime::UNIX_EPOCH`] as the creation time.
327+
///
328+
/// See [`InvoiceRequest::respond_with_no_std`] for further details where the aforementioned
329+
/// creation time is used for the `created_at` parameter.
330+
///
331+
/// [`Invoice`]: crate::offers::invoice::Invoice
332+
/// [`Duration`]: core::time::Duration
333+
#[cfg(feature = "std")]
334+
pub fn respond_with(
335+
&self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash
336+
) -> Result<InvoiceBuilder, SemanticError> {
337+
let created_at = std::time::SystemTime::now()
338+
.duration_since(std::time::SystemTime::UNIX_EPOCH)
339+
.expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
340+
341+
self.respond_with_no_std(payment_paths, payment_hash, created_at)
342+
}
343+
325344
/// Creates an [`Invoice`] for the request with the given required fields.
326345
///
327346
/// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after
328-
/// calling this method in `std` builds. For `no-std` builds, a final [`Duration`] parameter
329-
/// must be given, which is used to set [`Invoice::created_at`] since [`std::time::SystemTime`]
330-
/// is not available.
347+
/// `created_at`, which is used to set [`Invoice::created_at`]. Useful for `no-std` builds where
348+
/// [`std::time::SystemTime`] is not available.
331349
///
332350
/// The caller is expected to remember the preimage of `payment_hash` in order to claim a payment
333351
/// for the invoice.
@@ -339,23 +357,16 @@ impl InvoiceRequest {
339357
///
340358
/// Errors if the request contains unknown required features.
341359
///
342-
/// [`Duration`]: core::time::Duration
343360
/// [`Invoice`]: crate::offers::invoice::Invoice
344361
/// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at
345-
pub fn respond_with(
362+
pub fn respond_with_no_std(
346363
&self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
347-
#[cfg(any(test, not(feature = "std")))]
348364
created_at: core::time::Duration
349365
) -> Result<InvoiceBuilder, SemanticError> {
350366
if self.features().requires_unknown_bits() {
351367
return Err(SemanticError::UnknownRequiredFeatures);
352368
}
353369

354-
#[cfg(all(not(test), feature = "std"))]
355-
let created_at = std::time::SystemTime::now()
356-
.duration_since(std::time::SystemTime::UNIX_EPOCH)
357-
.expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
358-
359370
InvoiceBuilder::for_offer(self, payment_paths, created_at, payment_hash)
360371
}
361372

lightning/src/offers/refund.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,31 @@ impl Refund {
317317
self.contents.payer_note.as_ref().map(|payer_note| PrintableString(payer_note.as_str()))
318318
}
319319

320+
/// Creates an [`Invoice`] for the refund with the given required fields and using the
321+
/// [`Duration`] since [`std::time::SystemTime::UNIX_EPOCH`] as the creation time.
322+
///
323+
/// See [`Refund::respond_with_no_std`] for further details where the aforementioned creation
324+
/// time is used for the `created_at` parameter.
325+
///
326+
/// [`Invoice`]: crate::offers::invoice::Invoice
327+
/// [`Duration`]: core::time::Duration
328+
#[cfg(feature = "std")]
329+
pub fn respond_with(
330+
&self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
331+
signing_pubkey: PublicKey,
332+
) -> Result<InvoiceBuilder, SemanticError> {
333+
let created_at = std::time::SystemTime::now()
334+
.duration_since(std::time::SystemTime::UNIX_EPOCH)
335+
.expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
336+
337+
self.respond_with_no_std(payment_paths, payment_hash, signing_pubkey, created_at)
338+
}
339+
320340
/// Creates an [`Invoice`] for the refund with the given required fields.
321341
///
322342
/// Unless [`InvoiceBuilder::relative_expiry`] is set, the invoice will expire two hours after
323-
/// calling this method in `std` builds. For `no-std` builds, a final [`Duration`] parameter
324-
/// must be given, which is used to set [`Invoice::created_at`] since [`std::time::SystemTime`]
325-
/// is not available.
343+
/// `created_at`, which is used to set [`Invoice::created_at`]. Useful for `no-std` builds where
344+
/// [`std::time::SystemTime`] is not available.
326345
///
327346
/// The caller is expected to remember the preimage of `payment_hash` in order to
328347
/// claim a payment for the invoice.
@@ -339,21 +358,14 @@ impl Refund {
339358
///
340359
/// [`Invoice`]: crate::offers::invoice::Invoice
341360
/// [`Invoice::created_at`]: crate::offers::invoice::Invoice::created_at
342-
pub fn respond_with(
361+
pub fn respond_with_no_std(
343362
&self, payment_paths: Vec<(BlindedPath, BlindedPayInfo)>, payment_hash: PaymentHash,
344-
signing_pubkey: PublicKey,
345-
#[cfg(any(test, not(feature = "std")))]
346-
created_at: Duration
363+
signing_pubkey: PublicKey, created_at: Duration
347364
) -> Result<InvoiceBuilder, SemanticError> {
348365
if self.features().requires_unknown_bits() {
349366
return Err(SemanticError::UnknownRequiredFeatures);
350367
}
351368

352-
#[cfg(all(not(test), feature = "std"))]
353-
let created_at = std::time::SystemTime::now()
354-
.duration_since(std::time::SystemTime::UNIX_EPOCH)
355-
.expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
356-
357369
InvoiceBuilder::for_refund(self, payment_paths, created_at, payment_hash, signing_pubkey)
358370
}
359371

0 commit comments

Comments
 (0)