Skip to content

Commit 20eeb2a

Browse files
committed
Update InvoiceBuilder's amount_msats
1. The amount_msats function first checks if any amount is given with the invoice requests, and defaults to using offer's amount if it's absent. 2. This can be a problem if the amount in offer was represent as a Currency. 3. Update amount_msats to take in an optional custom amount which can be used in case amount if absent in Invoice Request. 4. This update will be utilised in the following commits to set custom amount_msats when responding to Invoice Request Asychronously.
1 parent 048584d commit 20eeb2a

File tree

4 files changed

+34
-23
lines changed

4 files changed

+34
-23
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11082,7 +11082,7 @@ where
1108211082
};
1108311083

1108411084
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats(
11085-
&invoice_request.inner
11085+
&invoice_request.inner, None
1108611086
) {
1108711087
Ok(amount_msats) => amount_msats,
1108811088
Err(error) => return Some((OffersMessage::InvoiceError(error.into()), responder.respond())),
@@ -11121,7 +11121,7 @@ where
1112111121
let response = if invoice_request.keys.is_some() {
1112211122
#[cfg(feature = "std")]
1112311123
let builder = invoice_request.respond_using_derived_keys(
11124-
payment_paths, payment_hash
11124+
payment_paths, payment_hash, None
1112511125
);
1112611126
#[cfg(not(feature = "std"))]
1112711127
let builder = invoice_request.respond_using_derived_keys_no_std(

lightning/src/ln/offers_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2222,7 +2222,7 @@ fn fails_paying_invoice_with_unknown_required_features() {
22222222
let created_at = alice.node.duration_since_epoch();
22232223
let invoice = invoice_request
22242224
.verify_using_recipient_data(nonce, &expanded_key, &secp_ctx).unwrap()
2225-
.respond_using_derived_keys_no_std(payment_paths, payment_hash, created_at).unwrap()
2225+
.respond_using_derived_keys_no_std(payment_paths, payment_hash, created_at, None).unwrap()
22262226
.features_unchecked(Bolt12InvoiceFeatures::unknown())
22272227
.build_and_sign(&secp_ctx).unwrap();
22282228

lightning/src/offers/invoice.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ macro_rules! invoice_explicit_signing_pubkey_builder_methods { ($self: ident, $s
216216
invoice_request: &'a InvoiceRequest, payment_paths: Vec<BlindedPaymentPath>,
217217
created_at: Duration, payment_hash: PaymentHash, signing_pubkey: PublicKey
218218
) -> Result<Self, Bolt12SemanticError> {
219-
let amount_msats = Self::amount_msats(invoice_request)?;
219+
let amount_msats = Self::amount_msats(invoice_request, None)?;
220220
let contents = InvoiceContents::ForOffer {
221221
invoice_request: invoice_request.contents.clone(),
222222
fields: Self::fields(
@@ -272,9 +272,9 @@ macro_rules! invoice_derived_signing_pubkey_builder_methods { ($self: ident, $se
272272
#[cfg_attr(c_bindings, allow(dead_code))]
273273
pub(super) fn for_offer_using_keys(
274274
invoice_request: &'a InvoiceRequest, payment_paths: Vec<BlindedPaymentPath>,
275-
created_at: Duration, payment_hash: PaymentHash, keys: Keypair
275+
created_at: Duration, payment_hash: PaymentHash, keys: Keypair, custom_amount_msats: Option<u64>
276276
) -> Result<Self, Bolt12SemanticError> {
277-
let amount_msats = Self::amount_msats(invoice_request)?;
277+
let amount_msats = Self::amount_msats(invoice_request, custom_amount_msats)?;
278278
let signing_pubkey = keys.public_key();
279279
let contents = InvoiceContents::ForOffer {
280280
invoice_request: invoice_request.contents.clone(),
@@ -340,18 +340,29 @@ macro_rules! invoice_builder_methods { (
340340
$self: ident, $self_type: ty, $return_type: ty, $return_value: expr, $type_param: ty $(, $self_mut: tt)?
341341
) => {
342342
pub(crate) fn amount_msats(
343-
invoice_request: &InvoiceRequest
343+
invoice_request: &InvoiceRequest, custom_amount_msats: Option<u64>
344344
) -> Result<u64, Bolt12SemanticError> {
345-
match invoice_request.amount_msats() {
346-
Some(amount_msats) => Ok(amount_msats),
347-
None => match invoice_request.contents.inner.offer.amount() {
348-
Some(Amount::Bitcoin { amount_msats }) => {
349-
amount_msats.checked_mul(invoice_request.quantity().unwrap_or(1))
350-
.ok_or(Bolt12SemanticError::InvalidAmount)
351-
},
352-
Some(Amount::Currency { .. }) => Err(Bolt12SemanticError::UnsupportedCurrency),
353-
None => Err(Bolt12SemanticError::MissingAmount),
354-
},
345+
if invoice_request.amount_msats().is_some() && custom_amount_msats.is_some() {
346+
return Err(Bolt12SemanticError::UnexpectedAmount);
347+
}
348+
349+
if let Some(amount_msats) = invoice_request.amount_msats() {
350+
return Ok(amount_msats);
351+
}
352+
353+
if let Some(custom_amount_msats) = custom_amount_msats {
354+
return Ok(custom_amount_msats);
355+
}
356+
357+
match invoice_request.contents.inner.offer.amount() {
358+
Some(Amount::Bitcoin { amount_msats }) => {
359+
let quantity = invoice_request.quantity().unwrap_or(1);
360+
amount_msats
361+
.checked_mul(quantity)
362+
.ok_or(Bolt12SemanticError::InvalidAmount)
363+
}
364+
Some(Amount::Currency { .. }) => Err(Bolt12SemanticError::UnsupportedCurrency),
365+
None => Err(Bolt12SemanticError::MissingAmount),
355366
}
356367
}
357368

@@ -1778,7 +1789,7 @@ mod tests {
17781789

17791790
if let Err(e) = invoice_request.clone()
17801791
.verify_using_recipient_data(nonce, &expanded_key, &secp_ctx).unwrap()
1781-
.respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now()).unwrap()
1792+
.respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now(), None).unwrap()
17821793
.build_and_sign(&secp_ctx)
17831794
{
17841795
panic!("error building invoice: {:?}", e);
@@ -1799,7 +1810,7 @@ mod tests {
17991810

18001811
match invoice_request
18011812
.verify_using_metadata(&expanded_key, &secp_ctx).unwrap()
1802-
.respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now())
1813+
.respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now(), None)
18031814
{
18041815
Ok(_) => panic!("expected error"),
18051816
Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),

lightning/src/offers/invoice_request.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -884,13 +884,13 @@ macro_rules! invoice_request_respond_with_derived_signing_pubkey_methods { (
884884
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
885885
#[cfg(feature = "std")]
886886
pub fn respond_using_derived_keys(
887-
&$self, payment_paths: Vec<BlindedPaymentPath>, payment_hash: PaymentHash
887+
&$self, payment_paths: Vec<BlindedPaymentPath>, payment_hash: PaymentHash, custom_amount_msats: Option<u64>
888888
) -> Result<$builder, Bolt12SemanticError> {
889889
let created_at = std::time::SystemTime::now()
890890
.duration_since(std::time::SystemTime::UNIX_EPOCH)
891891
.expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH");
892892

893-
$self.respond_using_derived_keys_no_std(payment_paths, payment_hash, created_at)
893+
$self.respond_using_derived_keys_no_std(payment_paths, payment_hash, created_at, custom_amount_msats)
894894
}
895895

896896
/// Creates an [`InvoiceBuilder`] for the request using the given required fields and that uses
@@ -902,7 +902,7 @@ macro_rules! invoice_request_respond_with_derived_signing_pubkey_methods { (
902902
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
903903
pub fn respond_using_derived_keys_no_std(
904904
&$self, payment_paths: Vec<BlindedPaymentPath>, payment_hash: PaymentHash,
905-
created_at: core::time::Duration
905+
created_at: core::time::Duration, custom_amount_msats: Option<u64>
906906
) -> Result<$builder, Bolt12SemanticError> {
907907
if $self.inner.invoice_request_features().requires_unknown_bits() {
908908
return Err(Bolt12SemanticError::UnknownRequiredFeatures);
@@ -919,7 +919,7 @@ macro_rules! invoice_request_respond_with_derived_signing_pubkey_methods { (
919919
}
920920

921921
<$builder>::for_offer_using_keys(
922-
&$self.inner, payment_paths, created_at, payment_hash, keys
922+
&$self.inner, payment_paths, created_at, payment_hash, keys, custom_amount_msats
923923
)
924924
}
925925
} }

0 commit comments

Comments
 (0)