Wrap KeyPair by DerivedSigningPubkey
authorJeffrey Czyz <jkczyz@gmail.com>
Fri, 11 Aug 2023 18:11:14 +0000 (13:11 -0500)
committerJeffrey Czyz <jkczyz@gmail.com>
Tue, 22 Aug 2023 00:14:27 +0000 (19:14 -0500)
InvoiceBuilder is parameterized by a SigningPubkeyStrategy, either
ExplicitSigningPubkey and DerivedSigningPubkey. It also holds an
Option<KeyPair>, which may be None and Some for those strategies,
respectively. This leads to methods for InvoiceBuilder parameterized by
DerivedSigningPubkey needing to blindly unwrap the Option<KeyPair>.
Instead, have DerivedSigningPubkey wrap KeyPair.

lightning/src/offers/invoice.rs

index 773e1ead26c8bbfa84eec3731519007e12c40de2..5442a072f37872ddb934b6a4103cd9e80f3f73be 100644 (file)
@@ -147,8 +147,7 @@ pub const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "signatu
 pub struct InvoiceBuilder<'a, S: SigningPubkeyStrategy> {
        invreq_bytes: &'a Vec<u8>,
        invoice: InvoiceContents,
-       keys: Option<KeyPair>,
-       signing_pubkey_strategy: core::marker::PhantomData<S>,
+       signing_pubkey_strategy: S,
 }
 
 /// Indicates how [`Bolt12Invoice::signing_pubkey`] was set.
@@ -164,7 +163,7 @@ pub struct ExplicitSigningPubkey {}
 /// [`Bolt12Invoice::signing_pubkey`] was derived.
 ///
 /// This is not exported to bindings users as builder patterns don't map outside of move semantics.
-pub struct DerivedSigningPubkey {}
+pub struct DerivedSigningPubkey(KeyPair);
 
 impl SigningPubkeyStrategy for ExplicitSigningPubkey {}
 impl SigningPubkeyStrategy for DerivedSigningPubkey {}
@@ -183,7 +182,7 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
                        ),
                };
 
-               Self::new(&invoice_request.bytes, contents, None)
+               Self::new(&invoice_request.bytes, contents, ExplicitSigningPubkey {})
        }
 
        pub(super) fn for_refund(
@@ -198,7 +197,7 @@ impl<'a> InvoiceBuilder<'a, ExplicitSigningPubkey> {
                        ),
                };
 
-               Self::new(&refund.bytes, contents, None)
+               Self::new(&refund.bytes, contents, ExplicitSigningPubkey {})
        }
 }
 
@@ -216,7 +215,7 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
                        ),
                };
 
-               Self::new(&invoice_request.bytes, contents, Some(keys))
+               Self::new(&invoice_request.bytes, contents, DerivedSigningPubkey(keys))
        }
 
        pub(super) fn for_refund_using_keys(
@@ -232,7 +231,7 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
                        ),
                };
 
-               Self::new(&refund.bytes, contents, Some(keys))
+               Self::new(&refund.bytes, contents, DerivedSigningPubkey(keys))
        }
 }
 
@@ -262,18 +261,13 @@ impl<'a, S: SigningPubkeyStrategy> InvoiceBuilder<'a, S> {
        }
 
        fn new(
-               invreq_bytes: &'a Vec<u8>, contents: InvoiceContents, keys: Option<KeyPair>
+               invreq_bytes: &'a Vec<u8>, contents: InvoiceContents, signing_pubkey_strategy: S
        ) -> Result<Self, Bolt12SemanticError> {
                if contents.fields().payment_paths.is_empty() {
                        return Err(Bolt12SemanticError::MissingPaths);
                }
 
-               Ok(Self {
-                       invreq_bytes,
-                       invoice: contents,
-                       keys,
-                       signing_pubkey_strategy: core::marker::PhantomData,
-               })
+               Ok(Self { invreq_bytes, invoice: contents, signing_pubkey_strategy })
        }
 
        /// Sets the [`Bolt12Invoice::relative_expiry`] as seconds since [`Bolt12Invoice::created_at`].
@@ -359,10 +353,11 @@ impl<'a> InvoiceBuilder<'a, DerivedSigningPubkey> {
                        }
                }
 
-               let InvoiceBuilder { invreq_bytes, invoice, keys, .. } = self;
+               let InvoiceBuilder {
+                       invreq_bytes, invoice, signing_pubkey_strategy: DerivedSigningPubkey(keys)
+               } = self;
                let unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice);
 
-               let keys = keys.unwrap();
                let invoice = unsigned_invoice
                        .sign::<_, Infallible>(
                                |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))