Skip to content

Commit 66060ca

Browse files
committed
Macro-ize Offer accessors for reuse
InvoiceRequest wraps OfferContents, which shouldn't be exposed as it is an implementation detail. Define a macro for Offer accessor methods so that InvoiceRequest and UnsignedInvoiceRequest can also define them.
1 parent 68d4717 commit 66060ca

File tree

2 files changed

+52
-46
lines changed

2 files changed

+52
-46
lines changed

lightning/src/offers/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
//!
1313
//! Offers are a flexible protocol for Lightning payments.
1414
15+
#[macro_use]
16+
pub mod offer;
17+
1518
pub mod invoice;
1619
pub mod invoice_error;
1720
pub mod invoice_request;
1821
pub mod merkle;
19-
pub mod offer;
2022
pub mod parse;
2123
mod payer;
2224
pub mod refund;

lightning/src/offers/offer.rs

+49-45
Original file line numberDiff line numberDiff line change
@@ -358,77 +358,86 @@ pub(super) struct OfferContents {
358358
signing_pubkey: PublicKey,
359359
}
360360

361-
impl Offer {
361+
macro_rules! offer_accessors { ($self: ident, $contents: expr) => {
362362
// TODO: Return a slice once ChainHash has constants.
363363
// - https://github.com/rust-bitcoin/rust-bitcoin/pull/1283
364364
// - https://github.com/rust-bitcoin/rust-bitcoin/pull/1286
365365
/// The chains that may be used when paying a requested invoice (e.g., bitcoin mainnet).
366366
/// Payments must be denominated in units of the minimal lightning-payable unit (e.g., msats)
367367
/// for the selected chain.
368-
pub fn chains(&self) -> Vec<ChainHash> {
369-
self.contents.chains()
370-
}
371-
372-
pub(super) fn implied_chain(&self) -> ChainHash {
373-
self.contents.implied_chain()
374-
}
375-
376-
/// Returns whether the given chain is supported by the offer.
377-
pub fn supports_chain(&self, chain: ChainHash) -> bool {
378-
self.contents.supports_chain(chain)
368+
pub fn chains(&$self) -> Vec<$crate::bitcoin::blockdata::constants::ChainHash> {
369+
$contents.chains()
379370
}
380371

381372
// TODO: Link to corresponding method in `InvoiceRequest`.
382373
/// Opaque bytes set by the originator. Useful for authentication and validating fields since it
383374
/// is reflected in `invoice_request` messages along with all the other fields from the `offer`.
384-
pub fn metadata(&self) -> Option<&Vec<u8>> {
385-
self.contents.metadata()
375+
pub fn metadata(&$self) -> Option<&Vec<u8>> {
376+
$contents.metadata()
386377
}
387378

388379
/// The minimum amount required for a successful payment of a single item.
389-
pub fn amount(&self) -> Option<&Amount> {
390-
self.contents.amount()
380+
pub fn amount(&$self) -> Option<&$crate::offers::offer::Amount> {
381+
$contents.amount()
391382
}
392383

393384
/// A complete description of the purpose of the payment. Intended to be displayed to the user
394385
/// but with the caveat that it has not been verified in any way.
395-
pub fn description(&self) -> PrintableString {
396-
self.contents.description()
386+
pub fn description(&$self) -> $crate::util::string::PrintableString {
387+
$contents.description()
397388
}
398389

399390
/// Features pertaining to the offer.
400-
pub fn features(&self) -> &OfferFeatures {
401-
&self.contents.features()
391+
pub fn offer_features(&$self) -> &$crate::ln::features::OfferFeatures {
392+
&$contents.features()
402393
}
403394

404395
/// Duration since the Unix epoch when an invoice should no longer be requested.
405396
///
406397
/// If `None`, the offer does not expire.
407-
pub fn absolute_expiry(&self) -> Option<Duration> {
408-
self.contents.absolute_expiry()
409-
}
410-
411-
/// Whether the offer has expired.
412-
#[cfg(feature = "std")]
413-
pub fn is_expired(&self) -> bool {
414-
self.contents.is_expired()
398+
pub fn absolute_expiry(&$self) -> Option<core::time::Duration> {
399+
$contents.absolute_expiry()
415400
}
416401

417402
/// The issuer of the offer, possibly beginning with `user@domain` or `domain`. Intended to be
418403
/// displayed to the user but with the caveat that it has not been verified in any way.
419-
pub fn issuer(&self) -> Option<PrintableString> {
420-
self.contents.issuer()
404+
pub fn issuer(&$self) -> Option<$crate::util::string::PrintableString> {
405+
$contents.issuer()
421406
}
422407

423408
/// Paths to the recipient originating from publicly reachable nodes. Blinded paths provide
424409
/// recipient privacy by obfuscating its node id.
425-
pub fn paths(&self) -> &[BlindedPath] {
426-
self.contents.paths()
410+
pub fn paths(&$self) -> &[$crate::blinded_path::BlindedPath] {
411+
$contents.paths()
427412
}
428413

429414
/// The quantity of items supported.
430-
pub fn supported_quantity(&self) -> Quantity {
431-
self.contents.supported_quantity()
415+
pub fn supported_quantity(&$self) -> $crate::offers::offer::Quantity {
416+
$contents.supported_quantity()
417+
}
418+
419+
/// The public key used by the recipient to sign invoices.
420+
pub fn signing_pubkey(&$self) -> $crate::bitcoin::secp256k1::PublicKey {
421+
$contents.signing_pubkey()
422+
}
423+
} }
424+
425+
impl Offer {
426+
offer_accessors!(self, self.contents);
427+
428+
pub(super) fn implied_chain(&self) -> ChainHash {
429+
self.contents.implied_chain()
430+
}
431+
432+
/// Returns whether the given chain is supported by the offer.
433+
pub fn supports_chain(&self, chain: ChainHash) -> bool {
434+
self.contents.supports_chain(chain)
435+
}
436+
437+
/// Whether the offer has expired.
438+
#[cfg(feature = "std")]
439+
pub fn is_expired(&self) -> bool {
440+
self.contents.is_expired()
432441
}
433442

434443
/// Returns whether the given quantity is valid for the offer.
@@ -443,11 +452,6 @@ impl Offer {
443452
self.contents.expects_quantity()
444453
}
445454

446-
/// The public key used by the recipient to sign invoices.
447-
pub fn signing_pubkey(&self) -> PublicKey {
448-
self.contents.signing_pubkey()
449-
}
450-
451455
/// Similar to [`Offer::request_invoice`] except it:
452456
/// - derives the [`InvoiceRequest::payer_id`] such that a different key can be used for each
453457
/// request, and
@@ -469,7 +473,7 @@ impl Offer {
469473
where
470474
ES::Target: EntropySource,
471475
{
472-
if self.features().requires_unknown_bits() {
476+
if self.offer_features().requires_unknown_bits() {
473477
return Err(Bolt12SemanticError::UnknownRequiredFeatures);
474478
}
475479

@@ -490,7 +494,7 @@ impl Offer {
490494
where
491495
ES::Target: EntropySource,
492496
{
493-
if self.features().requires_unknown_bits() {
497+
if self.offer_features().requires_unknown_bits() {
494498
return Err(Bolt12SemanticError::UnknownRequiredFeatures);
495499
}
496500

@@ -515,7 +519,7 @@ impl Offer {
515519
pub fn request_invoice(
516520
&self, metadata: Vec<u8>, payer_id: PublicKey
517521
) -> Result<InvoiceRequestBuilder<ExplicitPayerId, secp256k1::SignOnly>, Bolt12SemanticError> {
518-
if self.features().requires_unknown_bits() {
522+
if self.offer_features().requires_unknown_bits() {
519523
return Err(Bolt12SemanticError::UnknownRequiredFeatures);
520524
}
521525

@@ -890,7 +894,7 @@ mod tests {
890894
assert_eq!(offer.metadata(), None);
891895
assert_eq!(offer.amount(), None);
892896
assert_eq!(offer.description(), PrintableString("foo"));
893-
assert_eq!(offer.features(), &OfferFeatures::empty());
897+
assert_eq!(offer.offer_features(), &OfferFeatures::empty());
894898
assert_eq!(offer.absolute_expiry(), None);
895899
#[cfg(feature = "std")]
896900
assert!(!offer.is_expired());
@@ -1131,15 +1135,15 @@ mod tests {
11311135
.features_unchecked(OfferFeatures::unknown())
11321136
.build()
11331137
.unwrap();
1134-
assert_eq!(offer.features(), &OfferFeatures::unknown());
1138+
assert_eq!(offer.offer_features(), &OfferFeatures::unknown());
11351139
assert_eq!(offer.as_tlv_stream().features, Some(&OfferFeatures::unknown()));
11361140

11371141
let offer = OfferBuilder::new("foo".into(), pubkey(42))
11381142
.features_unchecked(OfferFeatures::unknown())
11391143
.features_unchecked(OfferFeatures::empty())
11401144
.build()
11411145
.unwrap();
1142-
assert_eq!(offer.features(), &OfferFeatures::empty());
1146+
assert_eq!(offer.offer_features(), &OfferFeatures::empty());
11431147
assert_eq!(offer.as_tlv_stream().features, None);
11441148
}
11451149

0 commit comments

Comments
 (0)