Skip to content

Commit bd1aad3

Browse files
committed
Refactor InvoiceRequestContents fields into a sub-struct
InvoiceRequestBuilder has a field containing InvoiceRequestContents. When deriving the payer_id from the remaining fields, a struct is needed without payer_id as it not optional. Refactor InvoiceRequestContents to have an inner struct without the payer_id such that InvoiceRequestBuilder can use it instead.
1 parent c960112 commit bd1aad3

File tree

2 files changed

+57
-31
lines changed

2 files changed

+57
-31
lines changed

lightning/src/offers/invoice.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl<'a> InvoiceBuilder<'a> {
146146
) -> Result<Self, SemanticError> {
147147
let amount_msats = match invoice_request.amount_msats() {
148148
Some(amount_msats) => amount_msats,
149-
None => match invoice_request.contents.offer.amount() {
149+
None => match invoice_request.contents.inner.offer.amount() {
150150
Some(Amount::Bitcoin { amount_msats }) => {
151151
amount_msats.checked_mul(invoice_request.quantity().unwrap_or(1))
152152
.ok_or(SemanticError::InvalidAmount)?
@@ -161,7 +161,7 @@ impl<'a> InvoiceBuilder<'a> {
161161
fields: InvoiceFields {
162162
payment_paths, created_at, relative_expiry: None, payment_hash, amount_msats,
163163
fallbacks: None, features: Bolt12InvoiceFeatures::empty(),
164-
signing_pubkey: invoice_request.contents.offer.signing_pubkey(),
164+
signing_pubkey: invoice_request.contents.inner.offer.signing_pubkey(),
165165
},
166166
};
167167

@@ -493,7 +493,8 @@ impl InvoiceContents {
493493
#[cfg(feature = "std")]
494494
fn is_offer_or_refund_expired(&self) -> bool {
495495
match self {
496-
InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.offer.is_expired(),
496+
InvoiceContents::ForOffer { invoice_request, .. } =>
497+
invoice_request.inner.offer.is_expired(),
497498
InvoiceContents::ForRefund { refund, .. } => refund.is_expired(),
498499
}
499500
}

lightning/src/offers/invoice_request.rs

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,12 @@ impl<'a> InvoiceRequestBuilder<'a> {
9090
Self {
9191
offer,
9292
invoice_request: InvoiceRequestContents {
93-
payer: PayerContents(metadata), offer: offer.contents.clone(), chain: None,
94-
amount_msats: None, features: InvoiceRequestFeatures::empty(), quantity: None,
95-
payer_id, payer_note: None,
93+
inner: InvoiceRequestContentsWithoutPayerId {
94+
payer: PayerContents(metadata), offer: offer.contents.clone(), chain: None,
95+
amount_msats: None, features: InvoiceRequestFeatures::empty(), quantity: None,
96+
payer_note: None,
97+
},
98+
payer_id,
9699
},
97100
}
98101
}
@@ -108,7 +111,7 @@ impl<'a> InvoiceRequestBuilder<'a> {
108111
return Err(SemanticError::UnsupportedChain);
109112
}
110113

111-
self.invoice_request.chain = Some(chain);
114+
self.invoice_request.inner.chain = Some(chain);
112115
Ok(self)
113116
}
114117

@@ -119,10 +122,10 @@ impl<'a> InvoiceRequestBuilder<'a> {
119122
///
120123
/// [`quantity`]: Self::quantity
121124
pub fn amount_msats(mut self, amount_msats: u64) -> Result<Self, SemanticError> {
122-
self.invoice_request.offer.check_amount_msats_for_quantity(
123-
Some(amount_msats), self.invoice_request.quantity
125+
self.invoice_request.inner.offer.check_amount_msats_for_quantity(
126+
Some(amount_msats), self.invoice_request.inner.quantity
124127
)?;
125-
self.invoice_request.amount_msats = Some(amount_msats);
128+
self.invoice_request.inner.amount_msats = Some(amount_msats);
126129
Ok(self)
127130
}
128131

@@ -131,16 +134,16 @@ impl<'a> InvoiceRequestBuilder<'a> {
131134
///
132135
/// Successive calls to this method will override the previous setting.
133136
pub fn quantity(mut self, quantity: u64) -> Result<Self, SemanticError> {
134-
self.invoice_request.offer.check_quantity(Some(quantity))?;
135-
self.invoice_request.quantity = Some(quantity);
137+
self.invoice_request.inner.offer.check_quantity(Some(quantity))?;
138+
self.invoice_request.inner.quantity = Some(quantity);
136139
Ok(self)
137140
}
138141

139142
/// Sets the [`InvoiceRequest::payer_note`].
140143
///
141144
/// Successive calls to this method will override the previous setting.
142145
pub fn payer_note(mut self, payer_note: String) -> Self {
143-
self.invoice_request.payer_note = Some(payer_note);
146+
self.invoice_request.inner.payer_note = Some(payer_note);
144147
self
145148
}
146149

@@ -159,16 +162,16 @@ impl<'a> InvoiceRequestBuilder<'a> {
159162
}
160163

161164
if chain == self.offer.implied_chain() {
162-
self.invoice_request.chain = None;
165+
self.invoice_request.inner.chain = None;
163166
}
164167

165-
if self.offer.amount().is_none() && self.invoice_request.amount_msats.is_none() {
168+
if self.offer.amount().is_none() && self.invoice_request.inner.amount_msats.is_none() {
166169
return Err(SemanticError::MissingAmount);
167170
}
168171

169-
self.invoice_request.offer.check_quantity(self.invoice_request.quantity)?;
170-
self.invoice_request.offer.check_amount_msats_for_quantity(
171-
self.invoice_request.amount_msats, self.invoice_request.quantity
172+
self.invoice_request.inner.offer.check_quantity(self.invoice_request.inner.quantity)?;
173+
self.invoice_request.inner.offer.check_amount_msats_for_quantity(
174+
self.invoice_request.inner.amount_msats, self.invoice_request.inner.quantity
172175
)?;
173176

174177
let InvoiceRequestBuilder { offer, invoice_request } = self;
@@ -180,22 +183,22 @@ impl<'a> InvoiceRequestBuilder<'a> {
180183
impl<'a> InvoiceRequestBuilder<'a> {
181184
fn chain_unchecked(mut self, network: Network) -> Self {
182185
let chain = ChainHash::using_genesis_block(network);
183-
self.invoice_request.chain = Some(chain);
186+
self.invoice_request.inner.chain = Some(chain);
184187
self
185188
}
186189

187190
fn amount_msats_unchecked(mut self, amount_msats: u64) -> Self {
188-
self.invoice_request.amount_msats = Some(amount_msats);
191+
self.invoice_request.inner.amount_msats = Some(amount_msats);
189192
self
190193
}
191194

192195
fn features_unchecked(mut self, features: InvoiceRequestFeatures) -> Self {
193-
self.invoice_request.features = features;
196+
self.invoice_request.inner.features = features;
194197
self
195198
}
196199

197200
fn quantity_unchecked(mut self, quantity: u64) -> Self {
198-
self.invoice_request.quantity = Some(quantity);
201+
self.invoice_request.inner.quantity = Some(quantity);
199202
self
200203
}
201204

@@ -265,13 +268,19 @@ pub struct InvoiceRequest {
265268
#[derive(Clone, Debug)]
266269
#[cfg_attr(test, derive(PartialEq))]
267270
pub(super) struct InvoiceRequestContents {
271+
pub(super) inner: InvoiceRequestContentsWithoutPayerId,
272+
payer_id: PublicKey,
273+
}
274+
275+
#[derive(Clone, Debug)]
276+
#[cfg_attr(test, derive(PartialEq))]
277+
pub(super) struct InvoiceRequestContentsWithoutPayerId {
268278
payer: PayerContents,
269279
pub(super) offer: OfferContents,
270280
chain: Option<ChainHash>,
271281
amount_msats: Option<u64>,
272282
features: InvoiceRequestFeatures,
273283
quantity: Option<u64>,
274-
payer_id: PublicKey,
275284
payer_note: Option<String>,
276285
}
277286

@@ -281,7 +290,7 @@ impl InvoiceRequest {
281290
///
282291
/// [`payer_id`]: Self::payer_id
283292
pub fn metadata(&self) -> &[u8] {
284-
&self.contents.payer.0[..]
293+
&self.contents.inner.payer.0[..]
285294
}
286295

287296
/// A chain from [`Offer::chains`] that the offer is valid for.
@@ -294,17 +303,17 @@ impl InvoiceRequest {
294303
///
295304
/// [`chain`]: Self::chain
296305
pub fn amount_msats(&self) -> Option<u64> {
297-
self.contents.amount_msats
306+
self.contents.inner.amount_msats
298307
}
299308

300309
/// Features pertaining to requesting an invoice.
301310
pub fn features(&self) -> &InvoiceRequestFeatures {
302-
&self.contents.features
311+
&self.contents.inner.features
303312
}
304313

305314
/// The quantity of the offer's item conforming to [`Offer::is_valid_quantity`].
306315
pub fn quantity(&self) -> Option<u64> {
307-
self.contents.quantity
316+
self.contents.inner.quantity
308317
}
309318

310319
/// A possibly transient pubkey used to sign the invoice request.
@@ -315,7 +324,8 @@ impl InvoiceRequest {
315324
/// A payer-provided note which will be seen by the recipient and reflected back in the invoice
316325
/// response.
317326
pub fn payer_note(&self) -> Option<PrintableString> {
318-
self.contents.payer_note.as_ref().map(|payer_note| PrintableString(payer_note.as_str()))
327+
self.contents.inner.payer_note.as_ref()
328+
.map(|payer_note| PrintableString(payer_note.as_str()))
319329
}
320330

321331
/// Signature of the invoice request using [`payer_id`].
@@ -377,7 +387,7 @@ impl InvoiceRequest {
377387
pub fn verify<T: secp256k1::Signing>(
378388
&self, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
379389
) -> bool {
380-
self.contents.offer.verify(TlvStream::new(&self.bytes), key, secp_ctx)
390+
self.contents.inner.offer.verify(TlvStream::new(&self.bytes), key, secp_ctx)
381391
}
382392

383393
#[cfg(test)]
@@ -392,6 +402,18 @@ impl InvoiceRequest {
392402
}
393403

394404
impl InvoiceRequestContents {
405+
pub(super) fn chain(&self) -> ChainHash {
406+
self.inner.chain()
407+
}
408+
409+
pub(super) fn as_tlv_stream(&self) -> PartialInvoiceRequestTlvStreamRef {
410+
let (payer, offer, mut invoice_request) = self.inner.as_tlv_stream();
411+
invoice_request.payer_id = Some(&self.payer_id);
412+
(payer, offer, invoice_request)
413+
}
414+
}
415+
416+
impl InvoiceRequestContentsWithoutPayerId {
395417
pub(super) fn chain(&self) -> ChainHash {
396418
self.chain.unwrap_or_else(|| self.offer.implied_chain())
397419
}
@@ -413,7 +435,7 @@ impl InvoiceRequestContents {
413435
amount: self.amount_msats,
414436
features,
415437
quantity: self.quantity,
416-
payer_id: Some(&self.payer_id),
438+
payer_id: None,
417439
payer_note: self.payer_note.as_ref(),
418440
};
419441

@@ -531,7 +553,10 @@ impl TryFrom<PartialInvoiceRequestTlvStream> for InvoiceRequestContents {
531553
};
532554

533555
Ok(InvoiceRequestContents {
534-
payer, offer, chain, amount_msats: amount, features, quantity, payer_id, payer_note,
556+
inner: InvoiceRequestContentsWithoutPayerId {
557+
payer, offer, chain, amount_msats: amount, features, quantity, payer_note,
558+
},
559+
payer_id,
535560
})
536561
}
537562
}

0 commit comments

Comments
 (0)