From ce7a02d1e002e5047aa1bf56a0176d85d8a5bde3 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Thu, 2 Feb 2023 17:13:09 -0600 Subject: [PATCH] Common offers test_utils module Move utility functions used across all offers modules into a common module. Avoids duplicating larger utilities such as payment_path across more than one module. --- lightning/src/offers/invoice.rs | 103 ++-------------------- lightning/src/offers/invoice_request.rs | 30 +------ lightning/src/offers/mod.rs | 2 + lightning/src/offers/offer.rs | 11 +-- lightning/src/offers/refund.rs | 17 +--- lightning/src/offers/test_utils.rs | 110 ++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 151 deletions(-) create mode 100644 lightning/src/offers/test_utils.rs diff --git a/lightning/src/offers/invoice.rs b/lightning/src/offers/invoice.rs index 48b8cec35..2c530760c 100644 --- a/lightning/src/offers/invoice.rs +++ b/lightning/src/offers/invoice.rs @@ -777,68 +777,27 @@ impl TryFrom for InvoiceContents { #[cfg(test)] mod tests { - use super::{DEFAULT_RELATIVE_EXPIRY, BlindedPayInfo, FallbackAddress, FullInvoiceTlvStreamRef, Invoice, InvoiceTlvStreamRef, SIGNATURE_TAG}; + use super::{DEFAULT_RELATIVE_EXPIRY, FallbackAddress, FullInvoiceTlvStreamRef, Invoice, InvoiceTlvStreamRef, SIGNATURE_TAG}; use bitcoin::blockdata::script::Script; use bitcoin::hashes::Hash; use bitcoin::network::constants::Network; - use bitcoin::secp256k1::{KeyPair, Message, PublicKey, Secp256k1, SecretKey, XOnlyPublicKey, self}; - use bitcoin::secp256k1::schnorr::Signature; + use bitcoin::secp256k1::{Message, Secp256k1, XOnlyPublicKey, self}; use bitcoin::util::address::{Address, Payload, WitnessVersion}; use bitcoin::util::schnorr::TweakedPublicKey; - use core::convert::{Infallible, TryFrom}; + use core::convert::TryFrom; use core::time::Duration; - use crate::ln::PaymentHash; use crate::ln::msgs::DecodeError; - use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures}; + use crate::ln::features::Bolt12InvoiceFeatures; use crate::offers::invoice_request::InvoiceRequestTlvStreamRef; use crate::offers::merkle::{SignError, SignatureTlvStreamRef, self}; use crate::offers::offer::{OfferBuilder, OfferTlvStreamRef, Quantity}; use crate::offers::parse::{ParseError, SemanticError}; use crate::offers::payer::PayerTlvStreamRef; use crate::offers::refund::RefundBuilder; - use crate::onion_message::{BlindedHop, BlindedPath}; + use crate::offers::test_utils::*; use crate::util::ser::{BigSize, Iterable, Writeable}; - fn payer_keys() -> KeyPair { - let secp_ctx = Secp256k1::new(); - KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()) - } - - fn payer_sign(digest: &Message) -> Result { - let secp_ctx = Secp256k1::new(); - let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); - Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys)) - } - - fn payer_pubkey() -> PublicKey { - payer_keys().public_key() - } - - fn recipient_keys() -> KeyPair { - let secp_ctx = Secp256k1::new(); - KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap()) - } - - fn recipient_sign(digest: &Message) -> Result { - let secp_ctx = Secp256k1::new(); - let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap()); - Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys)) - } - - fn recipient_pubkey() -> PublicKey { - recipient_keys().public_key() - } - - fn pubkey(byte: u8) -> PublicKey { - let secp_ctx = Secp256k1::new(); - PublicKey::from_secret_key(&secp_ctx, &privkey(byte)) - } - - fn privkey(byte: u8) -> SecretKey { - SecretKey::from_slice(&[byte; 32]).unwrap() - } - trait ToBytes { fn to_bytes(&self) -> Vec; } @@ -855,58 +814,6 @@ mod tests { } } - fn payment_paths() -> Vec<(BlindedPath, BlindedPayInfo)> { - let paths = vec![ - BlindedPath { - introduction_node_id: pubkey(40), - blinding_point: pubkey(41), - blinded_hops: vec![ - BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] }, - BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] }, - ], - }, - BlindedPath { - introduction_node_id: pubkey(40), - blinding_point: pubkey(41), - blinded_hops: vec![ - BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] }, - BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] }, - ], - }, - ]; - - let payinfo = vec![ - BlindedPayInfo { - fee_base_msat: 1, - fee_proportional_millionths: 1_000, - cltv_expiry_delta: 42, - htlc_minimum_msat: 100, - htlc_maximum_msat: 1_000_000_000_000, - features: BlindedHopFeatures::empty(), - }, - BlindedPayInfo { - fee_base_msat: 1, - fee_proportional_millionths: 1_000, - cltv_expiry_delta: 42, - htlc_minimum_msat: 100, - htlc_maximum_msat: 1_000_000_000_000, - features: BlindedHopFeatures::empty(), - }, - ]; - - paths.into_iter().zip(payinfo.into_iter()).collect() - } - - fn payment_hash() -> PaymentHash { - PaymentHash([42; 32]) - } - - fn now() -> Duration { - std::time::SystemTime::now() - .duration_since(std::time::SystemTime::UNIX_EPOCH) - .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH") - } - #[test] fn builds_invoice_for_offer_with_defaults() { let payment_paths = payment_paths(); diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index a1a0520c6..8364814ed 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -532,8 +532,7 @@ mod tests { use bitcoin::blockdata::constants::ChainHash; use bitcoin::network::constants::Network; - use bitcoin::secp256k1::{KeyPair, Message, PublicKey, Secp256k1, SecretKey, self}; - use bitcoin::secp256k1::schnorr::Signature; + use bitcoin::secp256k1::{KeyPair, Secp256k1, SecretKey, self}; use core::convert::{Infallible, TryFrom}; use core::num::NonZeroU64; #[cfg(feature = "std")] @@ -544,35 +543,10 @@ mod tests { use crate::offers::offer::{Amount, OfferBuilder, OfferTlvStreamRef, Quantity}; use crate::offers::parse::{ParseError, SemanticError}; use crate::offers::payer::PayerTlvStreamRef; + use crate::offers::test_utils::*; use crate::util::ser::{BigSize, Writeable}; use crate::util::string::PrintableString; - fn payer_keys() -> KeyPair { - let secp_ctx = Secp256k1::new(); - KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()) - } - - fn payer_sign(digest: &Message) -> Result { - let secp_ctx = Secp256k1::new(); - let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); - Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys)) - } - - fn payer_pubkey() -> PublicKey { - payer_keys().public_key() - } - - fn recipient_sign(digest: &Message) -> Result { - let secp_ctx = Secp256k1::new(); - let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap()); - Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys)) - } - - fn recipient_pubkey() -> PublicKey { - let secp_ctx = Secp256k1::new(); - KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap()).public_key() - } - #[test] fn builds_invoice_request_with_defaults() { let invoice_request = OfferBuilder::new("foo".into(), recipient_pubkey()) diff --git a/lightning/src/offers/mod.rs b/lightning/src/offers/mod.rs index 2da6fac08..c2b0d6aea 100644 --- a/lightning/src/offers/mod.rs +++ b/lightning/src/offers/mod.rs @@ -19,3 +19,5 @@ pub mod offer; pub mod parse; mod payer; pub mod refund; +#[cfg(test)] +mod test_utils; diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 405e2e278..a1445c6f7 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -666,26 +666,17 @@ mod tests { use bitcoin::blockdata::constants::ChainHash; use bitcoin::network::constants::Network; - use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; use core::convert::TryFrom; use core::num::NonZeroU64; use core::time::Duration; use crate::ln::features::OfferFeatures; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; use crate::offers::parse::{ParseError, SemanticError}; + use crate::offers::test_utils::*; use crate::onion_message::{BlindedHop, BlindedPath}; use crate::util::ser::{BigSize, Writeable}; use crate::util::string::PrintableString; - fn pubkey(byte: u8) -> PublicKey { - let secp_ctx = Secp256k1::new(); - PublicKey::from_secret_key(&secp_ctx, &privkey(byte)) - } - - fn privkey(byte: u8) -> SecretKey { - SecretKey::from_slice(&[byte; 32]).unwrap() - } - #[test] fn builds_offer_with_defaults() { let offer = OfferBuilder::new("foo".into(), pubkey(42)).build().unwrap(); diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index cc0388c02..51cfebed4 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -575,7 +575,7 @@ mod tests { use bitcoin::blockdata::constants::ChainHash; use bitcoin::network::constants::Network; - use bitcoin::secp256k1::{KeyPair, PublicKey, Secp256k1, SecretKey}; + use bitcoin::secp256k1::{KeyPair, Secp256k1, SecretKey}; use core::convert::TryFrom; use core::time::Duration; use crate::ln::features::{InvoiceRequestFeatures, OfferFeatures}; @@ -584,24 +584,11 @@ mod tests { use crate::offers::offer::OfferTlvStreamRef; use crate::offers::parse::{ParseError, SemanticError}; use crate::offers::payer::PayerTlvStreamRef; + use crate::offers::test_utils::*; use crate::onion_message::{BlindedHop, BlindedPath}; use crate::util::ser::{BigSize, Writeable}; use crate::util::string::PrintableString; - fn payer_pubkey() -> PublicKey { - let secp_ctx = Secp256k1::new(); - KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()).public_key() - } - - fn pubkey(byte: u8) -> PublicKey { - let secp_ctx = Secp256k1::new(); - PublicKey::from_secret_key(&secp_ctx, &privkey(byte)) - } - - fn privkey(byte: u8) -> SecretKey { - SecretKey::from_slice(&[byte; 32]).unwrap() - } - trait ToBytes { fn to_bytes(&self) -> Vec; } diff --git a/lightning/src/offers/test_utils.rs b/lightning/src/offers/test_utils.rs new file mode 100644 index 000000000..7447b86fb --- /dev/null +++ b/lightning/src/offers/test_utils.rs @@ -0,0 +1,110 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + +//! Utilities for testing BOLT 12 Offers interfaces + +use bitcoin::secp256k1::{KeyPair, Message, PublicKey, Secp256k1, SecretKey}; +use bitcoin::secp256k1::schnorr::Signature; +use core::convert::Infallible; +use core::time::Duration; +use crate::ln::PaymentHash; +use crate::ln::features::BlindedHopFeatures; +use crate::offers::invoice::BlindedPayInfo; +use crate::onion_message::{BlindedHop, BlindedPath}; + +pub(super) fn payer_keys() -> KeyPair { + let secp_ctx = Secp256k1::new(); + KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()) +} + +pub(super) fn payer_sign(digest: &Message) -> Result { + let secp_ctx = Secp256k1::new(); + let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()); + Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys)) +} + +pub(super) fn payer_pubkey() -> PublicKey { + payer_keys().public_key() +} + +pub(super) fn recipient_keys() -> KeyPair { + let secp_ctx = Secp256k1::new(); + KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap()) +} + +pub(super) fn recipient_sign(digest: &Message) -> Result { + let secp_ctx = Secp256k1::new(); + let keys = KeyPair::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[43; 32]).unwrap()); + Ok(secp_ctx.sign_schnorr_no_aux_rand(digest, &keys)) +} + +pub(super) fn recipient_pubkey() -> PublicKey { + recipient_keys().public_key() +} + +pub(super) fn pubkey(byte: u8) -> PublicKey { + let secp_ctx = Secp256k1::new(); + PublicKey::from_secret_key(&secp_ctx, &privkey(byte)) +} + +pub(super) fn privkey(byte: u8) -> SecretKey { + SecretKey::from_slice(&[byte; 32]).unwrap() +} + +pub(super) fn payment_paths() -> Vec<(BlindedPath, BlindedPayInfo)> { + let paths = vec![ + BlindedPath { + introduction_node_id: pubkey(40), + blinding_point: pubkey(41), + blinded_hops: vec![ + BlindedHop { blinded_node_id: pubkey(43), encrypted_payload: vec![0; 43] }, + BlindedHop { blinded_node_id: pubkey(44), encrypted_payload: vec![0; 44] }, + ], + }, + BlindedPath { + introduction_node_id: pubkey(40), + blinding_point: pubkey(41), + blinded_hops: vec![ + BlindedHop { blinded_node_id: pubkey(45), encrypted_payload: vec![0; 45] }, + BlindedHop { blinded_node_id: pubkey(46), encrypted_payload: vec![0; 46] }, + ], + }, + ]; + + let payinfo = vec![ + BlindedPayInfo { + fee_base_msat: 1, + fee_proportional_millionths: 1_000, + cltv_expiry_delta: 42, + htlc_minimum_msat: 100, + htlc_maximum_msat: 1_000_000_000_000, + features: BlindedHopFeatures::empty(), + }, + BlindedPayInfo { + fee_base_msat: 1, + fee_proportional_millionths: 1_000, + cltv_expiry_delta: 42, + htlc_minimum_msat: 100, + htlc_maximum_msat: 1_000_000_000_000, + features: BlindedHopFeatures::empty(), + }, + ]; + + paths.into_iter().zip(payinfo.into_iter()).collect() +} + +pub(super) fn payment_hash() -> PaymentHash { + PaymentHash([42; 32]) +} + +pub(super) fn now() -> Duration { + std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .expect("SystemTime::now() should come after SystemTime::UNIX_EPOCH") +} -- 2.39.5