Migrate to `KVStore`/`FilesystemStore`
[rust-lightning] / lightning / src / offers / invoice.rs
index 745b389fa4673d34141aa8d42a017594e64c8cdc..06215e2d48615ce9784c6e95f534a8eeb7739be9 100644 (file)
@@ -110,6 +110,7 @@ use core::time::Duration;
 use crate::io;
 use crate::blinded_path::BlindedPath;
 use crate::ln::PaymentHash;
+use crate::ln::channelmanager::PaymentId;
 use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
 use crate::ln::inbound_payment::ExpandedKey;
 use crate::ln::msgs::DecodeError;
@@ -397,6 +398,11 @@ impl UnsignedBolt12Invoice {
                Self { bytes, contents, tagged_hash }
        }
 
+       /// Returns the [`TaggedHash`] of the invoice to sign.
+       pub fn tagged_hash(&self) -> &TaggedHash {
+               &self.tagged_hash
+       }
+
        /// Signs the [`TaggedHash`] of the invoice using the given function.
        ///
        /// Note: The hash computation may have included unknown, odd TLV records.
@@ -690,10 +696,11 @@ impl Bolt12Invoice {
                merkle::message_digest(SIGNATURE_TAG, &self.bytes).as_ref().clone()
        }
 
-       /// Verifies that the invoice was for a request or refund created using the given key.
+       /// Verifies that the invoice was for a request or refund created using the given key. Returns
+       /// the associated [`PaymentId`] to use when sending the payment.
        pub fn verify<T: secp256k1::Signing>(
                &self, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
-       ) -> bool {
+       ) -> Result<PaymentId, ()> {
                self.contents.verify(TlvStream::new(&self.bytes), key, secp_ctx)
        }
 
@@ -942,7 +949,7 @@ impl InvoiceContents {
 
        fn verify<T: secp256k1::Signing>(
                &self, tlv_stream: TlvStream<'_>, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
-       ) -> bool {
+       ) -> Result<PaymentId, ()> {
                let offer_records = tlv_stream.clone().range(OFFER_TYPES);
                let invreq_records = tlv_stream.range(INVOICE_REQUEST_TYPES).filter(|record| {
                        match record.r#type {
@@ -962,10 +969,7 @@ impl InvoiceContents {
                        },
                };
 
-               match signer::verify_metadata(metadata, key, iv_bytes, payer_id, tlv_stream, secp_ctx) {
-                       Ok(_) => true,
-                       Err(()) => false,
-               }
+               signer::verify_payer_metadata(metadata, key, iv_bytes, payer_id, tlv_stream, secp_ctx)
        }
 
        fn derives_keys(&self) -> bool {
@@ -1637,36 +1641,31 @@ mod tests {
                        .build().unwrap()
                        .sign(payer_sign).unwrap();
 
-               if let Err(e) = invoice_request
-                       .verify_and_respond_using_derived_keys_no_std(
-                               payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx
-                       )
-                       .unwrap()
+               if let Err(e) = invoice_request.clone()
+                       .verify(&expanded_key, &secp_ctx).unwrap()
+                       .respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now()).unwrap()
                        .build_and_sign(&secp_ctx)
                {
                        panic!("error building invoice: {:?}", e);
                }
 
                let expanded_key = ExpandedKey::new(&KeyMaterial([41; 32]));
-               match invoice_request.verify_and_respond_using_derived_keys_no_std(
-                       payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx
-               ) {
-                       Ok(_) => panic!("expected error"),
-                       Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),
-               }
+               assert!(invoice_request.verify(&expanded_key, &secp_ctx).is_err());
 
                let desc = "foo".to_string();
                let offer = OfferBuilder
                        ::deriving_signing_pubkey(desc, node_id, &expanded_key, &entropy, &secp_ctx)
                        .amount_msats(1000)
+                       // Omit the path so that node_id is used for the signing pubkey instead of deriving
                        .build().unwrap();
                let invoice_request = offer.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
                        .build().unwrap()
                        .sign(payer_sign).unwrap();
 
-               match invoice_request.verify_and_respond_using_derived_keys_no_std(
-                       payment_paths(), payment_hash(), now(), &expanded_key, &secp_ctx
-               ) {
+               match invoice_request
+                       .verify(&expanded_key, &secp_ctx).unwrap()
+                       .respond_using_derived_keys_no_std(payment_paths(), payment_hash(), now())
+               {
                        Ok(_) => panic!("expected error"),
                        Err(e) => assert_eq!(e, Bolt12SemanticError::InvalidMetadata),
                }