X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Foffers%2Finvoice.rs;h=fbfcffe2ad805fdec8af1f4f24ae7dc7de916e63;hb=ec956516d1db59d5e667cf3ebec2dc2e08148cdd;hp=f665bd3b26e81dda6c2181e15dc2f46758f84a9f;hpb=3bd00b943a3f3a101a77ad127b219dad91845aa6;p=rust-lightning diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index f665bd3b..fbfcffe2 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -1,4 +1,4 @@ -// This file is Copyright its original authors, visible in version control + // This file is Copyright its original authors, visible in version control // history. // // This file is licensed under the Apache License, Version 2.0 ( -//! |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) +//! .sign(|message: &UnsignedBolt12Invoice| +//! Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) //! ) //! .expect("failed verifying signature") //! .write(&mut buffer) @@ -90,8 +91,8 @@ //! .allow_mpp() //! .fallback_v0_p2wpkh(&wpubkey_hash) //! .build()? -//! .sign::<_, Infallible>( -//! |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) +//! .sign(|message: &UnsignedBolt12Invoice| +//! Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) //! ) //! .expect("failed verifying signature") //! .write(&mut buffer) @@ -109,7 +110,6 @@ use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, self}; use bitcoin::secp256k1::schnorr::Signature; use bitcoin::address::{Address, Payload, WitnessProgram, WitnessVersion}; use bitcoin::key::TweakedPublicKey; -use core::convert::{AsRef, Infallible, TryFrom}; use core::time::Duration; use crate::io; use crate::blinded_path::BlindedPath; @@ -119,7 +119,7 @@ use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures, InvoiceRequ use crate::ln::inbound_payment::ExpandedKey; use crate::ln::msgs::DecodeError; use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef}; -use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream, WithoutSignatures, self}; +use crate::offers::merkle::{SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, TlvStream, WithoutSignatures, self}; use crate::offers::offer::{Amount, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef, Quantity}; use crate::offers::parse::{Bolt12ParseError, Bolt12SemanticError, ParsedMessage}; use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef}; @@ -128,6 +128,7 @@ use crate::offers::signer; use crate::util::ser::{HighZeroBytesDroppedBigSize, Iterable, SeekReadable, WithoutLength, Writeable, Writer}; use crate::util::string::PrintableString; +#[allow(unused_imports)] use crate::prelude::*; #[cfg(feature = "std")] @@ -324,8 +325,8 @@ macro_rules! invoice_derived_signing_pubkey_builder_methods { ($self: ident, $se let mut unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice.clone()); let invoice = unsigned_invoice - .sign::<_, Infallible>( - |message| Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) + .sign(|message: &UnsignedBolt12Invoice| + Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys)) ) .unwrap(); Ok(invoice) @@ -507,6 +508,30 @@ pub struct UnsignedBolt12Invoice { tagged_hash: TaggedHash, } +/// A function for signing an [`UnsignedBolt12Invoice`]. +pub trait SignBolt12InvoiceFn { + /// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream. + fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result; +} + +impl SignBolt12InvoiceFn for F +where + F: Fn(&UnsignedBolt12Invoice) -> Result, +{ + fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result { + self(message) + } +} + +impl SignFn for F +where + F: SignBolt12InvoiceFn, +{ + fn sign(&self, message: &UnsignedBolt12Invoice) -> Result { + self.sign_invoice(message) + } +} + impl UnsignedBolt12Invoice { fn new(invreq_bytes: &[u8], contents: InvoiceContents) -> Self { // Use the invoice_request bytes instead of the invoice_request TLV stream as the latter may @@ -534,12 +559,9 @@ macro_rules! unsigned_invoice_sign_method { ($self: ident, $self_type: ty $(, $s /// Signs the [`TaggedHash`] of the invoice using the given function. /// /// Note: The hash computation may have included unknown, odd TLV records. - /// - /// This is not exported to bindings users as functions aren't currently mapped. - pub fn sign($($self_mut)* $self: $self_type, sign: F) -> Result> - where - F: FnOnce(&Self) -> Result - { + pub fn sign( + $($self_mut)* $self: $self_type, sign: F + ) -> Result { let pubkey = $self.contents.fields().signing_pubkey; let signature = merkle::sign_message(sign, &$self, pubkey)?; @@ -1430,9 +1452,10 @@ mod tests { use bitcoin::secp256k1::{Message, Secp256k1, XOnlyPublicKey, self}; use bitcoin::address::{Address, Payload, WitnessProgram, WitnessVersion}; use bitcoin::key::TweakedPublicKey; - use core::convert::TryFrom; + use core::time::Duration; - use crate::blinded_path::{BlindedHop, BlindedPath}; + + use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode}; use crate::sign::KeyMaterial; use crate::ln::features::{Bolt12InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures}; use crate::ln::inbound_payment::ExpandedKey; @@ -1440,6 +1463,7 @@ mod tests { use crate::offers::invoice_request::InvoiceRequestTlvStreamRef; use crate::offers::merkle::{SignError, SignatureTlvStreamRef, TaggedHash, self}; use crate::offers::offer::{Amount, OfferTlvStreamRef, Quantity}; + use crate::prelude::*; #[cfg(not(c_bindings))] use { crate::offers::offer::OfferBuilder, @@ -1780,7 +1804,7 @@ mod tests { let secp_ctx = Secp256k1::new(); let blinded_path = BlindedPath { - introduction_node_id: pubkey(40), + introduction_node: IntroductionNode::NodeId(pubkey(40)), blinding_point: pubkey(41), blinded_hops: vec![ BlindedHop { blinded_node_id: pubkey(42), encrypted_payload: vec![0; 43] }, @@ -2013,10 +2037,10 @@ mod tests { .sign(payer_sign).unwrap() .respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap() .build().unwrap() - .sign(|_| Err(())) + .sign(fail_sign) { Ok(_) => panic!("expected error"), - Err(e) => assert_eq!(e, SignError::Signing(())), + Err(e) => assert_eq!(e, SignError::Signing), } match OfferBuilder::new("foo".into(), recipient_pubkey())