-// 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 <LICENSE-APACHE
//!
//! use bitcoin::hashes::Hash;
//! use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey};
-//! use core::convert::{Infallible, TryFrom};
+//! use core::convert::TryFrom;
//! use lightning::offers::invoice::UnsignedBolt12Invoice;
//! use lightning::offers::invoice_request::InvoiceRequest;
//! use lightning::offers::refund::Refund;
//! .allow_mpp()
//! .fallback_v0_p2wpkh(&wpubkey_hash)
//! .build()?
-//! .sign(|message: &UnsignedBolt12Invoice| -> Result<_, Infallible> {
+//! .sign(|message: &UnsignedBolt12Invoice|
//! Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
-//! })
+//! )
//! .expect("failed verifying signature")
//! .write(&mut buffer)
//! .unwrap();
//! .allow_mpp()
//! .fallback_v0_p2wpkh(&wpubkey_hash)
//! .build()?
-//! .sign(|message: &UnsignedBolt12Invoice| -> Result<_, Infallible> {
+//! .sign(|message: &UnsignedBolt12Invoice|
//! Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
-//! })
+//! )
//! .expect("failed verifying signature")
//! .write(&mut buffer)
//! .unwrap();
use bitcoin::blockdata::constants::ChainHash;
use bitcoin::hash_types::{WPubkeyHash, WScriptHash};
-use bitcoin::hashes::Hash;
use bitcoin::network::constants::Network;
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 core::hash::{Hash, Hasher};
use crate::io;
use crate::blinded_path::BlindedPath;
use crate::ln::PaymentHash;
use crate::util::ser::{HighZeroBytesDroppedBigSize, Iterable, SeekReadable, WithoutLength, Writeable, Writer};
use crate::util::string::PrintableString;
+#[allow(unused_imports)]
use crate::prelude::*;
#[cfg(feature = "std")]
let mut unsigned_invoice = UnsignedBolt12Invoice::new(invreq_bytes, invoice.clone());
let invoice = unsigned_invoice
- .sign(|message: &UnsignedBolt12Invoice| -> Result<_, Infallible> {
+ .sign(|message: &UnsignedBolt12Invoice|
Ok(secp_ctx.sign_schnorr_no_aux_rand(message.as_ref().as_digest(), &keys))
- })
+ )
.unwrap();
Ok(invoice)
}
/// Successive calls to this method will add another address. Caller is responsible for not
/// adding duplicate addresses and only calling if capable of receiving to P2WSH addresses.
pub fn fallback_v0_p2wsh($($self_mut)* $self: $self_type, script_hash: &WScriptHash) -> $return_type {
+ use bitcoin::hashes::Hash;
let address = FallbackAddress {
version: WitnessVersion::V0.to_num(),
program: Vec::from(script_hash.to_byte_array()),
/// Successive calls to this method will add another address. Caller is responsible for not
/// adding duplicate addresses and only calling if capable of receiving to P2WPKH addresses.
pub fn fallback_v0_p2wpkh($($self_mut)* $self: $self_type, pubkey_hash: &WPubkeyHash) -> $return_type {
+ use bitcoin::hashes::Hash;
let address = FallbackAddress {
version: WitnessVersion::V0.to_num(),
program: Vec::from(pubkey_hash.to_byte_array()),
/// A function for signing an [`UnsignedBolt12Invoice`].
pub trait SignBolt12InvoiceFn {
- /// Error type returned by the function.
- type Error;
-
/// Signs a [`TaggedHash`] computed over the merkle root of `message`'s TLV stream.
- fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, Self::Error>;
+ fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()>;
}
-impl<F, E> SignBolt12InvoiceFn for F
+impl<F> SignBolt12InvoiceFn for F
where
- F: Fn(&UnsignedBolt12Invoice) -> Result<Signature, E>,
+ F: Fn(&UnsignedBolt12Invoice) -> Result<Signature, ()>,
{
- type Error = E;
-
- fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, E> {
+ fn sign_invoice(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()> {
self(message)
}
}
-impl<F, E> SignFn<UnsignedBolt12Invoice> for F
+impl<F> SignFn<UnsignedBolt12Invoice> for F
where
- F: SignBolt12InvoiceFn<Error = E>,
+ F: SignBolt12InvoiceFn,
{
- type Error = E;
-
- fn sign(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, Self::Error> {
+ fn sign(&self, message: &UnsignedBolt12Invoice) -> Result<Signature, ()> {
self.sign_invoice(message)
}
}
let mut bytes = Vec::new();
unsigned_tlv_stream.write(&mut bytes).unwrap();
- let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
+ let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
Self { bytes, contents, tagged_hash }
}
/// Note: The hash computation may have included unknown, odd TLV records.
pub fn sign<F: SignBolt12InvoiceFn>(
$($self_mut)* $self: $self_type, sign: F
- ) -> Result<Bolt12Invoice, SignError<F::Error>> {
+ ) -> Result<Bolt12Invoice, SignError> {
let pubkey = $self.contents.fields().signing_pubkey;
let signature = merkle::sign_message(sign, &$self, pubkey)?;
/// [`Refund`]: crate::offers::refund::Refund
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
#[derive(Clone, Debug)]
-#[cfg_attr(test, derive(PartialEq))]
pub struct Bolt12Invoice {
bytes: Vec<u8>,
contents: InvoiceContents,
}
}
+impl PartialEq for Bolt12Invoice {
+ fn eq(&self, other: &Self) -> bool {
+ self.bytes.eq(&other.bytes)
+ }
+}
+
+impl Eq for Bolt12Invoice {}
+
+impl Hash for Bolt12Invoice {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.bytes.hash(state);
+ }
+}
+
impl InvoiceContents {
/// Whether the original offer or refund has expired.
#[cfg(feature = "std")]
(payer_tlv_stream, offer_tlv_stream, invoice_request_tlv_stream, invoice_tlv_stream)
)?;
- let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
+ let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
Ok(UnsignedBolt12Invoice { bytes, contents, tagged_hash })
}
None => return Err(Bolt12ParseError::InvalidSemantics(Bolt12SemanticError::MissingSignature)),
Some(signature) => signature,
};
- let tagged_hash = TaggedHash::new(SIGNATURE_TAG, &bytes);
+ let tagged_hash = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &bytes);
let pubkey = contents.fields().signing_pubkey;
merkle::verify_signature(&signature, &tagged_hash, pubkey)?;
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;
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,
assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
- let message = TaggedHash::new(SIGNATURE_TAG, &invoice.bytes);
+ let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &invoice.bytes);
assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok());
let digest = Message::from_slice(&invoice.signable_hash()).unwrap();
assert_eq!(invoice.invoice_features(), &Bolt12InvoiceFeatures::empty());
assert_eq!(invoice.signing_pubkey(), recipient_pubkey());
- let message = TaggedHash::new(SIGNATURE_TAG, &invoice.bytes);
+ let message = TaggedHash::from_valid_tlv_stream_bytes(SIGNATURE_TAG, &invoice.bytes);
assert!(merkle::verify_signature(&invoice.signature, &message, recipient_pubkey()).is_ok());
assert_eq!(
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] },
.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())