BOLT 12 invoice: extract helper for invoice signing pubkey checks
authorValentine Wallace <vwallace@protonmail.com>
Tue, 4 Jun 2024 22:21:50 +0000 (18:21 -0400)
committerValentine Wallace <vwallace@protonmail.com>
Tue, 11 Jun 2024 18:55:06 +0000 (14:55 -0400)
Will be useful for static invoices.

lightning/src/offers/invoice.rs

index 1890337585862e67cef449e0a2471267c150c80d..ac2b4aa76822692dbf623da4c5ae33f5368c571b 100644 (file)
@@ -1337,37 +1337,18 @@ impl TryFrom<PartialInvoiceTlvStream> for InvoiceContents {
                        features, signing_pubkey,
                };
 
-               match (offer_tlv_stream.node_id, &offer_tlv_stream.paths) {
-                       (Some(expected_signing_pubkey), _) => {
-                               if fields.signing_pubkey != expected_signing_pubkey {
-                                       return Err(Bolt12SemanticError::InvalidSigningPubkey);
-                               }
-
-                               let invoice_request = InvoiceRequestContents::try_from(
-                                       (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
-                               )?;
-                               Ok(InvoiceContents::ForOffer { invoice_request, fields })
-                       },
-                       (None, Some(paths)) => {
-                               if !paths
-                                       .iter()
-                                       .filter_map(|path| path.blinded_hops.last())
-                                       .any(|last_hop| fields.signing_pubkey == last_hop.blinded_node_id)
-                               {
-                                       return Err(Bolt12SemanticError::InvalidSigningPubkey);
-                               }
-
-                               let invoice_request = InvoiceRequestContents::try_from(
-                                       (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
-                               )?;
-                               Ok(InvoiceContents::ForOffer { invoice_request, fields })
-                       },
-                       (None, None) => {
-                               let refund = RefundContents::try_from(
-                                       (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
-                               )?;
-                               Ok(InvoiceContents::ForRefund { refund, fields })
-                       },
+               check_invoice_signing_pubkey(&fields.signing_pubkey, &offer_tlv_stream)?;
+
+               if offer_tlv_stream.node_id.is_none() && offer_tlv_stream.paths.is_none() {
+                       let refund = RefundContents::try_from(
+                               (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
+                       )?;
+                       Ok(InvoiceContents::ForRefund { refund, fields })
+               } else {
+                       let invoice_request = InvoiceRequestContents::try_from(
+                               (payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream)
+                       )?;
+                       Ok(InvoiceContents::ForOffer { invoice_request, fields })
                }
        }
 }
@@ -1388,6 +1369,29 @@ pub(super) fn construct_payment_paths(
        }
 }
 
+pub(super) fn check_invoice_signing_pubkey(
+       invoice_signing_pubkey: &PublicKey, offer_tlv_stream: &OfferTlvStream
+) -> Result<(), Bolt12SemanticError> {
+       match (&offer_tlv_stream.node_id, &offer_tlv_stream.paths) {
+               (Some(expected_signing_pubkey), _) => {
+                       if invoice_signing_pubkey != expected_signing_pubkey {
+                               return Err(Bolt12SemanticError::InvalidSigningPubkey);
+                       }
+               },
+               (None, Some(paths)) => {
+                       if !paths
+                               .iter()
+                               .filter_map(|path| path.blinded_hops.last())
+                               .any(|last_hop| invoice_signing_pubkey == &last_hop.blinded_node_id)
+                       {
+                               return Err(Bolt12SemanticError::InvalidSigningPubkey);
+                       }
+               },
+               _ => {},
+       }
+       Ok(())
+}
+
 #[cfg(test)]
 mod tests {
        use super::{Bolt12Invoice, DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, InvoiceTlvStreamRef, SIGNATURE_TAG, UnsignedBolt12Invoice};